【问题标题】:Bluetooth Transfer for Core Data Entities核心数据实体的蓝牙传输
【发布时间】:2010-01-21 01:07:21
【问题描述】:

我将如何使用蓝牙传输具有对应关系的核心数据实体?我设置了三个具有反向关系的核心数据实体,一切正常,但我需要根据上下文将它们转移到另一部 iPhone,因为它不在另一部 iPhone 上的核心数据实体集中的相应表中。我知道如何通过蓝牙传输简单的东西,例如字符串和整数,但这是一个全新的水平,我大约 4 个月前才开始为 iPhone 编程。感谢各位专家的帮助!

编辑:

谢谢,但由于某种原因,我不断收到此错误!我该怎么办?

2010-02-12 21:24:14.907 PitScout[92918:207] Failed to call designated initializer on NSManagedObject class 'Team' 
2010-02-12 21:24:14.907 PitScout[92918:207] *** -[Team setTeamNumber:]: unrecognized selector sent to instance 0x112b630
2010-02-12 21:24:14.908 PitScout[92918:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[Team setTeamNumber:]: unrecognized selector sent to instance 0x112b630'

谢谢。

【问题讨论】:

    标签: iphone cocoa cocoa-touch core-data bluetooth


    【解决方案1】:

    您需要以某种方式序列化您的对象以进行传输,然后重新插入到另一端的上下文中。我建议查看NSCoding 协议和示例,这些协议将允许您使用NSKeyedArchiverNSKeyedUnarchiver 将您的对象序列化为NSData 以进行传输(或在必要时将base64 编码为NSString)。

    首先确保你的模型对象实现了 NSCoding:

    @interface MyObject :  NSManagedObject <NSCoding>
    

    然后在你的模型对象中实现以下方法来处理对象的编码和解码:

    -(id)initWithCoder:(NSCoder*)coder
    {
        if (self = [self init])
        {
            self.myProperty = [coder decodeObjectForKey:@"myProperty"];
        }
    
        return self;
    }
    
    -(void)encodeWithCoder:(NSCoder*)coder
    {
        [coder encodeObject:self.message forKey:@"myProperty"];
    }
    

    使用NSKeyedArchiver 将您的对象序列化为NSData

    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:myObject];
    

    使用 NSKeyedUnarchiver 反序列化:

    MyObject *myObject = (MyObject *)[NSKeyedUnarchiver unarchiveObjectWithData:myData];
    

    如果需要字符串,则必须对 NSData 进行 base64 编码和解码,有关详细信息,请参阅此帖子:How do I do base64 encoding on iphone-sdk?

    【讨论】:

    • 它们序列化为数据,而不是字符串。将字符串视为纯二进制数据是一个非常常见的错误,会导致很多混淆。
    • 啊,是的,我的错误,如果字符串是必需的,那么结果数据可能会被 base64 编码。我已经更正了我的答案。
    • 我该怎么做呢?
    • 哇。太感谢了!虽然我仍然不了解 KeyedArchiver 的完整用法,但我想我可以通过阅读 Apple 的 Dev 资料了解一下。谢谢格雷格!
    • 您不能序列化 NSManagedObject 实例,因为它们直接与创建它们的 NSManagedObjectContext 相关联。它们不会正确反序列化。
    【解决方案2】:

    尝试序列化 NSManagedObject 实例将会失败,因为它们直接绑定到它们来自的 NSManagedObjectContext

    您需要将它们转换为另一种数据结构,然后传输它们。 JSON 和 XML 都可以很好地解决这个问题,因为您可以使用 KVC 将数据从 NSManagedObject 中取出并放入 NSDictionary 中,然后可以轻松地将其转换为中间格式。

    一旦您将它们设为中间格式并通过网络发送,您就可以轻松地将它们重新构建到目标 NSManagedObjectContext 中,而不会出现问题。

    【讨论】:

      【解决方案3】:

      这可能是过度杀戮,但尚未失败的方法是 SLIP,RFC 1055 1988 版本。多年来,我一直使用它将数据块映射到 7 或 8 位 ASCII 流,以便在我遇到的每种媒体上传输。然后使用它的反向或一些修改将流转换回另一端所需的配置。 C 中的代码示例在 RFC 中。我总是使用 Phil Karn 的建议,为数据包的开头和结尾使用相同的字符。

      这样只需要一个例程来处理流。它会吞噬字符,直到遇到 SOP/EOP。选择此选项是为了处理无线电链路输入端在空闲等待数据时可能累积的噪声。菲尔在其他著作中提到了这一点。

      我通常使用\x0D 或\x0A 作为调试工具运行的系统使用的回车符,并使用流行的反斜杠“\”作为转义字符。不时地使用另一个控制代码或使用不同的控制字符值来减小数据包大小是很方便的。使用该系统允许终端程序添加 SLIP 代码并进行一些修改,以用作监视器和手动将数据包输入流的工具。

      如果数据包中的第一个字符指示另一端的选项,我总是发现我有足够的选项。当然,必须提供某种形式的错误检查和/或错误恢复以及重新传输 MUNGED 数据包的能力。对于通过高度可靠的链路发送的小数据包,一个简单的校验和可能会执行,或者在使用三个矿化火山作为天线站点的情况下,传输距离比一个距离要远一些的情况下,高度 redubpndantr Fowarad 纠错算法就在家里。

      SLIP 具有足够的通用性,可以从 16 位 Motorola 68HC11 获取数据并在 32 位 Intel 系统上重建它,前提是程序员反转 endness 并处理 16 位和 32 位数据之间的偏移。

      戈登

      戈登·库格 斯蒂尔沃特,好吧

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-11-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-27
        • 1970-01-01
        • 1970-01-01
        • 2013-03-02
        相关资源
        最近更新 更多