- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
目前我正在为我的毕业设计开发一个应用程序。问题是,它不仅仅是一个应用程序,它由一个为用户制作的 iOS 应用程序和一个为“所有者”制作的 macOS 应用程序组成。在 mac 应用程序中,所有者可以创建一个文件,该文件在 iOS 应用程序中应该是红色的。
到目前为止,我已经制作了一个脚本,其中包含传输信息所需的所有变量,它可以序列化和反序列化文件并将其分配给 UI。只要我在 macOS 应用程序上工作,一切都运行良好,可以创建文件、反序列化等等,但是当我尝试转到 iOS 应用程序时,我将用作 dataModel 的完全相同的脚本复制到项目中当我尝试反序列化在 macOS 文件中创建的文件时,应用程序崩溃并给我一条错误消息:
cannot decode object of class (ExcursionCreator.ExcursionDataModel) for key (root); the class may be defined in source code or a library that is not linked'
我调查了这个错误,发现我不能只将脚本从一个项目复制到另一个项目,所以我找到了一个来源说我应该只用这个文件创建一个框架,但是我还没有找到任何讨论跨平台框架的有用主题。
简单来说,我的问题是,我是否必须为此目的创建一个框架,如果是的话,我将如何做才能使其在 macOS 和 iOS 上都能正常工作。任何其他建议也将不胜感激。在此先感谢豪尔赫。 :)
正如 danielv 所问,这是我存储信息的代码,它也符合 NSCoding 协议(protocol),因此我可以对其进行序列化和反序列化:
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 operates on objects, scalars, C arrays, structures, and strings, and on pointers to these types. It does not handle types whose implementation varies across platforms, such as union, void *, function pointers, and long chains of pointers. A coder object stores object type information along with the data, so an object decoded from a stream of bytes is normally of the same class as the object that was originally encoded into the stream.
您在 MacOS 应用程序中编码的类是 ExcursionCreator.ExcursionDataModel
。但是,您的 iOS 应用程序可能具有不同的模块名称,因此即使您在 iOS 应用程序中包含完全相同的 swift 类,实际的命名空间类名称也会不同,例如 ExcursionIOSApp.ExcursionDataModel
。
NSCoder 不知道这些是相同的类,当它尝试解码 ExcursionDataModel 时找不到它,所以你会得到错误。
您的选择是:
选项#1
为您的序列化使用开放的可移植格式。 JSON 是一个流行的选择,但还有其他选择。如果您以后决定将您的应用程序移植到 Android,这有利于在 Apple 生态系统之外的平台中重用。
MacOS/iOS 中有一个基础的 JSON 序列化支持,许多开源项目提供更好/额外的 JSON 支持。
选项 #2
使用跨平台共享相同实现和名称的不同类。例如,您可以使用 NSDictionary 作为您的数据结构。只要确保你放在那里的所有东西都符合 NSCoder 要求的限制
选项 #3
将您的数据类放入框架中。这将强制该类在两个项目中使用时具有相同的名称。
要创建框架,请在创建新项目时选择一个 MacOS 框架项目。将您的 ExcursionDataModel
添加到此框架。
请注意,您需要为每个平台单独编译此框架。因此,一旦您拥有适用于 MacOS 的它,您将需要在 xcode 中为其添加额外的目标,以便为 iOS 编译它。
然后将您的框架项目包含在您的每个应用程序中。确保从您的应用程序源中删除该类。
查看 Apple 的 Framework Programming Guide ,
就我个人而言,我会选择选项 #1,使用开放和流行的格式,并远离 Apple 的专有序列化。
关于ios - 适用于 iOS 和 macOS 的 Swift 框架,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40746834/
在跨平台应用程序中,我正在使用一个配置文件,允许用户根据需要覆盖各种默认值。 我的问题是...在哪里放置/查找此配置文件,尤其是关于 MacOS X(我从未使用过且无法访问)?我知道 MacOS X
由于Xcode的代码签名和存档非常耗时,枯燥且有问题,因此我一直通过自己的脚本使用命令行工具xcodebuild,codesign等对我的开发人员ID签名的macOS应用进行代码签名,存档和交付。公证
我正在寻找一种在 MacOs 应用程序中以编程方式逐帧绘制动画的方法(不是关键帧属性动画)。我尝试使用drawLayer:inContext:委托(delegate)方法绘制到CALayers,调用s
就目前情况而言,这个问题不太适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、民意调查或扩展讨论。如果您觉得这个问题可以改进并可能重新开放,visit
我在83%的安装openCV中遇到问题...我的python是2.7.3。我已经适应了xcode。我使用了这个tuturial。 我的Cmake: cmake -D CMAKE_BUILD_TYPE=
我需要弄清楚 Mac 的日志键的键码(ctrl、shift 等)或者需要知道如何跟踪这个日志按键事件... 基本上我正在将 mac key 代码转换为等效的 Windows key 代码......我
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 2年前关闭。 Improve thi
我想将一个 Rust 程序从我的 x86 Mac 交叉编译成一个可以在 Silicon Mac 上运行的二进制文件,但我无法弄清楚链接。 我有: 运行 macOS 10.15.7 Catalina 的
在 macOS ventura 中,我无法复制我的终端应用程序。 我想这样做,因为我有一个 M1 处理器,我想要一个使用 Rosetta2 打开的处理器和一个本地打开的处理器。 有什么办法解决这个问题
当您可以访问实际硬件时,在 Mac 上以安全模式启动是很容易的。您只需在启动时按住 shift 键即可。 在虚拟机中运行 macOS (OSX) 时如何启动到安全模式? 最佳答案 Schmitty 在
这个问题在这里已经有了答案: How to get Conda and Virtualenv to work on mac OS Catalina? (8 个答案) 关闭 3 年前。 我在 macO
我有一个关于 macOS 应用程序图标的问题。我以前看过很多动画图标,但从来没有真正密切关注正在发生的事情/他们是如何做的。我只是想知道是否有任何方法可以创建在停靠栏中动画的动画应用程序图标。 例如:
每当我在 vim 中输入终端命令(例如,!echo hello)时,我会立即被踢出去查看该终端命令的结果,然后提示我使用 按 ENTER 或键入命令继续。这有点刺耳。我想留在 vim 中,并在底部打印
当使用文本编辑应用程序时,选择一种字体(例如“Menlo”)来呈现字形,当所选字体不包含特殊字形(例如“𠹷”,它是一个简单的中文字形,“Menlo"不包含它), 应用程序会选择一种字体来呈现它, 在
已经有几个关于如何在 Mac 上启用虚拟化的问题(例如 How to enable support of CPU virtualization on Macbook Pro?)。经常报告 sysctl
这只是出于好奇。 Exposé 有两个功能,其中一个是重新排列桌面上的窗口,一个是显示所有打开的窗口,这样用户可以看到隐藏在其他窗口下面的窗口,另一个功能是将所有窗口移到两侧,让用户与桌面交互。 我只
我使用的是 MacOS X,我对应用程序包类型的东西还很陌生。我正在编写一个程序来打开一个窗口并注册鼠标输入——而不是一个命令行工具。当我将我的代码(用 C 编写,如果这很重要)编译成一个可执行文件(
我正在制作一个必须支持 macOS 的 Flutter 插件。但是,当我想创建一个插件并在示例应用程序中运行该插件时(即使我还没有编辑过 Flutter 生成的代码),Xcode 会抛出以下错误。 无
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 7年前关闭。 Improve thi
我想在终端(MacOs)中像屏幕一样显示当前目录面包屑: 我该怎么做? 现在它只是一个文本...... 谢谢 最佳答案 首选项 -> 窗口 -> 检查工作目录或文档下的“路径”。 路径将作为窗口标题的
我是一名优秀的程序员,十分优秀!