我可以在协议上使用Swift的map()吗?

时间:2018-03-02 02:32:31

标签: swift protocols swift-protocols

我有一些模型代码,我有一些Thought s我想要读取和写入plists。我有以下代码:

protocol Note {
    var body: String { get }
    var author: String { get }
    var favorite: Bool { get set }
    var creationDate: Date { get }
    var id: UUID { get }
    var plistRepresentation: [String: Any] { get }
    init(plist: [String: Any])
}

struct Thought: Note {
    let body: String
    let author: String
    var favorite: Bool
    let creationDate: Date
    let id: UUID
}

extension Thought {
    var plistRepresentation: [String: Any] {
        return [
            "body": body as Any,
            "author": author as Any,
            "favorite": favorite as Any,
            "creationDate": creationDate as Any,
            "id": id.uuidString as Any
        ]
    }

    init(plist: [String: Any]) {
        body = plist["body"] as! String
        author = plist["author"] as! String
        favorite = plist["favorite"] as! Bool
        creationDate = plist["creationDate"] as! Date
        id = UUID(uuidString: plist["id"] as! String)!
    }
}

对于我的数据模型,然后在我的数据写入控制器中我有这个方法:

func fetchNotes() -> [Note] {
    guard let notePlists = NSArray(contentsOf: notesFileURL) as? [[String: Any]] else {
        return []
    }
    return notePlists.map(Note.init(plist:))
}

由于某种原因,行return notePlists.map(Note.init(plist:))会出现错误'map' produces '[T]', not the expected contextual result type '[Note]' 但是,如果我用return notePlists.map(Thought.init(plist:))替换该行,我没有任何问题。显然,我无法映射协议的初始化程序?为什么不呢?什么是替代解决方案?

1 个答案:

答案 0 :(得分:0)

如果您希望有多种类型符合Note,并且想知道它存储在您的词典中的哪种类型的注释,则需要使用所有注释类型为您的协议添加枚举。

enum NoteType {
    case thought 
}

将其添加到您的协议中。

protocol Note {
    var noteType: NoteType { get }
    // ...
}

并将其添加到Note对象中:

 struct Thought: Note {
     let noteType: NoteType = .thought
     // ...
  }

通过这种方式,您可以从字典中读取此属性并进行相应的映射。