ios - 使用 Swift 2 中的面向协议(protocol)编程解析抽象层

标签 ios swift

所以我对 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/

相关文章:

ios - 为什么 NSHashTable 保持对指针的引用?

ios - 是否可以将相同的 View 添加到两个不同的 View Controller ?

javascript - Jquery 滚动功能不适用于 iphone 设备

iphone - iPhone SDK 中的信用卡验证算法

android - 是否可以使用 Google map 在 Android/iOS 上创建转弯 GPS 导航应用程序?

ios - UITableViewCells 消失

ios - 成员运算符 '%' 必须至少有一个 'ViewController’ 类型的参数

swift - 如何让细胞变大几秒钟?

swift - 如何在 TableView 上居中弹出窗口?

swift - 模块文件的部署目标是 ios9.0 v9.0 with Xcode 7/Swift 2