2014-06-30 15 views
6

Czy możliwe jest programowe przyznanie dostępu do macierzystej książki adresowej (NAB) na symulatorze systemu iOS 7.0? Piszę xctest testów jednostkowych, które wymagają zapisu dostępu do NAB. Testy jednostkowe są przeprowadzane na iOS 7.0 Simulator i są częścią procesu ciągłej integracji i nie wymagają żadnej interakcji użytkownika.Przyznanie dostępu do NAB programowo na iOS 7.0 Simulator

Obecnie, chyba że użytkownik wyraźnie przyznaje dostęp za pomocą "TestApp" Chciałby uzyskać dostęp do swojego kontaktu,, dostęp do NAB jest zabroniony.

+0

iOS 8 wersji tego pytania: http://stackoverflow.com/q/30106320/476716 – OrangeDog

Odpowiedz

7

W duchu dzielenia się zamierzam odpowiedzieć na moje własne pytanie. Pośród innych uprawnień, Książka adresowa uprawnienia dostępu są przechowywane w bazie danych TCC.db, która znajduje się pod numerem /Library/TCC/ w folderze iPhone Simulator.

e.g. /Users/useriko/Library/Application Support/iPhone Simulator/7.1-64/Applications/[appGUID]/Library/TCC/TCC.db 

Uprawnienia są przechowywane w tabeli w bazie danych TCC.db access. access schematu tabela: TCC.db schema

Pola jesteśmy zainteresowani są:

  1. service - typ pozwolenie
  2. client     - identyfikator aplikacji
  3. allowed - uprawnienie przyznane?

W celu przyznania dostęp do książki pozwolenie i odpowiedni zapis powinien zostać wstawiony do tabeli access (lub aktualizowane, jeśli już istnieje). Po wstawieniu lub aktualizacji rekordu tabela powinna wyglądać następująco: access table after update

Napisałem następującą metodę aktualizacji bazy danych TCC.db.

#import <sqlite3.h> 

- (void)grantAccessBookAccess { 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    // tccDbPath: /Users/useriko/Library/Application Support/iPhone Simulator/7.1-64/Applications/FB8DF5E9-94B8-4CA9-A167-43AFE794B94E/Document 

    NSString *tccDbPath = nil; 
    tccDbPath = [[[[paths objectAtIndex:0] 
        stringByDeletingLastPathComponent] // remove Document 
        stringByDeletingLastPathComponent] // remove [appGUID] 
        stringByDeletingLastPathComponent]; // remove Applications 

    // tccDbPath: /Users/useriko/Library/Application Support/iPhone Simulator/7.1-64/ 

    tccDbPath = [[[tccDbPath stringByAppendingPathComponent:@"Library"] 
       stringByAppendingPathComponent:@"TCC"] 
       stringByAppendingPathComponent:@"TCC.db"]; 

    // tccDbPath: /Users/useriko/Library/Application Support/iPhone Simulator/7.1-64/Library/TCC/TCC.db 

    sqlite3 *database; 
    if(sqlite3_open([tccDbPath UTF8String], &database) != SQLITE_OK) { 
    NSLog(@"Error while opening database. %s", sqlite3_errmsg(database)); 
    return; 
    } 

    NSString *updateSql = @"INSERT OR REPLACE INTO access (service, client, client_type, allowed, prompt_count) VALUES (\"kTCCServiceAddressBook\",\"com.your.app.id\",0,1,1);"; 

    int rc; 
    char* errmsg; 
    const char *sql = [updateSql UTF8String]; 
    rc = sqlite3_exec(database, sql, NULL, NULL, &errmsg); 
    if (rc != SQLITE_OK) { 
    NSLog(@"Error updating access table. %s", errmsg); 
    sqlite3_free(errmsg); 
    } 

    sqlite3_close(database); 
} 

Ponieważ z oczywistych względów, cel ten powinien być połączony z libsqlite3.dylib.

NIE NIE zapomnij zmienić identyfikator aplikacji (com.your.app.id) w updateSql do identyfikatora aplikacji.

+1

jakieś pomysły jak to zrobić w swift3? –

+0

@Async Przepraszamy. Brak pomysłu. – mrvincenzo

Powiązane problemy