iOS App Extension: Requesting permissions

1k Views Asked by At

I'm writing an integration app harness that will test the functionality of our SDK in the real world and I'm planning to do so using iOS Action App extensions as subprocesses to initiate the Action Extensions as test cases. I followed the article below to accomplish that

https://ianmcdowell.net/blog/nsextension/

And so I created one action extension so far, which is to test starting the library manager of the SDK. It works on the simulator but when tested on the device the test fails, because it requires the Location Services to run the SDK.

I could override that service, but Xcode will generate this logs that complains about not accessing the NSUserDefaults. This adds 30 seconds of testing so I rather avoid that

2017-12-07 10:38:55.907542-0500 LibraryManagerTestExtension[2619:13235133] [User Defaults] Couldn't read values in CFPrefsPlistSource<0x1017041d0> (Domain: com.apple.Accessibility, User: kCFPreferencesCurrentUser, ByHost: No, Container: kCFPreferencesNoContainer, Contents Need Refresh: Yes): accessing preferences outside an application's container requires user-preference-read or file-read-data sandbox access, detaching from cfprefsd
2017-12-07 10:39:25.932663-0500 LibraryManagerTestExtension[2619:13235133] failed to open connection to AppleKeyStore
2017-12-07 10:39:25.933117-0500 LibraryManagerTestExtension[2619:13235133] Unexpected AppleKeyStore error: -536870212
2017-12-07 10:39:25.933951-0500 LibraryManagerTestExtension[2619:13235133] MKBDeviceUnlockedSinceBoot: MKBDeviceUnlockedSinceBoot fails with error(-1) for handle(0) with AKS error(-536870212)
2017-12-07 10:39:25.934237-0500 LibraryManagerTestExtension[2619:13235133] Attempting to create a background session before first device unlock!
2017-12-07 10:39:25.938302-0500 LibraryManagerTestExtension[2619:13235250] An error occurred on the xpc connection: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service named com.apple.nsurlsessiond was invalidated." UserInfo={NSDebugDescription=The connection to service named com.apple.nsurlsessiond was invalidated.}

Here are my codes. Hope you can provide me some guidance on what things I'm missing and needed to be added to get the permissions.

import Foundation
import IntegrationExtension
import VSTB

public class LibraryManagerTestExtension : NSObject, NSExtensionRequestHandling {
    var extensionContext : NSExtensionContext!
    var libraryManager : QPLibraryManager!

    public func beginRequest(with context: NSExtensionContext) {
        print("Beginning request with context: %@", context.description);
        extensionContext = context

        guard let configContent = getConfigContent() else {
            extensionContext.cancelRequest(withError: QPError(code: -1, description: "ConfigContent is empty"))
            return
        }
        startLibraryManager(configContent)
    }

    func getConfigContent() -> [String: Any]? {
        //Get the config path, which is the 1st first of the input items
        let inputItems = extensionContext.inputItems
        print("Input Items: \(inputItems)")
        assert(inputItems.count == 1)

        let inputItem = inputItems.first as? NSExtensionItem
        assert(inputItem?.attachments?.count == 1)

        return inputItem?.attachments?.first as? [String: Any]
    }

    fileprivate func startLibraryManager(_ contentConfig: [String: Any]) {
        let foo = isOpenAccessGranted()
        print("Access: \(foo)")

        let configuration = QPLibraryConfiguration(dictionary: contentConfig)
        //Disable location services by overriding it with custom values. This adds 30 seconds of testing though, which needs to be avoided
        configuration?.setStartupLibraryConfigurationValue(0, for: .IOS_LOCATION_MANAGER_MODE)
        let userLocation : [String : Any] = ["country" : "IN",
                                            "territory" : "",
                                            "city" : "Chennai",
                                            "latitude" : 0,
                                            "longitude" : 0]
        configuration?.setRuntimeLibraryConfigurationValue(userLocation, for: .USER_LOCATION)
        libraryManager = QPLibraryManager()
        libraryManager.delegate = self
        libraryManager.start(with: configuration)
    }
}

extension LibraryManagerTestExtension : QPLibraryManagerDelegate {
    public func libraryManager(_ libraryManager: QPLibraryManager!, didStartWith association: QPLibraryManagerAssociation!) {
        //Handle Library Start
        let item = NSExtensionItem()
        extensionContext.completeRequest(returningItems: [item]) { (expired : Bool) in
            print("Completed Request")
        }
    }

    public func libraryManager(_ libraryManager: QPLibraryManager!, didFailToStartWith association: QPLibraryManagerAssociation!, error: QPError!) {
        //Handle Library failed
        extensionContext.cancelRequest(withError: error)
    }
}

Here's the .plist file. Note that the action extension is a non-ui extensions that are manually triggered by the app. App groups are also enabled on both app and extension

<key>NSExtension</key>
<dict>
    <key>NSExtensionAttributes</key>
    <dict>
        <key>RequestOpenAccess</key>
        <true/>
        <key>NSExtensionActivationRule</key>
        <string>FALSEPREDICATE</string>
    </dict>
    <key>NSExtensionPointIdentifier</key>
    <string>com.apple.app.non-ui-extension</string>
    <key>NSExtensionPrincipalClass</key>
    <string>$(PRODUCT_MODULE_NAME).LibraryManagerTestExtension</string>
</dict>
0

There are 0 best solutions below