目前我正在为我的毕业设计开发一个应用程序。问题是,它不仅仅是一个应用程序,它由一个为用户制作的iOS应用程序和一个为“所有者”制作的macOS应用程序组成。在mac应用程序中,所有者可以创建一个文件,然后在iOS应用程序中应该是红色的。
到目前为止,我已经制作了一个脚本,其中包含了传输信息所需的所有变量,它可以序列化和反序列化一个文件并将其分配给UI。只要我在macOS应用程序上工作,一切都正常,文件可以被创建、反序列化等等,但是当我试图转到iOS应用程序时,我将作为数据模型的完全相同的脚本复制到了项目中,当我试图反序列化在macOS文件中创建的文件时,应用程序崩溃并给了我一个错误:
无法解码类的对象(outferOnCreator.outferOnDataModel)
对于键(根);类可以在源代码或库中定义
那是没有联系的
我调查了这个错误,发现我不能把脚本从一个项目复制到另一个项目,所以我找到了一个源代码,说我应该用这个文件创建一个框架,但是我没有找到任何有用的主题来讨论跨平台框架。
所以我的问题是,我是否真的必须为此目的创建一个框架,如果是的话,我将如何在macOS和iOS上运行。任何其他建议也将不胜感激。提前谢谢乔治。:)
更新
正如danielv所要求的,这里是我存储信息的代码,它也符合NSCoding协议,因此我可以序列化和反序列化它:

import Foundation

class ExcursionDataModel: NSObject, NSCoding {

    var title: String

    var imagesData = [Data]()
    var thumbnailImageData: Data?
    var shortText = String()
    var completeText = String()

    var difficulty: String = "Hard"
    var duration: String = "Long"

    var isFavourite: Bool = false
    var type: excursionType = .other

    enum excursionType: String {
        case biking
        case rafting
        case other
    }

    static let possibleDifficulties = ["Hard", "Medium", "Easy"]
    static let possibleDurations = ["Long", "Medium", "Short"]

    init (title: String) {
        self.title = title
    }

    override init() {
        self.title = "Title"
    }

    struct PropertyKey {
        static let titleKey = "title"
        static let imagesKey = "images"
        static let thumbnailImageKey = "thumbnailImage"
        static let shortTextKey = "shortText"
        static let completeTextKey = "completeText"
        static let difficultyKey = "difficulty"
        static let durationKey = "duration"
        static let isFavouriteKey = "isFavourite"
        static let typeKey = "type"
    }

    //MARK: - NSCoding

    func encode(with aCoder: NSCoder) {

        aCoder.encode(title, forKey: PropertyKey.titleKey)
        aCoder.encode(imagesData, forKey: PropertyKey.imagesKey)
        aCoder.encode(thumbnailImageData, forKey: PropertyKey.thumbnailImageKey)
        aCoder.encode(shortText, forKey: PropertyKey.shortTextKey)
        aCoder.encode(completeText, forKey: PropertyKey.completeTextKey)
        aCoder.encode(difficulty, forKey: PropertyKey.difficultyKey)
        aCoder.encode(duration, forKey: PropertyKey.durationKey)
        aCoder.encode(isFavourite, forKey: PropertyKey.isFavouriteKey)
        aCoder.encode(type.rawValue, forKey: PropertyKey.typeKey)
    }

    required convenience init?(coder aDecoder: NSCoder) {
        let title = aDecoder.decodeObject(forKey: PropertyKey.titleKey) as! String

        self.init(title: title)

        self.imagesData = aDecoder.decodeObject(forKey: PropertyKey.imagesKey) as! [Data]
        self.thumbnailImageData = aDecoder.decodeObject(forKey: PropertyKey.thumbnailImageKey) as? Data
        self.shortText = aDecoder.decodeObject(forKey: PropertyKey.shortTextKey) as! String
        self.completeText = aDecoder.decodeObject(forKey: PropertyKey.completeTextKey) as! String
        self.difficulty = aDecoder.decodeObject(forKey: PropertyKey.difficultyKey) as! String
        self.duration = aDecoder.decodeObject(forKey: PropertyKey.durationKey) as! String
        self.isFavourite = aDecoder.decodeObject(forKey: PropertyKey.isFavouriteKey) as! Bool
        self.type = excursionType(rawValue: aDecoder.decodeObject(forKey: PropertyKey.typeKey) as! String)!
    }
}

最佳答案

NSCoder documentation
NSCoder操作对象、标量、C数组、结构和
字符串,以及指向这些类型的指针。它不处理类型
其实现在不同平台上有所不同,例如union、void*,
函数指针和长的指针链。编码器对象存储
对象类型信息以及数据,因此从
字节流通常与
最初编码到流中。
您在MacOS应用程序中编码的类是ExcursionCreator.ExcursionDataModel。但是,您的iOS应用程序可能有不同的模块名,因此即使您在iOS应用程序中包含完全相同的swift类,实际的命名空间类名也会不同,例如ExcursionIOSApp.ExcursionDataModel
NSCoder不知道这些是相同的类,当它试图解码outsureondata模型时,它找不到它,所以您得到了错误。
你的选择是:
选项1
对序列化使用开放的可移植格式。JSON是一个流行的选择,但也有其他选择。如果你以后决定将你的应用移植到安卓(Android)的话,这在苹果生态系统之外的平台上具有可重用性。
iOS和iOS中有一个基础JSON序列化支持,并且提供了更好的/额外的JSON支持的许多开源项目。
选项2
使用跨平台共享相同实现和名称的不同类。例如,可以使用NSDictionary作为数据结构。只要确保你放的所有东西都符合NSCoder要求的限制
选项3
将数据类放在框架中。这将强制类在从两个项目中使用时具有相同的名称。
要创建框架,请在创建新项目时选择MacOS框架项目。将ExcursionDataModel添加到此框架中。
注意,您需要分别为每个平台编译这个框架。因此,一旦你有了MacOS版,你就需要在xcode中为它添加额外的目标,以便为iOS版编译它。
然后将框架的项目包含在每个应用程序中。请确保从应用程序的源中删除该类。
查看苹果Framework Programming Guide
就我个人而言,我会选择1,使用开放和流行的格式,远离苹果专有的系列化。

10-05 20:22
查看更多