2

我有一个现有的模型类,我想用 Parse 进行管理,理想情况下是通过将其超类从 NSObject 更改为 PFObject。但这是一个真实世界的模型类,在设计时没有考虑 Parse,因此它提出了许多挑战。

挑战

挑战是:

  1. 这个类在 Swift 中。
  2. 此类具有存储属性和计算属性。(所以 Parse 当然应该只管理存储的属性。)
  3. 一些属性包含其他自定义模型类的实例数组
  4. 其中一些自定义类本身包含 User 对象,这些对象应由 Parse 管理。

这些事情中的每一件事似乎都需要特殊处理才能在 Parse 中正确处理,Parse 的文档对这些问题进行了简要说明。

现有模型类层次结构

举个例子,我的课是这样的:

// I’d like to change this to be a PFUser subclass.
class User : NSObject { /* an ordinary user object  */ }

// And this to be a PFObject subclass
class Tango : NSObject {
  var user:User  // Presumably, a Parse "Pointer" to a PFUser
  var opponent:Participant
  var info:NSString?
  var watchers:NSArray // an array of Participants
  var duration:NSTimeInterval? // (notice this is an optional value type, in accessible from Objc)

   // various methods
}

// a custom class which contains a User
class Participant : NSObject
{
  var status:String
  var user:User // a Pointer to a PFUser?
  // etc..
}

关键问题

所以我在这里有几个关键问题:

  1. 是否应该将所有对 User 的引用都替换为PointersUser的子类PFUser
  2. 我是否需要用像 NSDictionary 这样的普通旧 Cocoa 类型替换 Participant?或者有没有办法只为 Parse 的内部序列化目的提供与 NSDictionary 的相互转换?
  3. 是否有针对 swift-only 类型的任何规定,例如Optional<NSTimeInterval>? 或者这是另一种情况,其中有一个扩展点来提供与 Parse 可以处理的数据类型的相互转换?
  4. 如何对参与者数组进行建模?参与者中的用户对象?
  5. 考虑Tango到使用 .

我对最大查询灵活性或最大性能不感兴趣。我对可以可靠工作的最快的东西感兴趣,并且需要对现有代码进行最少的重写,这取决于现有的类层次结构。我知道这种User / Tango关系可以描述为多对多,这就是PFRelation目的,但我的印象是需要重新设计才能使用它。

换句话说,我真的希望我可以避免用设计为非规范化表的新类层次结构替换我的整个模型层,以供 Parse 使用。我有适用于当前结构的现有代码,并且我试图在不破坏任何已经存在的情况下适应 Parse。

那么这些关键问题是否适合为 Parse 改进这个类?处理它们的正确方法是什么?

4

3 回答 3

2

您绝对应该查看子类化指南。需要注意的一些事项对您的用例特别重要:

  1. 如果您将一个内置类(例如User : PFUser)子类化,那么您只需要注册该子类。所有的构造方法都返回instancetype,所以你可以在 User 上调用它们,你会得到一个实际的 User 回来。同样,对 Parse 用户类的任何查询都将返回反序列化为您的类型的结果。
  2. 如果您PFObject为自己的类型进行子类化,则还必须实现+parseClassName. 这会将您的类映射到您希望在数据浏览器中看到的名称。此名称必须在所有语言中保持一致,以确保您使用的是相同的数据。
  3. 子类库被PFObject编写为仅实现@dynamic属性。如果您使用@static它或定义该方法,那么 PFObject 将不理会它。如果您有一个同名的 ivar,则该属性不会保存到 Parse,但我们将创建一个访问器/突变器对,该对尊重PFObject我们在合并服务器数据或准备保存操作时采用的内部锁。
  4. PFObject可以处理任何 JSON 可序列化原语的属性、指向其他PFObject子类型的指针、其数组/字典和PFRelation指针。我还没有玩过 Swift,所以我不知道它会如何与可选属性交互;我假设它们是 NSNumbers 并PFObject处理 NSNumbers 以及原语(它们是自动装箱/取消装箱的)。
  5. [Bonus] 要使您的子类自包含,您可以将以下内容添加到它们的定义中: // Note: +initialize is Objective-C's only non-polymorphic function; every class // must implement this directly. +(void) initialize { [self registerSubclass]; }
于 2014-11-12T03:19:41.760 回答
1

Google Groups 上有一个类似的问题,尽管我必须说你的问题更复杂。我们知道在 Swift 中你必须将你的属性声明为 @NSManaged public var. 第二步是确定您是否可以与内置用户(PFUsers)建立关系。当您找到所有问题的答案时,请给我们您的完整解决方案。

请参阅以下链接了解第 1 步: 这里

附加信息: 我已经构建了自己的 PFObject。我发现当我调用saveInBackgroundWithBlock该块时,该块永远不会被执行,尽管该对象实际上已成功保存。我的 PFObject 仅供参考

public class PatientRemote:  PFObject, PFSubclassing {

    public override class func load() {
        self.registerSubclass()
    }
  public  class func parseClassName() -> String! {
        return "Patient"
    }

    @NSManaged public var firstname : NSString
    @NSManaged public var lastname : NSString
    @NSManaged public var birth : NSDate
    @NSManaged public var idnumber : NSString
    @NSManaged public var gender : NSString
    @NSManaged public var fileNumber : NSString
    @NSManaged public var patientPicture : NSString
    @NSManaged public var medicalAid: NSString
    @NSManaged public var option: NSString
    @NSManaged public var mainMember: NSString
    @NSManaged public var membershipNo: NSString
    @NSManaged public var dependant: NSString
    @NSManaged public var address1: NSString
    @NSManaged public var address2: NSString
    @NSManaged public var address3: NSString
    @NSManaged public var address4: NSString
    @NSManaged public var postalCode: NSString
    @NSManaged public var workNumber: NSString
    @NSManaged public var cellNumber: NSString
    @NSManaged public var localId: NSString        
}
于 2014-11-11T13:41:54.127 回答
1

我的回答:不要!使您的模型类依赖于第三方后端提供程序是没有意义的。

使模型类成为 Parse 类的子类是一个脆弱的设计。如果你想从 Parse 切换到其他东西,你将不得不再次更改你的模型类!

我正在考虑使用 Parse 作为后端,我不打算子类化。相反,我将定义一个具有基于 Parse 实现的数据访问层协议,用于从后端获取数据/向后端发送数据。该层将处理从 PFObjects 等转换为我的模型对象,反之亦然,将数据存储在 Parse 中并从中检索数据。

更新:我询问了 Parse iOS SDK 开发人员之一,他建议使用 Parse REST API 来实现这种方法,因为创建和销毁 PFObjects 是内存密集型的。他还指出,切换后端提供商的情况非常罕见——根据我的经验,这是正确的。

我想这消除了使用 Parse 的一些好处,但这是我愿意做出的权衡。它仍然允许我避免编写服务器代码。在您的情况下,这种设计可能会减少工作量,因为它将隔离更改。

于 2015-09-10T04:52:59.863 回答