标签: nscoder

NSCoder - 使用多级嵌套数组编码数组

我有一个mainObjectArray(NSMutableArray),它填充了自定义类的实例.每个实例本身都是一个数组,每个数组中的对象是NSDates,NSStrings,BOOL以及包含类似对象的更多数组.

我无法确定的是,是否有可能在内部

- (void)encodeWithCoder:(NSCoder *)encoder 
Run Code Online (Sandbox Code Playgroud)

方法,只是说这样的话:

[encoder encodeWithObject:mainObjectArray];
Run Code Online (Sandbox Code Playgroud)

或者必须分别编码每个实例中的每个对象?这会有点痛苦......

非常感谢您的帮助.

xcode objective-c saving-data nscoder ios

3
推荐指数
1
解决办法
6111
查看次数

如何保存/存档包含自定义对象的NSMutableArray?

我有一个NSMutableArray*recordsArray,键是NSStrings,值是一个自定义对象:

@interface DictRecord : NSObject{
}
@property (nonatomic, retain) NSString* word; 
@property (nonatomic, retain)  NSString  *wordStatus;
Run Code Online (Sandbox Code Playgroud)

Cocoa:如何保存/存档包含自定义对象的NSMutableArray

我想保存NSMutable数组,最好是非二进制(稍微可读)格式.

我已阅读文档并已将编码方法添加到DictRecord:

- (void) encodeWithCoder: (NSCoder *)coder
{
    [coder encodeObject: _word forKey:@"word" ];
    [coder encodeObject: _wordStatus forKey:@"wordStatus" ];
}
- (id) initWithCoder: (NSCoder *) coder
{
    self = [super init];
    if (self) {
        self.word = [coder decodeObjectForKey:@"word"];
        self.wordStatus = [coder decodeObjectForKey:@"wordStatus"];
}
Run Code Online (Sandbox Code Playgroud)

然后我尝试保存使用:

[recordsArray writeToFile:filePath atomically:YES];
Run Code Online (Sandbox Code Playgroud)

文件已保存,但我可以看到它是空的.

任何人都可以告诉我我省略了哪些步骤,或者我是否以错误的方式解决了这个问题.

谢谢

cocoa nsmutablearray nscoder

2
推荐指数
1
解决办法
1569
查看次数

未调用所需的init?(coder aDecoder:NSCoder)

我编写了自己的Button,Textfield,...类。在“自定义类”的情节提要中,将类设置为UIElement。这很好。

现在,我需要以编程方式添加的工具栏。当我在ViewController中添加工具栏时,一切都很好。但是我想像这样创建自己的工具栏类。

class MyOwnToolbar : UIToolbar {


required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    //never called
    self.backgroundColor = UIColor.redColor()
    self.tintColor = UIColor.greenColor()
    self.barTintColor = UIColor.blueColor()
}

override init(frame: CGRect) {
   //error: super.init isn'T called on all paths before returning from initiliazer
}
Run Code Online (Sandbox Code Playgroud)

在我的ViewController中,我尝试这样调用:

fromToolBar = MyOwnToolBar() //call nothing?
fromToolBar = MyOwnToolBar(frame: CGRectMake(0,0,0,0)) //doesn't work because init(frame: CGRECT) doesnt work
Run Code Online (Sandbox Code Playgroud)

我的ViewController中的旧代码有效:

    self.untilToolBar = UIToolbar(frame: CGRectMake(0,0,0,0))
    untilToolBar?.backgroundColor = redColor
    untilToolBar?.tintColor = greenColor
    untilToolBar?.barTintColor = blueColor
Run Code Online (Sandbox Code Playgroud)

因此,我可以使用有效的解决方案,但我想理解为什么我的代码无法正常工作。因此,也许有人有解决方案或良好的联系。

init nscoder swift

2
推荐指数
1
解决办法
5006
查看次数

使用Swift 3中的NSCoder编码/解码日期?

我正在编写一个基于Apple的FoodTracker教程的计划器应用程序,它可以存储多个字符串,一个日期和每个分配的UIImage.我遇到编码/解码日期的问题.我不确定它是什么因为控制台输出随着每次轻微的修改而改变,但从我所知道的,我的代码将Date保存为nil,然后当它试图加载该Date时,它意外地发现nil和崩溃.因为我对Swift相对较新,而Swift 3是一个令人头疼的问题,我几乎不知道问题究竟在哪里.这是我认为应该工作的代码:

class Assignment: NSObject, NSCoding {

//MARK: Properties

var name: String
var className: String
var assignmentDescription: String
var materials: String
var dueDate: Date?
var assignmentImage: UIImage?

//MARK: Archiving Paths

static let DocumentsDirectory = FileManager().urls(for: .documentDirectory, in: .userDomainMask).first!
static let ArchiveURL = DocumentsDirectory.appendingPathComponent("assignments")

//MARK: Types

struct PropertyKey {
    static let nameKey = "name"
    static let classNameKey = "className"
    static let assignmentDescriptionKey = "assignmentDescription"
    static let materialsKey = "materials"
    static let dueDateKey = "dueDate"
    static let assignmentImageKey = "assignmentImage" …
Run Code Online (Sandbox Code Playgroud)

nscoder ios swift

2
推荐指数
1
解决办法
6794
查看次数

NSCoder decodeDouble可选值

decodeDoubleNSCoder返回一个非可选值,但我想,以确定一个值是否是零它编码之前.

这是我的情景:

var optionalDouble: Double? = nil

func encode(with aCoder: NSCoder) {
    if let optionalDouble {
        aCoder.encode(optionalDouble, forKey: "myOptionalDouble")
    }
}

convenience required init?(coder aDecoder: NSCoder) {
    optionalDouble = aDecoder.decodeDouble(forKey: "myOptionalDouble") 
    // here optionalDouble is never nil anymore
}
Run Code Online (Sandbox Code Playgroud)

因此0,如果从未设置值,则解码double会返回,因此我似乎无法确定值是实际0还是nil在编码之前

有没有办法在编码之前检查双精度是否为零?

nscoding nscoder ios swift

2
推荐指数
1
解决办法
782
查看次数

Swift使用编码器超越app close保存viewcontroller状态

我正在使用Xcode 8和swift 2.3

我想将整个视图控制器保存到文件并恢复状态,即使应用程序关闭后也是如此.我到处搜索,发现我们需要使用编码器.但所有只是节目保存对象.但在这里我需要保存整个ViewContoller和子视图.

ViewCotroller将有三个按钮

  • 添加文字
  • 添加图片:用户可以添加任意数量的textViews和图像.所以我还需要保存所有信息.
  • 添加ViewController:用户可能拥有此viewController的数组,需要全部保存.

问题1)

可以保存self.view并自动保存所有子视图吗?

问题2)

我只需要使用就可以在没有编码器的情况下初始化

let nameVccVar = nameVcc()
Run Code Online (Sandbox Code Playgroud)

let nameVccVar = nameVcc(coder: CodeVar)
Run Code Online (Sandbox Code Playgroud)

问题3)

