在iOS 7.0模拟器上以编程方式授予对NAB的访问权限

是否有可能以编程方式授予在iOS 7.0 Simulator上的原生地址簿(NAB)访问权限? 我正在写xctestunit testing,需要写访问 NAB。 unit testing在iOS 7.0模拟器上运行,是持续集成过程的一部分,不涉及任何用户交互。

目前,除非用户通过“TestApp”明确授予访问权限,否则将拒绝访问NAB。

本着分享的精神,我将回答我自己的问题。 在其他权限中, 地址簿访问权限存储在位于iPhone Simulator文件夹的/Library/TCC/中的TCC.db数据库中。

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

权限存储在TCC.db数据库的access表中。 access表架构是: TCC.db模式

我们感兴趣的领域是:

  1. service – 权限types
  2. client – 应用程序标识符
  3. allowed – 权限授予?

为了授予访问簿权限,并应将相应的logging插入access表(如果已经存在,则更新)。 logging插入或更新后,表格应如下所示: 访问表后更新

我已经写了下面的方法来更新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); } 

由于显而易见的原因,目标应该与libsqlite3.dylib链接。

不要忘记将updateSql中的应用程序标识符( com.your.app.idupdateSql为您的应用程序标识符。

这个Cocoapod非常适合testing用途: https : //github.com/plu/JPSimulatorHacks