12

I have a simple app running on ios simulator which will (at some point in the app), prompt the user to authorize the following:

  1. Location setting
  2. Address contact book
  3. Pictures/Albums

Because I am doing automation testing on the iOS simulator (several thousand on virtual machines), is there a way to force iOS simulator to have these permissions already set to yes when the app is installed?

I vaguely remember there was a way to manipulate this using a plist file associated with iOS simulator, but I'm not 100% sure if "its all in my head". I'm not finding much on google.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Just a coder
  • 15,480
  • 16
  • 85
  • 138
  • 1
    Not an answer, but a possible path is to check the permissions database at `~/Library/Developer/CoreSimulator/Devices//data/Library/TCC/TCC.db` that might give you a hint on how to update that sqlite database before you start your tests. Please let us know if that works out :) – Felipe Sabino Feb 10 '15 at 23:16
  • 1
    @FelipeSabino i tried it and it worked. I put what i did below – Just a coder Feb 12 '15 at 09:30
  • @FelipeSabino your solution worked great for location Services. Do you also know the database that controls notificaiton alerts? – Just a coder May 12 '15 at 06:19

2 Answers2

11

There's some discussion here on this topic. I'll quote the relevant portion for posterity:

For CoreLocation, you can just call the following private method at some point before your first use:

[CLLocationManager setAuthorizationStatus:YES 
                      forBundleIdentifier:[[NSBundle mainBundle] bundleIdentifier]]

Privacy alerts for contacts, photos and the calendar are handled differently. These can be set via TCCAccessSetForBundle from TCC.framework, but this function is not callable from within the same app whose privacy settings you're attempting to modify AFAICT.

Instead, you can just sign your app with these entitlements:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>com.apple.private.tcc.allow.overridable</key>
    <array>
        <string>kTCCServiceAddressBook</string>
        <string>kTCCServiceCalendar</string>
        <string>kTCCServicePhotos</string>
    </array>
</dict>
</plist>

To hide your app from the Simulator's Privacy Settings screens, replace com.apple.private.tcc.allow.overridable with com.apple.private.tcc.allow.

You probably don't want to include these entitlements in your AppStore build.

(Make sure to take this stuff out when you submit your app - or only include it in your debug target - because it won't pass app review.)

Aaron Brager
  • 65,323
  • 19
  • 161
  • 287
  • +1 Good link. Thanks. This will work for older versions of XCode. Their method seems outdated with the new XCode however. I'm currently looking into another way to solve this based on the comment by https://stackoverflow.com/users/429521 above. – Just a coder Feb 11 '15 at 18:48
  • @Jai What error(s) are you getting with this approach? – Aaron Brager Feb 11 '15 at 20:12
  • The problems are the same the users experienced in the link you posted. The alerts are still shown on screen. I think its due to the last XCode that behaves differently. The user above however mentioned a db file. This seems to work (for the address/calendar/photos alerts). I'm currently trying to do this through a shell script. For the location alert, i implemented a category to bypass it all together. I could not use the undocumented method for this app unfortunately. – Just a coder Feb 12 '15 at 03:16
  • @Jai OK, I'll post a bounty after this question has been open 48 hours to try to get a more updated answer. – Aaron Brager Feb 12 '15 at 03:26
  • Any idea how to get notifications to be authorized in the same way? None of the following worked: kTCCServiceNotifications, kTCCServiceNotification, kTCCServiceLocalNotification, kTCCServiceLocalNotifications – Liron Yahdav Apr 22 '15 at 23:20
  • @LironYahdav I recommend posting a new question – Aaron Brager Apr 23 '15 at 05:13
  • @AaronBrager OK, I asked this in a new question: http://stackoverflow.com/questions/30008145/removing-ios-permission-alert-for-local-notifications-when-running-app-in-simula – Liron Yahdav May 02 '15 at 22:23
  • Using the SecSysInfo app (which was pulled by Apple) I can see an app having those entitlements set, yet it was downloaded from the app store. Do I have to worry or are these entitlements simply ignored in a real environment? – Mojo66 May 27 '16 at 13:31
9

Based on the comment by Felipe Sabino above I worked out the following. The permissions file of iOS for Xcode 6 is stored at location: ~/Library/Developer/CoreSimulator/Devices/<device>/data/Library/TCC/TCC.db. So we modify the db file using sqlite3 on the console.

Used the following Perl script from terminal. This could be done in any language really.

$folderLocations = `xcrun simctl list`; // running "xcrun simctl list" on terminal returns iOS device locations 
$currentUserID = `id -un`;              // get current user
chomp($currentUserID);                  // remove extra white space from user string
print "currentUserID: $currentUserID";  // debug logs

while($folderLocations =~ /iPad Air \((.{8}-.*?)\)/g) { // Use regex to loop through each iPad Air device found in $folderLocations. Insert the permissions in the database of each. 
    print "folderLocations <1>: $1\n";  // debug logs
    `sqlite3 /Users/$currentUserID/Library/Developer/CoreSimulator/Devices/$1/data/Library/TCC/TCC.db "insert into access values('kTCCServiceAddressBook','com.apple.store.MyApp', 0, 1, 0, 0)"`;
    print "\n";  // neat logs
}

This one overrides kTCCServiceAddressBook permission, but there is also kTCCServiceCalendar and kTCCServicePhotos.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Just a coder
  • 15,480
  • 16
  • 85
  • 138
  • There are some things to watch out for: The simulator you want to use needs to be launched at least once (the database gets created then). `simctl list` returns human readable output, which is difficult to parse. Rather use `find . -name TCC` (Where "." is the devices folder) – TAKeanice Mar 23 '15 at 10:11
  • 2
    I've worked that out in https://github.com/SocialbitGmbH/SwiftAddressBook . See `.travis.yml` and the `allowAccess` script for reference – TAKeanice Mar 23 '15 at 10:13
  • By the way, to grant iTunes Library access, use the key `kTCCServiceMediaLibrary` – yano Jan 20 '17 at 22:53