在iOS中以编程方式获取自己的电话号码


330

有什么方法可以通过iPhone SDK中的标准API获取自己的电话号码?


对于其他正在寻找不使用私有api的how-does-squares-cardcase-app-do-this的解决方案的人来说可能有用-使用设备名称来捕获用户名只是修改以捕获电话号码或其他适当信息
Nik Burns

davidgyoung提供了一个可行的解决方案。它被掩埋了(需要一些投票)。

现在可以在Xcode中使用像stackoverflow.com/a/54004224/536214
aqavi_paracha,

Answers:


318

冒着被打分的风险,我想建议排名最高的解决方案(当前为第一个响应)违反了截至2009年11月5日的最新SDK协议。我们的应用程序因使用它而被拒绝。这是苹果公司的回应:

“出于安全考虑,iPhone OS将应用程序(包括其首选项和数据)限制为文件系统中的唯一位置。此限制是称为应用程序“沙箱”的安全功能的一部分。沙箱是一组优良的功能,细粒度的控件限制了应用程序对文件,首选项,网络资源,硬件等的访问。”

该设备的电话号码在您应用程序的容器中不可用。您将需要修改您的应用程序以使其只能在目录容器中读取,然后将二进制文件重新提交给iTunes Connect,以便将应用程序重新考虑用于App Store。

真令人失望,因为我们想让用户不必输入自己的电话号码。


83
Snapchat是如何做到的?
rgbrgb

1
@Dylan:您的应用什么时候被拒绝了,也许准则被修改了吗?请提供文档的有用链接。不过,感谢您的回答。
Abhishek Bedi

1
我可以得到提到的apple.developer文档链接吗?
Ganesh AB-Android 2015年

3
我从没有找到任何文档,但是很乐意看到它。这是苹果对我而言仍然不透明的领域之一。此后,我还没有尝试过提交申请。
迪伦

1
@rgbrgb我不使用Snapchat,能否请您解释一下他们的经验如此神秘?
William Entriken '17

138

不,没有合法可靠的方法可以做到这一点。

如果您找到了一种方法,那么将来它将被禁用,因为以前的每种方法都曾经发生过这种情况。


2
请参阅Nik Burn的答案:stackoverflow.com/a/8415162/292166-有一种方法可以做到这一点!
JosephH 2013年

4
您看到Apple禁止基于权限访问用户电话的最佳理由是什么?Apple已经允许对联系人,照片,位置以及用户的相机和麦克风进行基于权限的访问。为什么没有电话号码?一定有一个很好的理由,但目前尚不清楚。不幸的是,禁止访问会导致开发人员在其他方式上花费大量时间和金钱来验证用户的电话号码。
Crashalot

86

更新:此功能似乎已被Apple在iOS 4或周围删除


只是为了扩展先前的答案,类似这样的事情对我来说是这样的:

NSString *num = [[NSUserDefaults standardUserDefaults] stringForKey:@"SBFormattedPhoneNumber"];

注意:这将检索在iPhone的iTunes激活期间输入的“电话号码”,并且可以为null或不正确的值。这是从SIM卡中读取。

至少在2.1中如此。NSUserDefaults中还有其他一些有趣的键,这些键也可能不会持续使用。(这是在我的使用UIWebView的应用程序中)

WebKitJavaScriptCanOpenWindowsAutomatically
NSInterfaceStyle
TVOutStatus
WebKitDeveloperExtrasEnabledPreferenceKey

等等。

不知道其他人会做什么,如果有的话。


1
还有的是最近一些关于这背后的能力安全问题按:theregister.co.uk/2009/09/30/iphone_security
JeffH

10
不要这样 通过键盘或联系选择器询问用户该号码。您应该对用户尽可能明确地收集任何信息。它可能不是最方便的方法,但是保存数字非常容易,因此您只需要询问一次即可。
David Kanarek 2010年

3
使应用程序被拒绝的解决方案不是解决方案。
averydev 2011年

27

使用专用API,您可以通过以下方式获取用户电话号码:

extern NSString* CTSettingCopyMyPhoneNumber();


+(NSString *) phoneNumber {
NSString *phone = CTSettingCopyMyPhoneNumber();

return phone;
}

还将CoreTelephony.framework包含到您的项目中。


在阅读了该论坛的其他答案之后,我认为这是不可能的,但是您做得很出色
Mehul Thakkar 2013年

1
在iOS 7上,它受权利stackoverflow.com/questions/19504478/…
creker

我尝试此操作时电话为零
C0D3

22

众所周知,如果您使用以下代码行,则您的应用将被苹果拒绝

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.

希望这可以帮助!


9
iOS5中也不推荐使用uniqueIdentifier。请改用MAC地址。
猛禽

15
MAC地址已在iOS 7中弃用。请[UIDevice identifierForVendor]改用。
jab

17

您不能单独使用iOS API来捕获电话号码(即使是在具有私有API的私有应用程序中),因为自iOS 11起,所有已知方法都已修补和阻止了该方法。即使发现了新的漏洞利用,苹果公司也取得了成功。明确表示他们将拒绝使用私有API来执行此操作的所有应用商店中的应用。有关详细信息,请参见@Dylan的答案。

但是,有一种合法的方式可以捕获电话号码,而无需输入任何用户数据。这与Snapchat相似,但是更简单,因为它不需要用户输入自己的电话号码。

想法是让应用程序以编程方式将带有该应用程序唯一安装代码的SMS消息发送到服务器。然后,该应用程序可以查询同一服务器,以查看它最近是否从具有此唯一应用程序安装代码的设备接收到SMS消息。如果有,它可以读取发送它的电话号码。这是一个演示视频该过程。如您所见,它就像一种魅力!

设置起来并非易事,但可以使用免费的AWS层在数小时内免费配置,并使用此处教程中提供的示例代码进行配置。


抱歉。视频意外地是私有的。现在是公开的。
davidgyoung

这是一个很好的方法,但是您能否请您丰富答案以至少涵盖基本的实现细节?如何在不知道您的电话号码的情况下从iOS设备发送短信?如何设置可以访问发件人电话号码的SMS接收服务器?涉及哪些工具?兼容性?
Motti Shneor

@MottiShneor,您是否在答案中看到了教程链接?它有一个完整的教程,介绍如何设置此解决方案以及Github存储库中的示例应用程序代码。
davidgyoung,

2

要获取您的电话号码,您可以阅读plist文件。它不适用于非越狱的iDevice:

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上使用。


苹果公司对越狱手机的保修无效,并且应用程序必须具有对所有用户无处不在的功能。
Cosmtar

2

没有官方的API可以做到这一点。使用私有API,您可以使用以下方法:

-(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;
}

它可以在没有JB和特殊签名的iOS 6上运行。

正如前面提到的带有JB的iOS 7上的creker一样,您需要使用权利才能使其正常工作。

如何使用权利来找到它: iOS 7:如何通过私有API获得自己的号码?


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.