Программно получить свой номер телефона в iOS

330

Есть ли способ получить собственный номер телефона с помощью стандартных API из iPhone SDK?

Вадим
источник
может быть полезно для других, ищущих решение, которое не использует частный api -how-do-squares-cardcase-app-do-this - используйте имя устройства для захвата имени пользователя, просто измените, чтобы захватить номер телефона или другие подробности в зависимости от ситуации
Nik Burns
Дэвидгёнг предоставил рабочее решение. Он похоронен (нужно несколько голосов).
P i
Это теперь возможно в XCode, как этот stackoverflow.com/a/54004224/536214
aqavi_paracha

Ответы:

318

Рискуя получить отрицательные оценки, я хочу предположить, что решение с самым высоким рейтингом (в настоящее время первый ответ) нарушает последнее Соглашение SDK от 5 ноября 2009 года. Наше приложение было отклонено для его использования. Вот ответ от Apple:

«В целях безопасности iPhone OS ограничивает приложение (включая его настройки и данные) уникальным местоположением в файловой системе. Это ограничение является частью функции безопасности, известной как« песочница »приложения.« Песочница »представляет собой набор детализированные элементы управления, ограничивающие доступ приложения к файлам, настройкам, сетевым ресурсам, оборудованию и т. д. "

Номер телефона устройства недоступен в контейнере вашего приложения. Вам нужно будет пересмотреть приложение, чтобы оно было доступно только для чтения в контейнере каталогов, и повторно отправить двоичный файл в iTunes Connect, чтобы приложение было пересмотрено в App Store.

Это было настоящим разочарованием, так как мы хотели избавить пользователя от необходимости вводить свой номер телефона.

Dylan
источник
83
Как Snapchat делает это?
rgbrgb
1
@Dylan: Когда ваше приложение было отклонено. Возможно, рекомендации были пересмотрены? Пожалуйста, предоставьте полезные ссылки на документацию. Тем не менее, я ценю ваш ответ.
Абхишек Беди
1
Могу ли я получить ссылку на документацию apple.developer, где это упоминалось?
Ганеш А.Б. - Android
3
Я никогда не нашел никакой документации по этому вопросу, но хотел бы увидеть это. Это одна из тех областей, где Apple осталась непрозрачной для меня. С тех пор я не пытался подать заявку.
Дилан
1
@ rgbrgb Я не пользуюсь Snapchat, не могли бы вы объяснить их опыт, который так загадочен?
Уильям Энтрикен
138

Нет, нет законного и надежного способа сделать это.

Если вы найдете способ, он будет отключен в будущем, как это было с каждым методом раньше.

Эндрю Грант
источник
2
Смотрите ответ Nik Burn: stackoverflow.com/a/8415162/292166 - есть (своего рода) способ сделать это!
JosephH
4
Какова лучшая причина, по которой Apple запрещает доступ на основе разрешений к номеру телефона пользователя? Apple уже разрешает доступ на основе разрешений к контактам, фотографиям, местоположению, а также к камере и микрофону пользователя. Почему не номер телефона? Должна быть веская причина, но она не сразу понятна. К сожалению, запрет доступа приводит к тому, что разработчики тратят много времени и денег на другие способы проверки номера телефона пользователя.
Crashalot
86

Обновление: похоже, что возможность была удалена Apple на iOS 4 или вокруг нее


Просто чтобы расширить предыдущий ответ, что-то вроде этого делает это для меня:

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

Примечание . При этом извлекается «номер телефона», который был введен во время активации iTunes на iPhone, и может иметь нулевое или неправильное значение. Это не читается с SIM-карты.

По крайней мере, в 2.1. В NSUserDefaults есть пара других интересных ключей, которые также могут не сохраняться. (Это в моем приложении, которое использует UIWebView)

WebKitJavaScriptCanOpenWindowsAutomatically
NSInterfaceStyle
TVOutStatus
WebKitDeveloperExtrasEnabledPreferenceKey

и так далее.

Не уверен, что делают другие.

