iOS App Extension:请求权限

时间:2017-12-07 15:49:11

标签: ios permissions ios-app-extension ios-permissions

我正在编写一个集成应用程序工具,它​​将在现实世界中测试我们SDK的功能,并且我计划使用iOS Action App扩展作为子进程来启动Action Extensions作为测试用例。我按照下面的文章来完成

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

所以到目前为止我创建了一个动作扩展,即测试启动SDK的库管理器。它在模拟器上工作,但在设备上测试时测试失败,因为它需要位置服务来运行SDK。

我可以覆盖该服务,但Xcode会生成这些抱怨无法访问NSUserDefaults的日志。这增加了30秒的测试,所以我宁愿避免这种情况

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.}

这是我的代码。希望您能为我提供一些指导,说明我缺少哪些内容并需要添加以获取权限。

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)
    }
}

这里是.plist文件。请注意,操作扩展是由应用程序手动触发的非ui扩展。应用程序组也在应用和扩展程序

上启用
<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>

1 个答案:

答案 0 :(得分:0)

我还根据Ian McDowell的工作进行了一些测试。

我建议您将NSExtensionPointIdentifier从com.apple.app.non-ui-extension更改为com.apple.services(非UI操作),然后应允许您执行这些操作的权限。

请注意,您仍然可以以相同的方式使用NSExtension私有API,并且如果您未定义NSExtensionServiceRoleType,则Action扩展不应对用户可见。