使用String& amp导出类NSImage属性到文件

时间:2016-06-27 06:36:22

标签: swift macos appkit nscoding

我有一个我希望能够打开并导出到文件的课程。它不需要编辑 - 这只是一种与我的应用程序的其他用户共享部分对象CoreData数据库的方法,所以我不认为我需要子类化NSDocument的复杂性。 / p>

该类非常基础,有两个属性StringNSImage的文件名,用于引用应用程序沙箱中的图像。

最初,我想过使用Document Bundle,基本上是带有图像的文件夹(如果需要)和带有字符串和图像文件名的plist。 现在,我倾向于创建一个只用于导出和导入的类,使用NSCoding将图像和字符串保存到文件中。

这是我不确定的事情:

  • 这是一个好主意吗?我在这里错过了什么吗?
  • 我可以将具有NSImageString属性的对象数组保存到单个文件中吗?我知道我可以相当容易地保存图像,但是我可以将它们捆绑到一个文档中吗? NSCoding是这样做的吗?
  • 我是否需要先将NSImage转换为NSData
  • 我的解码器如何知道文件的哪一部分是String,哪部分是NSImage

我做了我的研究!有关保存图像或保存NSDocument的大量信息,但我只想要一种简单的方法让用户导出和导入任意数据进出,我的应用程序的核心数据存储。

3 个答案:

答案 0 :(得分:2)

使用order.pl 0 4 5 6 2 3 1,您可以保存每个内置支持此协议的类,或者添加它。 NSCoding和 - 当然 - NSImage都符合NSString。您只需向自定义类添加NSCoding支持which is pretty simple

NSCoding

如果要将数据保存为属性列表文件,则只能使用属性列表类。 NSString is a property list, but NSImage is not - 当然,你的自定义课程不是。因此,您必须将- (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; } 和自定义类的实例转换为NSImage的实例,因为NSData是属性列表。你可以用 - 鼓 - NSData来做到这一点。只需使用键控归档器即可。 NSCoding+archivedDataWithRootObject:)的结果是NSKeyedArchiver的一个实例。回过头来使用NSData

但是,如果您不想使用通用属性列表工具编辑它,则没有理由选择属性列表的文件格式。

所以,直接回答你的问题:

  

这是一个好主意吗?我在这里错过了什么吗?

没关系

  

我可以将具有NSImage和String属性的对象数组保存到单个文件中吗?

由于NSKeyedUnarchiver符合NSArray并且是属性列表,因此这两种方法都可以直接使用。

  

我知道我可以相当容易地保存图像,但是我可以将它们捆绑到一个文档中吗?

您是文件的所有者,您可以定义文件格式。继续吧。

  

NSCoding是否可以这样做?

  

我是否需要先将NSImage转换为NSData?

仅当您要保存属性列表文件时。

答案 1 :(得分:1)

任一选项都应该正常工作。如果你走NSCoding路线,请务必使用带键的归档器。

任何一个选项都可以处理一组对象,你只需要设计你的文件结构/处理代码来检查和处理它。

对于文件选项,图像将只是磁盘上的图像。对于编码选项,所有内容都将是磁盘上的二进制数据,但这些都是在编码过程中完成的(将图像转换为数据)。

基于文件的结构,可能是包中文件的扩展名。对于编码选项,它是关键名称。

您的两个选项对用户来说实际上是相同的,并且将来可以扩展,无论您选择哪个都取决于个人偏好。我希望编码选项更快更容易编写代码。

答案 2 :(得分:1)

实施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>)

要从UIImage获取NSData,请使用其中一个UIKit函数

UIImageJPEGRepresentation(::) UIImagePNGRepresentation(_:)