冒着被扣分的风险,我想提出一个建议:目前排名最高的解决方案(当前第一响应)违反了2009年11月5日最新的SDK协议。我们的应用程序刚刚因为使用它而被拒绝了。以下是来自苹果公司的回复:
"出于安全考虑,iPhone OS将应用程序(包括其首选项和数据)限制在文件系统中的唯一位置。这种限制是安全功能的一部分,称为应用程序的“沙箱”。沙箱是一组细粒度控件,限制应用程序对文件、首选项、网络资源、硬件等的访问。"
设备的电话号码不可在您的应用程序容器内使用。您需要修改应用程序,仅在您的目录容器内进行读取,并重新提交二进制文件到iTunes Connect,以便您的应用程序重新考虑加入应用商店。
这真是令人失望,因为我们希望减轻用户输入他们自己的电话号码的负担。
不,目前没有合法可靠的方法可以实现这个功能。
即使你找到了一种方法,它也会在不久的将来被禁用,就像以前所有的方法一样。
仅仅是为了扩展之前的答案,像这样的东西对我很有用:
NSString *num = [[NSUserDefaults standardUserDefaults] stringForKey:@"SBFormattedPhoneNumber"];
注意: 这会检索在 iPhone 的 iTunes 激活期间输入的“电话号码”,可能为空或者不正确。这不是从 SIM 卡中读取的。
至少在2.1版本中是这样的。NSUserDefaults中还有其他一些有趣的键,也可能不会持久存在(这是在我的应用程序中使用UIWebView的情况下)。
WebKitJavaScriptCanOpenWindowsAutomatically
NSInterfaceStyle
TVOutStatus
WebKitDeveloperExtrasEnabledPreferenceKey
等等其他人是否有做什么,我不确定。
使用私有API,您可以按照以下方式获取用户电话号码:
extern NSString* CTSettingCopyMyPhoneNumber();
+(NSString *) phoneNumber {
NSString *phone = CTSettingCopyMyPhoneNumber();
return phone;
}
同时将CoreTelephony.framework添加到您的项目中。
即使在使用私有API的私有应用程序中,iOS API本身无法单独捕获电话号码,因为所有已知的方法都在iOS 11中被修补和阻止。即使发现了新的漏洞,苹果也明确表示,他们将拒绝使用私有API来执行此操作的任何应用程序进入应用商店。详见@Dylan的回答。
但是,有一种合法的方式可以捕获电话号码而不需要用户输入任何数据。这类似于Snapchat的做法,但更简单,因为它不需要用户输入自己的电话号码。
其思想是:应用程序以编程方式向服务器发送一个SMS消息并附带应用程序的唯一安装代码。然后,应用程序可以查询同一服务器,以查看最近是否从具有此唯一应用程序安装代码的设备接收到SMS消息。如果有,则可以读取发送它的电话号码。以下是展示该过程的演示视频。正如你所见,它非常有效!
这不是非常容易设置的,但是可以使用教程提供的示例代码在免费的AWS层上在几小时内配置完成而无需支付任何费用。
如果你使用以下这行代码,你可能已经知道你的应用会被苹果拒绝
NSString *num = [[NSUserDefaults standardUserDefaults] stringForKey:@"SBFormattedPhoneNumber"];
这里有一个参考链接:
http://ayeapi.blogspot.com/2009/12/sbformatphonenumber-is-lie.html
您可以使用以下信息代替。
NSString *phoneName = [[UIDevice currentDevice] name];
NSString *phoneUniqueIdentifier = [[UIDevice currentDevice] uniqueIdentifier];
等等,等等
@property(nonatomic,readonly,retain) NSString *name; // e.g. "My iPhone"
@property(nonatomic,readonly,retain) NSString *model; // e.g. @"iPhone", @"iPod Touch"
@property(nonatomic,readonly,retain) NSString *localizedModel; // localized version of model
@property(nonatomic,readonly,retain) NSString *systemName; // e.g. @"iPhone OS"
@property(nonatomic,readonly,retain) NSString *systemVersion; // e.g. @"2.0"
@property(nonatomic,readonly) UIDeviceOrientation orientation; // return current device orientation
@property(nonatomic,readonly,retain) NSString *uniqueIdentifier; // a string unique to each device based on various hardware info.
希望这能帮到你!
[UIDevice identifierForVendor]
。 - jab-(NSString*) getMyNumber {
NSLog(@"Open CoreTelephony");
void *lib = dlopen("/Symbols/System/Library/Framework/CoreTelephony.framework/CoreTelephony",RTLD_LAZY);
NSLog(@"Get CTSettingCopyMyPhoneNumber from CoreTelephony");
NSString* (*pCTSettingCopyMyPhoneNumber)() = dlsym(lib, "CTSettingCopyMyPhoneNumber");
NSLog(@"Get CTSettingCopyMyPhoneNumber from CoreTelephony");
if (pCTSettingCopyMyPhoneNumber == nil) {
NSLog(@"pCTSettingCopyMyPhoneNumber is nil");
return nil;
}
NSString* ownPhoneNumber = pCTSettingCopyMyPhoneNumber();
dlclose(lib);
return ownPhoneNumber;
}
要获取您的电话号码,您可以读取一个plist文件。这在非越狱的iDevices上不起作用:
NSString *commcenter = @"/private/var/wireless/Library/Preferences/com.apple.commcenter.plist";
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:commcenter];
NSString *PhoneNumber = [dict valueForKey:@"PhoneNumber"];
NSLog([NSString stringWithFormat:@"Phone number: %@",PhoneNumber]);
我不确定苹果是否允许这样做,但是在iPhone上可以使用。
应用商店将拒绝它,因为它超出了应用程序容器的范围。
应用程序应该在其包中自我包含,并且不得读取或写入指定容器区域之外的数据
第2.5.2节: https://developer.apple.com/app-store/review/guidelines/#software-requirements