作为先驱,我对 Game Center 并不熟悉,因此可能存在一些我没有考虑到的问题。所以,有了这个,我解决这个问题的本能是从启动参数开始的。这里有一篇关于如何做到这一点的精彩文章:https ://www.swiftbysundell.com/articles/launch-arguments-in-swift/ 。
现在您可以根据来自不同方案的启动参数开始改变行为,您可以开始研究如何分割您的测试/产品数据。
由于我不是 CoreData 专家,我不能 100% 有信心地说这是可能的(或容易),但我会研究如何根据启动参数设置单独的持久存储。使用本文-testGameCenter
作为参考,在测试 Game Center 时,在为新TestGameCenter
方案创建启动参数以创建内存数据存储后,您似乎可以大致执行以下操作
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "YourDataStore")
if CommandLine.arguments.contains("-testGameCenter") {
let description = NSPersistentStoreDescription()
description.url = URL(fileURLWithPath: "/dev/null")
container.persistentStoreDescriptions = [description]
}
container.loadPersistentStores(completionHandler: { _, error in
if let error = error as NSError? {
fatalError("Failed to load stores: \(error), \(error.userInfo)")
}
})
return container
}()
如果您能够解决上面的 CoreData 问题,那么是时候开始研究如何分割您的 UserDefaults 数据了。立即想到的这个粗略但简单的解决方案是在test
从您的测试方案运行时为您的 UserDefault 键添加前缀。下面是一个示例,说明如何围绕 UserDefaults 构造一个包装器来管理它
struct UserDefaultsWrapper {
let userDefaults: UserDefaults
let keyPrefix: String
init(userDefaults: UserDefaults, keyPrefix: String) {
self.userDefaults = userDefaults
self.keyPrefix = keyPrefix
}
func setValue(_ value: Any?, forKey key: String) {
self.userDefaults.setValue(value, forKey: prefixedKey(forKey: key))
}
func value(forKey key: String) -> Any? {
self.userDefaults.value(forKey: prefixedKey(forKey: key))
}
func prefixedKey(forKey key: String) -> String {
return "\(keyPrefix)\(key)}"
}
}
你可以像这样使用包装器
let userDefaultsPrefix = CommandLine.arguments.contains("-testGameCenter") ? "testGameCenter_" : ""
let userDefaultsWrapper = UserDefaultsWrapper(userDefaults: .standard, keyPrefix: userDefaultsPrefix)
为了获得更优雅的东西,您可以多看一下 UserDefaults,看看您是否可以应用类似于 CoreData 的解决方案,其中有两个完全独立的商店。快速浏览一下这个初始化器,也许你可以用你的包装器做一些像这样简单的事情
struct UserDefaultsWrapper {
let userDefaults: UserDefaults
init(userDefaults: UserDefaults) {
self.userDefaults = userDefaults
}
func setValue(_ value: Any?, forKey key: String) {
self.userDefaults.setValue(value, forKey: key)
}
func value(forKey key: String) -> Any? {
self.userDefaults.value(forKey: key)
}
}
你在哪里建造它
let userDefaultsSuiteName: String? = CommandLine.arguments.contains("-testGameCenter") ? myTestingGameCenterSuiteName : nil
let userDefaults = UserDefaults(suiteName: userDefaultsSuiteName)
let userDefaultsWrapper = UserDefaultsWrapper(userDefaults: userDefaults)
最后,从您对另一个回复的评论来看,听起来您也关心全新安装场景。也就是说,我概述的方法对于在删除/安装中持久化数据没有帮助(至少我不认为)。但是,我认为您应该考虑的是是否有必要从您的生产捆绑包 ID 中测试这些删除/安装问题。您能否改为从测试包 id 手动测试这些问题和/或围绕涉及这些问题的组件编写单元测试?当你接近你的测试策略时,确保你在正确的层测试正确的东西是很重要的;在错误的层测试错误的东西会使每个测试层都更难执行