it-roy-ru.com

Уникальная идентификация пользователя iOS

Я хотел бы создать учетную запись пользователя на сервере для новых пользователей приложения, но я также хотел бы не просить пользователя вводить что-либо. В идеале я бы хотел, чтобы это было автоматически, как в Game Center.

Но мне интересно, если это возможно. Что-нибудь, что я могу использовать, чтобы уникально идентифицировать пользователя? Маловероятно, что я смогу узнать Apple ID пользователя. Кроме того, идентификатор устройства однозначно идентифицирует устройство, а не пользователя, поэтому было бы бесполезно, если бы у пользователя было больше устройств ...

Есть ли что-нибудь еще, что я могу использовать?

О конфиденциальности - я не хочу ничего узнавать за спиной пользователя. У меня нет абсолютно никаких проблем с запросом у пользователя доступа к его информации (и если есть API, который предоставляет мне эту информацию, было бы здорово, если бы API запрашивал это сам). Как сказал сам Стив Джобс, в этом и заключается конфиденциальность - заставлять приложения запрашивать разрешение у пользователя, прежде чем что-либо делать с его личными данными.

36
rid

Правильным решением является использование iCloud Key-Value Store , где вы можете хранить уникальный идентификатор пользователя, не требуя какой-либо аутентификации или пользовательской информации, такой как адрес электронной почты. 

Конечным результатом является случайный UUID (ничего, что фактически идентифицирует пользователя), которое отличается для каждого пользователя, но будет иметь одинаковое значение для нескольких устройств, зарегистрированных в одной учетной записи iTunes.

Мы определяем поле в нашем iCloud KV Store, назовем его userID. Когда приложение запускается, мы сначала проверяем userID. Если это так, то у нас все настроено с уникальным идентификатором нашего пользователя. Если нет, то это первый раз, когда мы запускаем этого пользователя. Мы генерируем случайный UUID и сохраняем его в KV Store под userID. Это все, что нужно сделать.

Наш опыт показывает, что этот UUID уникален для каждой учетной записи iTunes. Если ваши конечные пользователи используют общий доступ к семье, этим учетным записям будут назначаться разные UUID (что может быть или не быть желательным, но вы ничего не можете с этим поделать). Любое количество устройств, запущенных под одной и той же учетной записью iTunes, увидят один и тот же UUID.

Этот подход является абсолютно законным и должен быть одобрен Apple без каких-либо проблем.

Очевидно, что вы должны включить iCloud Key-Value store в Xcode в разделе «Возможности», просто включите iCloud Switch.

Вот простой класс, который реализует эту концепцию в Objective-C:

@implementation EEUserID

+ (NSUUID *) getUUID
{
    NSUUID *uuid = nil;
    NSString *uuidString = [[NSUbiquitousKeyValueStore defaultStore] stringForKey: @"EEUserID"];
    if (uuidString == nil)
    {
        // This is our first launch for this iTunes account, so we generate random UUID and store it in iCloud:
        uuid = [NSUUID UUID];
        [[NSUbiquitousKeyValueStore defaultStore] setString: uuid.UUIDString forKey: @"EEUserID"];
        [[NSUbiquitousKeyValueStore defaultStore] synchronize];
    }
    else
    {
        uuid = [[NSUUID alloc] initWithUUIDString: uuidString];
    }

    return uuid;
}

+ (NSString *) getUUIDString
{
    NSUUID *uuid = [self getUUID];
    if (uuid != nil)
        return uuid.UUIDString;
    else
        return nil;
}

+ (void) load
{
    // get changes that might have happened while this
    // instance of your app wasn't running
    [[NSUbiquitousKeyValueStore defaultStore] synchronize];
}

@end

И для заголовочного файла:

#import <Foundation/Foundation.h>

@interface EEUserID : NSObject

+ (NSUUID *) getUUID;
+ (NSString *) getUUIDString;

@end

Чтобы использовать, все, что вам нужно сделать, это вызвать:

NSString *uniqueIDForiTunesAccount = [EEUserID getUUIDString];

Наслаждаться.

23
ldoogy

Создайте UUID с этим:

NSString *UUID() {
    CFUUIDRef cfuuid = CFUUIDCreate(NULL); 
    NSString *uuid =  (__bridge_transfer NSString *)CFUUIDCreateString(NULL, cfuuid); 
    CFRelease(cfuuid);
    return uuid;
}

Apple ничего не осуждает и не осуждает - на самом деле, именно так они и предлагают вам это сделать. Сохраните сгенерированный UUID в цепочке для ключей, и он будет там - даже если пользователь удаляет и переустанавливает ваше приложение. UUID уникален для устройства и времени его создания.

