2014-06-16 11 views
5

Sto sviluppando una posizione basata su Q & Un SDK per dispositivi mobili.iOS: Rileva se il mio SDK è installato su un'altra app sul dispositivo

Quando viene posta una domanda su un luogo specifico, il lato server si rivolge all'utente più pertinente e invia la domanda a quell'utente. Se l'utente non risponde, la domanda viene inviata al secondo miglior utente e così via.

Il problema è che il mio SDK potrebbe essere installato su più di un'applicazione sul dispositivo, il che significa che l'utente può ottenere una domanda più di una volta.

C'è un modo per rilevare se il mio SDK è installato su più di un'app? Ho pensato che l'invio dell'UDID al server potesse funzionare, ma iOS UDIDs differ between applications.

+0

sono le due applicazioni dello stesso sviluppatore o diversi sviluppatori? – rmaddy

+0

Le app potrebbero appartenere a sviluppatori separati. –

+0

Ciò lo rende praticamente impossibile con le versioni moderne di iOS. Ogni due app otterrà un ID diverso per ogni ID fornito da Apple tramite la sua API. Due app dello stesso sviluppatore potrebbero rilevarsi a vicenda sul dispositivo utilizzando una lavagna condivisa denominata. Ma due app di uno sviluppatore diverso non possono condividere un pasteboard con nome comune. – rmaddy

risposta

5

È possibile utilizzare UIPasteboard per condividere i dati tra le applicazioni sul dispositivo.

La classe UIPasteboard consente a un'app di condividere i dati all'interno dell'applicazione e con un'altra app. Per condividere i dati con qualsiasi altra app, puoi utilizzare le schede di sistema a livello di sistema; per condividere i dati con un'altra app con lo stesso ID team della tua app, puoi utilizzare le pasteboard specifiche dell'app.

Nel vostro SDK, fare qualcosa di simile:

@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 
0

Penso che sia possibile utilizzare keychain, è possibile disporre di una chiave di portachiavi unica in cui è possibile salvare tutto ciò che si desidera e accessibile da altre app se disponibili. Quindi per il tuo SDK, diciamo che se c'è un'app, registrerà qualche valore nel portachiavi con una chiave univoca che è privata dell'SDK solo se la chiave non esiste, e se esiste lo sai, dal momento che puoi salvare qualsiasi valore nel portachiavi, puoi provare più opzioni e combinazioni che ti si addicono.

È possibile utilizzare KeychainItemWrapper per le implementazioni.

Elaborazione

Diciamo che abbiamo un metodo.

[MySDK register]; 

che può essere utilizzato ovunque, dicono in AppDelegate. Il metodo register genererà un token per l'app, per il dispositivo, che verrà salvato nel portachiavi utilizzando una chiave univoca che abbiamo definito nell'SDK, ad esempio in com.mysdk.key. E mentre si salva in keychain, l'SDK può effettivamente fare una registrazione.

Consideriamo il metodo sopra riportato in più app.

Ora abbiamo uno scenario. installa

  1. utente un App-A che utilizza il SDK, il metodo register chiamerà e creare un token e salverà nel portachiavi per la prima volta.

  2. Ora utente installa un'altra App-B che utilizza anche il SDK, lo stesso metodo register chiamerà, ma ora controllerà la chiave com.mysdk.key in portachiavi, se esiste verrà solo aggiornare il conteggio per il token, che significava per il dispositivo.

Nota

portachiavi non destinato a salvare solo unique identifier, è possibile salvare altre informazioni troppo.

Aggiornamento

controllare demo proietta https://db.tt/7xpKrgMp

Il wrapper ho usato nei progetti è stessa SDK nel tuo caso, che è lo stesso in entrambi i progetti.

Cheers.

+0

Le chiavi e i valori nel portachiavi sono leggibili da ogni altra app? –

+0

Non l'ho provato, ma penso che dovrebbe, dato che usa un portachiavi comune come nei sistemi Mac, quindi se salviamo usando una chiave univoca e proviamo a recuperare in un'altra app con la stessa chiave, dovrebbe funzionare. – iphonic

+0

@AdamMatan Sì, funziona, ho appena provato, un'applicazione ha generato un valore = '64112F7D-2AC6-4F27-ACBA-A64BB7026CEA', ho salvato in una chiave comune, sono stato in grado di ottenere lo stesso valore in altre applicazioni usando la stessa chiave. – iphonic

1

Se si desidera fornire solo un SDK, non è possibile. Apple ha aggiunto misure di sicurezza per impedire che per la privacy degli utenti. La condivisione del portachiavi non funzionerà, perché le app devono condividere lo stesso ID seme (vedere here per maggiori informazioni).

Se si desidera fornire un'app insieme al proprio SDK, allora si potrebbe fare qualcosa come Facebook, dove l'app invia un messaggio "helo", Facebook chiede all'utente e infine Facebook invia un messaggio "ehlo".

La tua app -> "Mi piacerebbe usare l'SDK; per favore dammi un token" -> SDK Controller App -> (Ricorda quali app hanno richiesto l'uso) -> "OK, puoi usare l'SDK; un token: # 123 "-> La tua app

L'app del controller SDK può ora inviare al server l'elenco di app.

+0

Che ne dici di "Chiave univoca" inclusa nell'SDK anziché nell'app? Questo è possibile, immagino. Per ogni dispositivo può essere presente un token per la prima app installata e può essere utilizzato da un'altra app nello stesso dispositivo perché utilizza la stessa chiave. E sarà diverso per dispositivo. Vedi la mia risposta aggiornata. – iphonic

+0

@iphonic Non importa ciò che è incorporato nell'SDK. SDK in iOS è una libreria statica e, durante il tempo di compilazione, i simboli sono collegati agli oggetti corrispondenti nella lib statica. Un'app ha un seme identificativo del bundle, e questo è ciò che conta per la condivisione del portachiavi. È diverso da OS X. –

+0

Sì, è giusto, c'è solo un identificatore visto per app, ma sto chiedendo di creare un ID univoco per un 'dispositivo', e' mantenere nel portachiavi usando una chiave comune' che solo il ' SDK lo sa, questo è sicuramente possibile? – iphonic

0

Penso che sia possibile raggruppare le app sullo stesso dispositivo in base all'indirizzo IP poiché utilizzeranno lo stesso indirizzo per connettersi al server. Quindi l'indirizzo IP rappresenterà il dispositivo e la chiave API rappresenterà l'app che utilizza l'SDK.

0

Puoi provare a utilizzare

advertisingIdentifier

Non è sicuro se serve il vostro scopo. Viene spiegato qui Riferimento alla classe ASIdentifierManager: Apple doc

+0

Ogni venditore ha il proprio identificatore di pubblicità quando un utente seleziona il limite del monitoraggio degli annunci. –

+1

Inoltre, la tua app verrà rifiutata se utilizzi advertisingIdentifier solo per identificare il dispositivo dell'utente. – arturdev