1

プロジェクトでObjectMapper ( https://github.com/Hearst-DD/ObjectMapper ) と Realm の両方を使用しています。私のオブジェクトはすべて RLMObjects です。

たとえば、添付ファイルを含むブログ オブジェクトがあります。

dynamic var attachments = RLMArray(objectClassName: Attachment.className())

次のように始まるカスタム トランスフォーマーがあります。

func transformFromJSON(value: AnyObject?) -> RLMArray? {
            let attachments = RLMArray(objectClassName: Attachment.className())
            if let str = value as? String {

それらを RLMArray に変換する方法を理解できないようです。トランスフォーマーでは常に nil になります。

"attachments" : [
    {
      "id" : 2,
      "file_name" : "img1.jpg",
      "url" : "uploads\/img.jpg"
    },
    {
      "id" : 3,
      "file_name" : "img1.jpg",
      "url" : "uploads\/img.jpg"
    },
    {
      "id" : 4,
      "file_name" : "img1.jpg",
      "url" : "uploads\/img.jpg"
    }
  ],

コードに頭を悩ませるのは難しいと思います。また、xcode のデバッガーにはあまり助けがありません。

TL;DR トランスフォーマーが nil を受け取るか、値を RLMArray に変換する方法が間違っていると予想しています。

更新: 私が何に苦労しているかが少し明確になっていることを願っています. とにかく、デバッグのためにこれを含むようにトランスフォーマーを変更しました:

    func transformFromJSON(value: AnyObject?) -> RLMArray? {
        let attachments = RLMArray(objectClassName: Attachment.className())
        if let val:AnyObject = value {
        Debug.log("the val is this \(val)")
        Debug.log("the val is this \(val as? String)")
        Debug.log("the val is this \(val as? Attachment)")
        Debug.log("the val is this \(val as? Array<Attachment>)")
        Debug.log("the val is this \(val as? Array<String>)")
        Debug.log("the val is this \(val as? Dictionary<String, AnyObject>)")
        Debug.log("the val is this \(val as? Dictionary<String, String>)")

        let mir = reflect(value)
        Debug.log("the mirror is this \(mir)")


        }
        return attachments
    }

さらに紛らわしいのは、最初の Debug.log (単に NSLog を作成するだけ) です。以下を出力します。

 the val is this (
        {
        "file_name" = "img.jpg";
        id = 2;
        url = "uploads/img.jpg";
    },
        {
        "file_name" = "img2.jpg";
        id = 3;
        url = "uploads/img2.jpg";
    },
        {
        "file_name" = "img3.jpg";
        id = 4;
        url = "uploads/img3.jpg";
    }
)

これらのログ行が返される原因を見る限り、これはjsonでも、配列でも、辞書でもありません。

val はこの nil です。配列の場合、val はこの Optional([]) です。

更新 タプルのように見えたので、今はこれがあります:

func transformFromJSON(value: AnyObject?) -> RLMArray? {
    let attachments = RLMArray(objectClassName: Attachment.className())
        if let val:AnyObject = value {
            Debug.log("-- new obj --")

        if let arr = value as? Array<(AnyObject)> {
            for file_name in arr {
                Debug.log("fn: \(file_name)")
            }
        }

これにより、さまざまな添付ファイルを反復処理できますが、内部オブジェクトが何であるかを調べる必要があります。

更新 "AnyObject" でタプル配列を取得した後、値は __NSCFDictionary だったようです。これは、objectForKey を使用して値を取得できました

4

1 に答える 1

1

したがって、これは、子の配列を RLMObject Attachment に変換する方法の解決策のようです。私がこれを実装する方法がどれほど間違っているか、そしてこれがちょっと悪いと感じているので、より適切な解決策は何かについてのフィードバックが欲しいです:

///API のアタッチメント配列を添付ファイル付きの RLMArray に変換する Transformer ///注: Back to json は現時点では実装されていません class ApiAttachmentsTransform: TransformType { typealias Object = RLMArray typealias JSON = String

    func transformFromJSON(value: AnyObject?) -> RLMArray? {
        let attachments = RLMArray(objectClassName: Attachment.className())
        if let val:AnyObject = value {
            if let arr = value as? Array<(AnyObject)> {
                for obj in arr {
                    let attachment = Attachment()
                    if let url = obj.valueForKey("url") as? String {
                        if let id = obj.valueForKey("id") as? Int {
                            attachment.url = url
                            attachment.id = id
                            attachments.addObject(attachment)
                        }
                    }
                }
            }
        }
        return attachments
    }

    func transformToJSON(value: RLMArray?) -> String? {
        return nil
    }
}
于 2015-05-01T08:21:53.720 に答える