如何使用NSKeyedUnarchiver将所有这些编码数据保存到文件并检索回来?

请帮助我或给我提示使所有这些工作

class nameVcc: UIViewController
{
    var nameIntVar = 0
    var nameStringVar = "Save this"
    var nameImageVar = UIImage()

    override func viewDidLoad()
    {
        super.viewDidLoad()
    }

    required init?(coder NkdPsgVar: NSCoder)
    {
        super.init(coder: NkdPsgVar)
    }

    override func encodeWithCoder(DkdPsgVar: NSCoder)
    {

    }

    func addTextViewBtnClick()
    {
        let viewVar = UIView()

        // Set many values for view 

        self.view.addSubview(viewVar)
    }

    func addImageViewBtnClick()
    { …
Run Code Online (Sandbox Code Playgroud)

uiviewcontroller nscoder ios swift

2
推荐指数
1
解决办法
1497
查看次数

NSKeyedUnarchiver 数据格式错误

我正在使用 ARKit 和 GameKitMatches,所以我不能使用 Codable (afaik),因为MCPeerID它也是ARWorldMap不可编码的,首先要解决这个问题。

所以我使用 NSCoding 和 NSSecureCoding 但由于某种原因我总是发现错误:

The data couldn’t be read because it isn’t in the correct format.

...即使我真的只是创建了它。我也尝试使用,NSKeyedUnarchiver.unarchivedObject(ofClasses: classes但这在我的初始化中抛出了一个意外的零。

这是我制作的一个显示问题的游乐场:

class CodingData: NSObject, NSCoding, NSSecureCoding {
    static var supportsSecureCoding = true
    var dic: [String: Int]!
    var i: Int!

    func encode(with coder: NSCoder) {
        coder.encode(i, forKey: "i")
        coder.encode(dic, forKey: "dic")
    }

    required convenience init?(coder: NSCoder) {
        let anInt = coder.decodeObject(forKey: "i") as! Int
        let anDic = coder.decodeObject(forKey: "dic") as! …
Run Code Online (Sandbox Code Playgroud)

nscoding nskeyedarchiver nscoder nskeyedunarchiver swift

2
推荐指数
1
解决办法
472
查看次数

从NSCoder获取所需的init属性(编码器aDecoder:NSCoder)

我正在Swift中实现一个Circle类(子类UIView),radius它根据传入的帧在其初始化器中设置它,init(frame: CGRect)如下所示:

override init(frame: CGRect)
{
    radius = frame.width/2.0
    super.init(frame: frame)
}
Run Code Online (Sandbox Code Playgroud)

我还想确保从Interface Builder实例化圆圈的情况,所以我还实现了'必需的init(编码器aDecoder:NSCoder)`(我无论如何都被Xcode强制做了).

如何检索frame以某种方式包含在其中的视图的属性aDecoder.我想要实现的基本上是这样的:

required init(coder aDecoder: NSCoder)
{
   var theFrame = aDecoder.someHowRetrieveTheFramePropertyOfTheView // how can I achieve this?
   radius = theFrame.width/2.0
   super.init(coder: aDecoder)
}
Run Code Online (Sandbox Code Playgroud)

objective-c drawrect nscoder ios swift

1
推荐指数
1
解决办法
3525
查看次数

导入为框架后,NSKeyedUnarchiver decodeObjectForKey崩溃

MyClass进入框架之前,我可以将实例保存MyClass到Core Data中.

这是实施MyClass:

open class MyClass: NSObject, NSCoding {
  required public init?(coder aDecoder: NSCoder) {
        super.init()
        stuffs = aDecoder.decodeObject(forKey: "stuff") as? [Stuff] ?? []
    }

    open func encode(with aCoder: NSCoder) {
        aCoder.encode(stuffs, forKey: "stuffs")
    }
}
Run Code Online (Sandbox Code Playgroud)

MyClass使用CocoaPods进入框架后,我开始遇到这些崩溃:

CoreData: error: exception handling request: <NSSQLFetchRequestContext: 0x1c019d4d0> , *** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (MyClass) for key (NS.objects); the class may be defined in source code or a library that is not linked …
Run Code Online (Sandbox Code Playgroud)

core-data nscoding nscoder ios cocoapods

1
推荐指数
1
解决办法
699
查看次数

编码NSAttributedString会引发错误

基于对此问题的接受答案,我编写了以下代码:

NSData* somedata;
somedata=[NSKeyedArchiver archivedDataWithRootObject:ts];
Run Code Online (Sandbox Code Playgroud)

其中ts是一个NSAttributedString,它填充了一些文本和一些属性(在本例中为颜色).

当我执行此代码时,我收到此错误:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFType encodeWithCoder:]: unrecognized selector sent to instance 0x6eb5b90'
Run Code Online (Sandbox Code Playgroud)

我是NSCoder竞技场的新手,但上述问题的答案使我觉得这就是我所要做的.是吗?我错过了什么?


编辑:

在这种情况下,无法识别的选择器被发送到NSAttributedString中的颜色属性.当我像这样初始化字符串时:

NSAttributedString *ts = [[NSAttributedString alloc] initWithString:text attributes:self.currentAttributeDictionary];
Run Code Online (Sandbox Code Playgroud)

字典就像这样构建:

self.currentAttributeDictionary=[NSDictionary dictionaryWithObjectsAndKeys:
                                 [self.currentColor CGColor],(NSString*)kCTForegroundColorAttributeName,
                                 nil];
Run Code Online (Sandbox Code Playgroud)

字典的NSLog产生了这个:

New dictionary is: {
CTForegroundColor = "<CGColor 0x6eb5b90> [<CGColorSpace 0x6e968c0> (kCGColorSpaceDeviceRGB)] ( 1 1 0 1 )";}
Run Code Online (Sandbox Code Playgroud)

上面的CGColor的地址与错误消息中的地址匹配.

objective-c nsattributedstring nskeyedarchiver nscoder

0
推荐指数
1
解决办法
3014
查看次数

通过NSStream发送时,数据会被截断

好的,所以我整天都在这个bug,我想我已经把它缩小到了根本问题.

背景:

我正在开发一个应用程序,它要求我编写自己的版本,NSNetServiceNSNetServiceBrowser允许在iOS 5中通过蓝牙使用Bonjour.这是一次伟大的冒险,因为在我开始这个项目之前我对网络编程一无所知.我从各种示例项目和经典的Unix网络编程教科书中学到了很多东西.我的实现主要基于Apple的DNSSDObjects示例项目.我已经添加了代码,以便在服务解决后实际建立设备之间的连接.一个NSInputStream和一个NSOutputStream是通过CFStreamCreatePairWithSocketToHost( ... ).

问题:

我试图通过此连接发送一些数据.数据由一个整数,一些NSStrings和一个NSData存档的对象组成NSKeyedArchiver.大小NSData约为150kb,因此整个消息的大小约为160kb.通过连接发送数据后,当我尝试取消归档时,我收到以下异常...

Terminating app due to uncaught exception 'NSInvalidArgumentException', 
reason: '*** -[NSKeyedUnarchiver initForReadingWithData:]: incomprehensible archive 
Run Code Online (Sandbox Code Playgroud)

经过进一步探索后,我注意到收到的数据只有2kb左右.消息被截断,从而使归档"难以理解".

潜在相关的代码:

将数据发送到所有连接设备的方法

- (void) sendMessageToPeers:(MyMessage *)msg
{
  NSEnumerator *e = [self.peers objectEnumerator];

  //MyMessage conforms to NSCoding, messageAsData getter calls encodeWithCoder:
  NSData *data = msg.messageAsData; 

  Peer *peer;
  while (peer = [e nextObject]) {
    if (![peer sendData:data]) { …
Run Code Online (Sandbox Code Playgroud)

network-programming objective-c nsstream nscoder ios5

0
推荐指数
1
解决办法
2189
查看次数