将带有字符串和 NSImage 属性的 Class 导出到文件
Export Class with String & NSImage Properties to File
我有一个 class,我希望能够将其打开并导出到文件中。它不需要编辑 - 这只是一种与我的应用程序的其他用户共享部分对象 CoreData 数据库的方法,所以我认为我不需要 subclassing NSDocument
的复杂性.
class 非常基本,有两个属性 String
和一个 NSImage
的文件名,它引用应用程序沙箱中的图像。
最初,我想到了使用文档包,基本上是一个包含图像的文件夹(如果需要)和一个包含字符串和图像文件名的 plist。
现在,我倾向于创建一个 class-just-for-export-and-import,它使用 NSCoding
将图像和字符串保存到文件中。
以下是我不确定的内容:
- 这是个好主意吗?我在这里遗漏了什么吗?
- 我可以将具有
NSImage
和 String
属性的对象数组保存到一个文件中吗?我知道我可以很容易地保存图像,但我可以将它们捆绑到一个文档中吗? NSCoding
是这样做的方法吗?
- 我需要先将
NSImage
转换为 NSData
吗?
- 我的解码器如何知道文件的哪一部分是
String
,哪一部分是 NSImage
?
我研究过了!有很多关于保存图像或保存 NSDocument
的信息,但我只是想为用户提供一种简单的方法来 将任意数据导出和导入 到我的或从中导出应用程序的核心数据存储。
任何一个选项都应该可以正常工作。如果您选择 NSCoding
路线,请务必使用键控存档器。
任何一个选项都可以处理一个对象数组,你只需要设计你的文件结构/处理代码来检查和处理它。
对于文件选项,图像将只是磁盘上的图像。对于编码选项,所有内容都将是磁盘上的二进制数据,但这是在编码过程中完成的(您将在此处将图像转换为数据)。
根据文件的结构,这可能是包中文件的扩展名。对于编码选项,它是键名。
您的两个选项对于用户来说实际上是相同的,并且将来可以扩展,您选择哪个取决于个人喜好。我希望编码选项更快更容易编写代码。
实施 NSCoding 协议,您可以轻松共享您描述的对象。
public required init!(coder:NSCoder)
{
self.busStopName = coder.decodeObjectForKey("busStopName") as? String
self.busStopID = coder.decodeIntegerForKey("busStopID") as Int
let lines: [String]! = coder.decodeObjectForKey("busLines") as? [String]
let photo: NSData = coder.decorDataForKey("photo") as? NSData
}
public override func encodeWithCoder(encoder: NSCoder) -> Void
{
encoder.encodeObject(self.busStopName, forKey:"busStopName")
encoder.encodeInteger(self.busStopID, forKey: "busStopID")
encoder.encodeObject(self.busLines, forKey: "busLines")
encoder.encodeDataObject(self.busStopImage, forKey: "photo")
}
为了从 NSData 创建一个 UIImage 使用这个 initializer
let image: UIImage = UIImage(data: <the nsdata decoded>)
并使用此 UIKit 函数之一从 UIImage 获取 NSData
使用 NSCoding
你可以保存每一个 class 内置支持这个协议的或者你自己添加的。 NSImage
和 – 当然 – NSString
都符合 NSCoding
。您只需为您的自定义 class、which is pretty simple:
添加 NSCoding
支持
- (void)encodeWithCoder:(NSCoder*)coder
{
[coder encodeObject:self.stringProperty forKey:@"String Property"];
[coder encodeObject:self.imageProperty forKey:@"Image Property"];
}
- (instancetype)initWithCoder:(NSCoder*)coder
{
self = [super init]; // or `-initWithCoder:, if it is supported
if (self)
{
self.stringProperty = [coder decodeObjectForKey:@"String Property"];
self.imageProperty = [coder decodeObjectForKey:@"Image Property"];
}
return self;
}
如果您想将数据保存为属性列表文件,您只能使用属性列表classes。 NSString
is a property list, but NSImage
is not – 当然你的习惯 class 不是。因此,您必须将 NSImage
的实例和您的自定义 class 的实例转换为 NSData
的实例,因为 NSData
是一个 属性 列表。你可以用 - drum-roll - NSCoding
来做到这一点。只需使用键控存档器。 +archivedDataWithRootObject:
(NSKeyedArchiver
) 的结果是 NSData
的实例。回来的路你用NSKeyedUnarchiver
.
但是,如果您不想使用通用的 属性 列表工具对其进行编辑,那么选择 属性 列表文件格式的理由并不多。
因此,直接回答您的问题:
is this a good idea? Am I missing something here?
没关系
can I save an array of objects with NSImage and String properties into a single file?
由于 NSArray
符合 NSCoding
并且是一个 属性 列表,因此两种方法都可以开箱即用。
I know I can save an image, fairly easily, but can I bundle them up into a single document?
您是文件的所有者并且您定义了文件格式。继续吧。
Is NSCoding the way to do this?
是的。
Do I need to convert the NSImage to NSData first?
仅当您要保存 属性 列表文件时。
我有一个 class,我希望能够将其打开并导出到文件中。它不需要编辑 - 这只是一种与我的应用程序的其他用户共享部分对象 CoreData 数据库的方法,所以我认为我不需要 subclassing NSDocument
的复杂性.
class 非常基本,有两个属性 String
和一个 NSImage
的文件名,它引用应用程序沙箱中的图像。
最初,我想到了使用文档包,基本上是一个包含图像的文件夹(如果需要)和一个包含字符串和图像文件名的 plist。
现在,我倾向于创建一个 class-just-for-export-and-import,它使用 NSCoding
将图像和字符串保存到文件中。
以下是我不确定的内容:
- 这是个好主意吗?我在这里遗漏了什么吗?
- 我可以将具有
NSImage
和String
属性的对象数组保存到一个文件中吗?我知道我可以很容易地保存图像,但我可以将它们捆绑到一个文档中吗?NSCoding
是这样做的方法吗? - 我需要先将
NSImage
转换为NSData
吗? - 我的解码器如何知道文件的哪一部分是
String
,哪一部分是NSImage
?
我研究过了!有很多关于保存图像或保存 NSDocument
的信息,但我只是想为用户提供一种简单的方法来 将任意数据导出和导入 到我的或从中导出应用程序的核心数据存储。
任何一个选项都应该可以正常工作。如果您选择 NSCoding
路线,请务必使用键控存档器。
任何一个选项都可以处理一个对象数组,你只需要设计你的文件结构/处理代码来检查和处理它。
对于文件选项,图像将只是磁盘上的图像。对于编码选项,所有内容都将是磁盘上的二进制数据,但这是在编码过程中完成的(您将在此处将图像转换为数据)。
根据文件的结构,这可能是包中文件的扩展名。对于编码选项,它是键名。
您的两个选项对于用户来说实际上是相同的,并且将来可以扩展,您选择哪个取决于个人喜好。我希望编码选项更快更容易编写代码。
实施 NSCoding 协议,您可以轻松共享您描述的对象。
public required init!(coder:NSCoder)
{
self.busStopName = coder.decodeObjectForKey("busStopName") as? String
self.busStopID = coder.decodeIntegerForKey("busStopID") as Int
let lines: [String]! = coder.decodeObjectForKey("busLines") as? [String]
let photo: NSData = coder.decorDataForKey("photo") as? NSData
}
public override func encodeWithCoder(encoder: NSCoder) -> Void
{
encoder.encodeObject(self.busStopName, forKey:"busStopName")
encoder.encodeInteger(self.busStopID, forKey: "busStopID")
encoder.encodeObject(self.busLines, forKey: "busLines")
encoder.encodeDataObject(self.busStopImage, forKey: "photo")
}
为了从 NSData 创建一个 UIImage 使用这个 initializer
let image: UIImage = UIImage(data: <the nsdata decoded>)
并使用此 UIKit 函数之一从 UIImage 获取 NSData
使用 NSCoding
你可以保存每一个 class 内置支持这个协议的或者你自己添加的。 NSImage
和 – 当然 – NSString
都符合 NSCoding
。您只需为您的自定义 class、which is pretty simple:
NSCoding
支持
- (void)encodeWithCoder:(NSCoder*)coder
{
[coder encodeObject:self.stringProperty forKey:@"String Property"];
[coder encodeObject:self.imageProperty forKey:@"Image Property"];
}
- (instancetype)initWithCoder:(NSCoder*)coder
{
self = [super init]; // or `-initWithCoder:, if it is supported
if (self)
{
self.stringProperty = [coder decodeObjectForKey:@"String Property"];
self.imageProperty = [coder decodeObjectForKey:@"Image Property"];
}
return self;
}
如果您想将数据保存为属性列表文件,您只能使用属性列表classes。 NSString
is a property list, but NSImage
is not – 当然你的习惯 class 不是。因此,您必须将 NSImage
的实例和您的自定义 class 的实例转换为 NSData
的实例,因为 NSData
是一个 属性 列表。你可以用 - drum-roll - NSCoding
来做到这一点。只需使用键控存档器。 +archivedDataWithRootObject:
(NSKeyedArchiver
) 的结果是 NSData
的实例。回来的路你用NSKeyedUnarchiver
.
但是,如果您不想使用通用的 属性 列表工具对其进行编辑,那么选择 属性 列表文件格式的理由并不多。
因此,直接回答您的问题:
is this a good idea? Am I missing something here?
没关系
can I save an array of objects with NSImage and String properties into a single file?
由于 NSArray
符合 NSCoding
并且是一个 属性 列表,因此两种方法都可以开箱即用。
I know I can save an image, fairly easily, but can I bundle them up into a single document?
您是文件的所有者并且您定义了文件格式。继续吧。
Is NSCoding the way to do this?
是的。
Do I need to convert the NSImage to NSData first?
仅当您要保存 属性 列表文件时。