[英]Grant access to NAB programatically on iOS 7.0 Simulator
Is it possible to grant access to the native address book (NAB) on iOS 7.0 Simulator programmatically? 是否可以通过编程方式在iOS 7.0 Simulator上授予对本机地址簿(NAB)的访问权限? I am writing xctest Unit Tests that need write access to NAB.
我正在编写需要对NAB进行写访问的 xctest单元测试。 The unit tests are run on iOS 7.0 Simulator and are part of Continuous Integration process and doesn't involve any user interaction.
单元测试在iOS 7.0 Simulator上运行,是Continuous Integration过程的一部分,不涉及任何用户交互。
Currently unless the user grants access explicitly via the “TestApp” Would like to Access Your Contacts alert, access to NAB is denied. 目前,除非用户通过“TestApp”明确授予访问权限想要访问“联系人”警报,否则将拒绝访问NAB。
In the spirit of sharing I am going to answer my own question. 本着分享的精神,我将回答我自己的问题。 Among other permissions, Address Book access permission is stored in
TCC.db
database that is located in /Library/TCC/
in the iPhone Simulator folder. 在其他权限中, 通讯簿访问权限存储在
TCC.db
数据库中,该数据库位于iPhone Simulator文件夹中的/Library/TCC/
中。
e.g. /Users/useriko/Library/Application Support/iPhone Simulator/7.1-64/Applications/[appGUID]/Library/TCC/TCC.db
Permissions are stored in the access
table in TCC.db database. 权限存储在TCC.db数据库的
access
表中。 access
table schema is: access
表模式是:
The fields we are interested in are: 我们感兴趣的领域是:
service
- the permission type service
- 权限类型 client
- the app identifier client
- 应用程序标识符 allowed
- permission granted? allowed
- 授予许可? In order to grant Access Book permission, and appropriate record should be inserted into the access
table (or updated if already exists). 为了授予Access Book权限,应将相应的记录插入
access
表(如果已存在则更新)。 After the record was either inserted or updated the table should look like that: 插入或更新记录后,表格应如下所示:
I've wrote the following method to update the TCC.db database. 我编写了以下方法来更新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);
}
Because of the obvious reasons, the target should be linked with libsqlite3.dylib . 由于显而易见的原因,目标应该与libsqlite3.dylib链接。
DO NOT forget to change the app identifier ( com.your.app.id ) in the updateSql
to your app identifier. 不要忘记将
updateSql
中的应用程序标识符( com.your.app.id ) updateSql
为您的应用程序标识符。
这个Cocoapod非常适合测试目的: https : //github.com/plu/JPSimulatorHacks
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.