我正在编写一个集成应用程序工具,它将在现实世界中测试我们的 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>