Роберт Сандерс
источник
1
В последнее время появились сообщения о проблемах безопасности, связанных с этой возможностью: theregister.co.uk/2009/09/30/iphone_security
JeffH
10
Не делай этого. Спросите пользователя о номере с помощью клавиатуры или выбора контактов. Вы должны сделать сбор информации как можно более понятным для пользователя. Это может быть не самым удобным, но сохранить номер очень просто, поэтому вам нужно только один раз запросить его.
Дэвид Канарек
3
Решение, которое отклоняет приложения, не является решением.
августа
27

Используя Private API, вы можете получить номер телефона пользователя следующим образом:

extern NSString* CTSettingCopyMyPhoneNumber();


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

return phone;
}

Также включите CoreTelephony.framework в ваш проект.

Игорь
источник
Прочитав другие ответы на этом форуме, я подумал, что это невозможно, но вы отлично поработали
Мехул Тхаккар,
1
На iOS 7 он защищен правами stackoverflow.com/questions/19504478/…
creker
телефон ноль, когда я пытаюсь это
C0D3
22

Как вы, наверное, все уже знаете, если вы используете следующую строку кода, ваше приложение будет отклонено Apple

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
uniqueIdentifier также устарел в iOS5. Вместо этого используйте MAC-адрес.
Raptor
15
MAC-адрес устарел в iOS 7. Используйте [UIDevice identifierForVendor]вместо этого.
джеб
17

Нельзя использовать только API-интерфейсы iOS для захвата телефонного номера (даже в частном приложении с частными API-интерфейсами), поскольку все известные способы сделать это были исправлены и заблокированы начиная с iOS 11. Даже если обнаружен новый эксплойт, Apple сделала Ясно, что они будут отклонять любые приложения из магазина приложений для использования частных API для этого. Смотрите ответ @ Dylan для деталей.

Тем не менее, существует законный способ захвата номера телефона без ввода данных пользователя. . Это похоже на то, что делает Snapchat, но проще, так как не требует, чтобы пользователь вводил свой номер телефона.

Идея состоит в том, чтобы приложение программно отправляло SMS-сообщение на сервер с уникальным кодом установки приложения. Затем приложение может запросить тот же сервер, чтобы узнать, получило ли оно недавно SMS-сообщение с устройства с этим уникальным кодом установки приложения. Если это так, он может прочитать номер телефона, который его отправил. Вот демонстрационное видео, показывающее процесс. Как видите, это работает как шарм!

Это не очень просто настроить, но его можно настроить бесплатно за несколько часов на бесплатном уровне AWS с помощью примера кода, приведенного в руководстве здесь .

davidgyoung
источник
Сожалею. Видео было случайно приватным. Это публично сейчас.
Давидгёнг
Это отличный способ, но не могли бы вы дополнить свой ответ, чтобы хотя бы охватить основные детали реализации? Как отправить SMS с устройства iOS, не зная свой номер телефона? Как настроить сервер получения SMS, который имеет доступ к номеру телефона отправителя? Какие инструменты задействованы? совместимость?
Мотти Шнеор
@MottiShneor, вы видели ссылку на учебник в ответе? Это полное руководство по настройке этого решения, а также рабочий пример кода приложения в репозитории Github.
Давидгёнг
2

Чтобы узнать свой номер телефона, вы можете прочитать файл 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]);

Я не знаю, разрешит ли Apple это, но это работает на iPhone.

Давид Гёлжойзер
источник
Apple аннулирует гарантию на взломанные телефоны, и приложение должно иметь повсеместную возможность для всех пользователей.
Космтар
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;
}

Работает на iOS 6 без JB и специальной подписи.

Как упоминалось в Creker на iOS 7 с JB, вам нужно использовать права, чтобы он работал.

Как это сделать с правами, которые вы можете найти здесь: iOS 7: Как получить собственный номер через частный API?

0x8BADF00D
источник
0

AppStore отклонит его, так как он выходит за пределы контейнера приложения.

Приложения должны быть автономными в своих пакетах и ​​не могут читать или записывать данные за пределами указанной области контейнера

Раздел 2.5.2: https://developer.apple.com/app-store/review/guidelines/#software-requirements

thedazed
источник