Затем вы можете использовать различные схемы, чтобы пользователь группировал свои устройства вместе - iCloud или какой-то ключ, который вы доставляете с сервера.

Удачи!

Дополнение:

Вот как я храню его в цепочке для ключей, используя uuid в качестве имени пользователя и генерируя случайный пароль:

uuid = UUID();
[keychainItemWrapper setObject:uuid forKey:(__bridge_transfer id)kSecAttrAccount];
NSString *pass_token = randomString(10);
[keychainItemWrapper setObject:pass_token forKey:(__bridge_transfer id)kSecValueData];

Обратите внимание, что все это может быть сделано без какого-либо участия пользователя.

Обновление:

MCSMKeychainItem имеет отличное решение для генерации и хранения UUID с [MCSMApplicationUUIDKeychainItem applicationUUID]. Библиотека также имеет [MCSMGenericKeychainItem genericKeychainItemWithService:service username:username password:password]. Вместе эти функции заботятся обо всем упомянутом выше. Простота установки с CocoaPods тоже.

22
Erik

Radu

Отличный вопрос. Мы решили проблему, которую вы описываете, интегрировав Urban Airship (urbanairship.com) в наши приложения. Urban Airship предлагает широкий набор функций для поддержки покупок в приложениях, проверки квитанций, восстановления подписки, доставки контента и push-уведомлений Apple.

Одна из замечательных особенностей Urban Airship - это возможность идентифицировать «пользователя», а не устройство, а «пользователя» по адресу электронной почты. На самом деле это не рекламируемая «особенность», а скорее побочный продукт предполагаемой функциональности.

Вот что мы нашли и как мы можем использовать Urban Airship для решения вашей проблемы.

Когда пользователь устанавливает ваше приложение, в которое встроен Urban Airship, UA каким-то образом генерирует UDID-подобный номер, который на данный момент просто идентифицирует устройство. 

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

Он также предлагает функциональность, позволяющую пользователю изменять адрес электронной почты, связанный со всеми его устройствами.

Мы действительно реализовали, и это работает ОЧЕНЬ хорошо!

ПРИМЕЧАНИЕ. По состоянию на 1 июля 2013 года Urban Airship устарела.

4
radesix

Генерация UUID, как предложил Эрик, определенно является надежным решением. Единственным (небольшим) предупреждением может быть то, что в случае полного восстановления iDevice цепочка для ключей также будет стерта. Приложение будет генерировать новый UUID в этом сценарии, и iDevice больше не может быть связан с существующим пользователем.

Другой подход к уникальной идентификации iDevice заключается в создании уникального идентификатора на основе MAC-адреса сетевого интерфейса и объединении его с идентификатором пакета приложения. Этот метод дает уникальный идентификатор, который является специфичным для приложения и надежным. Он не изменится, когда iDevice будет стерт, восстановлен или когда приложение удалено и переустановлено. Из-за этого нет необходимости хранить этот идентификатор в цепочке для ключей.

К счастью, уже есть люди, которые создали небольшую библиотеку для достижения этой цели. Код можно найти на GitHub:

https://github.com/gekitz/UIDevice-with-UniqueIdentifier-for-iOS-5

1
Bas Peters

Как насчет совместного использования игрового центра и iCloud для идентификации пользователя?

Менее вероятно, что пользователь не играет в игру и не синхронизирует свои данные.

0
Mickey

Вы можете использовать сторонние решения, такие как SECUREUDID также проверить это

0
msk

Сегодня наше приложение было отклонено из-за идентификации пользователя Game Center. Он находится в Руководстве по App Store: https://developer.Apple.com/appstore/resources/approval/guidelines.html

Вы не можете использовать уникальный идентификатор Game Center в формате G :.

Единственный способ для нас - использовать интеграцию iOS6 с Facebook.

ОБНОВЛЕНИЕ: Наша новая версия с автоматическим входом в систему FB прошла проверку и доступна в App Store (Словенская дуэль). Использует также подписку inApp, связанную с профилем FB.

0
Lubomir

Это не абсолютно верное решение (и работает только при включенном iCloud), но его очень легко реализовать:.

Единственная проблема заключается в том, что опытные пользователи знают, как удалить контент из iCloud.

Чтобы пользователь не мог просто изменить уникальный идентификатор, сохраненный в iCloud, на другой идентификатор, к которому вы можете добавить какой-то секрет.

0
miho

Альтернативой предложению Эрика является сторонняя библиотека под названием OpenUDID . Вы можете сгенерировать уникальный идентификатор для каждого устройства, и он очень прост: 

#include "OpenUDID.h"
NSString* openUDID = [OpenUDID value];
0
Anthony