所以我对 Swift 还很陌生,还不太清楚面向协议(protocol)编程的最佳实践,可以使用一些建议。我想做的是在 Parse 之上创建一个抽象层,让我从 Parse 加载对象并将它们转换为实现“BackendLoading”协议(protocol)的结构/类。这是我到目前为止的想法:
import Foundation
import Parse
protocol BackendLoading {
typealias AbstractType
static var backendDBKey: String { get }
static var propertyKeyNames: [String] { get }
init()
init(parameterDictionary: [String: AnyObject])
}
protocol BackendLoader {
func loadAllObjectsFromBackend<T where T: BackendLoading>(classType: T.Type) -> [T];
}
extension BackendLoader {
func getPropertyDictionaryFromType<T where T: BackendLoading>(classType: T.Type) -> [String: String] {
var returnDictionary = [String: String]()
let mirror = Mirror(reflecting: T())
for child in mirror.children {
if let label = child.label {
returnDictionary[label] = label
}
}
return returnDictionary
}
}
struct ParseBackendLoader: BackendLoader {
func loadAllObjectsFromBackend<T where T: BackendLoading>(classType: T.Type) -> [T] {
var returnArray = [T]()
let parseObjectArray = loadAllParseObjectsFromBackend(classType)
let propertyDictionary = getPropertyDictionaryFromType(T)
for parseObject in parseObjectArray {
let extractedDictionary = extractPropertiesFromParseObject(parseObject, propertyDictionary: propertyDictionary)
let object = T(parameterDictionary: extractedDictionary)
returnArray.append(object)
}
return returnArray
}
func extractPropertiesFromParseObject(parseObject: PFObject, propertyDictionary: [String: String]) -> [String: AnyObject] {
var returnDictionary = [String: AnyObject]()
for (key, _) in propertyDictionary {
if let parseValue = parseObject[key] {
returnDictionary[key] = parseValue
}
}
return returnDictionary;
}
func loadAllParseObjectsFromBackend<T where T: BackendLoading>(classType: T.Type) -> [PFObject] {
do {
let query = PFQuery(className: T.backendDBKey)
return try query.findObjects()
} catch {
print(error)
return [PFObject]()
}
}
}
这是我在单元测试中使用的对象,它连接到 Parse 中的等效后端:
class TestLoading: BackendLoading {
typealias AbstractType = TestLoading
static var backendDBKey = "TestObject"
static var propertyKeyNames = ["testObjectString"]
var testObjectString: String?
required init() {}
required init(parameterDictionary: [String: AnyObject]) {
if let testObjectStringFromDict = parameterDictionary["testObjectString"] as? String {
testObjectString = testObjectStringFromDict
}
}
}
一切正常...只是想知道我是否以正确的方式进行此操作。谢谢!
最佳答案
除了协议(protocol)设计之外的一个评论:根据 findObjects() 抛出的错误,需要特定的错误处理。我通常不会捕获错误并将其记录下来,而是将其传递给调用者。有些错误可以自动恢复,有些需要用户交互,有些可以或必须忽略。例如。应该向用户报告打开的飞行模式。在 API 设计的早期考虑错误处理 - 最终你不能忽视它。
关于ios - 使用 Swift 2 中的面向协议(protocol)编程解析抽象层,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34458055/