iOS: определить, установлен ли мой SDK в других приложениях на устройстве

Я разрабатываю Q&A SDK для мобильных устройств на основе определения местоположения.

Когда задается вопрос о конкретном местоположении, серверная сторона нацеливается на наиболее релевантного пользователя и отправляет вопрос этому пользователю. Если пользователь не отвечает, вопрос отправляется второму лучшему пользователю и так далее.

Проблема в том, что мой SDK может быть установлен более чем на одном приложении на устройстве, что означает, что пользователь может получить вопрос более одного раза.

Есть ли способ определить, установлен ли мой SDK более чем в одном приложении? Я думал, что отправка UDID на сервер может работать, но iOS UDID отличаются между приложениями.

5 ответов

Решение

Вы можете использовать UIPasteboard для обмена данными между приложениями на устройстве.

Класс UIPasteboard позволяет приложению обмениваться данными внутри приложения и с другим приложением. Для обмена данными с любым другим приложением вы можете использовать общесистемные монтажные панели; для обмена данными с другим приложением, имеющим тот же идентификатор группы, что и ваше приложение, вы можете использовать специальные монтажные панели для приложений.

В вашем SDK сделайте что-то вроде этого:

@interface SDKDetector : NSObject

@end

@implementation SDKDetector

+ (void)load
{
    int numberOfApps = (int)[self numberOfAppsInDeviceUsingSDK];
    NSLog(@"Number of apps using sdk:%d", numberOfApps);
}

+ (NSInteger)numberOfAppsInDeviceUsingSDK
{
    static NSString *pasteboardType = @"mySDKPasteboardUniqueKey";

    NSData *value = [[UIPasteboard generalPasteboard] valueForPasteboardType:pasteboardType];
    NSMutableArray *storedData = [[NSKeyedUnarchiver unarchiveObjectWithData:value] mutableCopy];

    if (!storedData) {
        storedData = [NSMutableArray new];
    }

    NSString *bundleId = [[NSBundle mainBundle] bundleIdentifier];
    if (![storedData containsObject:bundleId]) {
        [storedData addObject:[[NSBundle mainBundle] bundleIdentifier]];
    }

    value = [NSKeyedArchiver archivedDataWithRootObject:storedData];
    [[UIPasteboard generalPasteboard] setData:value forPasteboardType:pasteboardType];

    return [storedData count];
}

@end

Если вы хотите предоставить только SDK, это невозможно. Apple добавила меры безопасности, чтобы предотвратить это для конфиденциальности пользователя. Совместное использование цепочки для ключей не будет работать, потому что приложения должны использовать один и тот же идентификатор начального числа пакета (см. Здесь для получения дополнительной информации).

Если вы хотите предоставить приложение вместе с вашим SDK, то вы можете сделать что-то вроде Facebook, где приложение отправляет сообщение "helo", Facebook запрашивает пользователя и, наконец, Facebook отправляет сообщение "ehlo".

Ваше приложение -> "Я хотел бы использовать SDK; пожалуйста, дайте мне токен" -> Приложение контроллера SDK -> (Запомните, какие приложения запросили использование) -> "Хорошо, вы можете использовать SDK; вот токен: #123" -> Ваше приложение

Приложение контроллера SDK теперь может отправлять серверу список приложений.

Я думаю, что вы можете сгруппировать приложения на одном устройстве по IP-адресу, так как они будут использовать один и тот же адрес для подключения к вашему серверу. Таким образом, IP-адрес будет представлять устройство, а ключ API - приложение, которое использует SDK.

Можете ли вы попробовать использовать

advertisingIdentifier

Не уверен, служит ли это вашей цели. Это объясняется здесь Ссылка на класс ASIdentifierManager: Apple Doc

Я думаю, что это возможно с помощью keychain, вы можете иметь уникальный ключ цепочки для ключей, в котором вы можете сохранить все, что вы хотите, и могут быть доступны из других приложений, если они доступны. Так что для вашего SDK, скажем, если есть одно приложение, оно зарегистрирует некоторое значение в цепочке для ключей с уникальным ключом, который является частным для вашего SDK, только если ключ не существует, и если он существует, вы узнаете, так как вы можете сохранить любое значение в связке ключей вы можете попробовать несколько вариантов и комбинаций, которые вам подходят.

Вы можете использовать KeychainItemWrapper для реализации.

разработка

Допустим, у нас есть метод.

[MySDK register];

Который может быть использован где угодно, скажем, в AppDelegate, register Метод сгенерирует токен для приложения, для устройства, которое мы сохраним в цепочке для ключей, используя уникальный ключ, который мы определили в SDK, скажем, в com.mysdk.key, И при сохранении в keychain SDK действительно может сделать регистрацию.

Мы считаем, что вышеописанный метод реализован в нескольких приложениях.

Теперь у нас есть сценарий.

  1. Пользователь устанавливает App-A который использует SDK, register Метод вызовет и создаст токен и сохранит его в связке ключей в первый раз.

  2. Теперь пользователь устанавливает другой App-B который также использует SDK, тот же самый register вызовет метод, но теперь он проверит ключ com.mysdk.key в цепочке для ключей, если существует, он просто обновит счет для токена, который означал для устройства.

Заметка

Брелок не предназначен только для сохранения unique identifierВы также можете сохранить другую информацию.

Обновить

Проверьте демонстрационные проекты https://db.tt/7xpKrgMp

wrapper Я использовал в проектах то же самое, что и SDK в вашем случае, который одинаков в обоих проектах.

Приветствия.

Другие вопросы по тегам