2016-06-16 7 views
1

私のアプリケーションコードは、サーバーからJSONデータを取得し、それを辞書に変換し、それを使用して対応するスキーマのRealmSwiftオブジェクトを保存します。Realmオブジェクトを作成する前に値を検証する方法(RealmSwiftで)

Floatという値がモデル内でIntと宣言されたフィールドに入ったことでクラッシュしました。 RLMExceptionがスローされました。

this threadで示唆されているように、単にRLMExceptionを捕まえることはありません。

私の質問は正しいですか?もしそうなら、予期しない値が見つかったときにクラッシュを防止する正しい方法は何ですか?それらを設定しようとする前に、すべての値に対して実行できる検証メカニズムはありませんか?

+0

なぜあなたはそのFloatをIntにキャストしませんか? – tbilopavlovic

+0

この特定のエラーを修正することは、一度それについて知っていれば簡単です。しかし、Intが予期されたときにサーバーが突然文字列を送信するとどうなりますか?それが起こるとアプリがクラッシュするのはなぜですか?私はそのフィールドが何か他のものにスキップするかデフォルトにしたいと思っています。 – SuitedSloth

答えて

0

これを処理するための拡張機能が作成されました。現時点では数字と日付の検証のみを行っていますが、switchステートメントはすべてのプロパティタイプを簡単にチェックできます。

extension Object { 

    public convenience init(withDictionary rawData: [String:AnyObject]) { 

     var sanitizedData = rawData 

     let dynamicSelf = self.dynamicType 

     let schema = dynamicSelf.sharedSchema() 


     for property in schema.properties { 

      guard let value = sanitizedData[property.name] else { continue } 

      var isValid = true 

      switch property.type { 

       case .Double: 

        let val = Double(String(value)) 

        if val == nil || val!.isNaN { 
         isValid = false 
        } 

       case .Float: 

        let val = Float(String(value)) 

        if val == nil || val!.isNaN { 
         isValid = false 
        } 

       case .Int: 

        if Int(String(value)) == nil { 
         isValid = false 
        } 

       case .Date: 

        if Int64(String(value)) == nil { 

         isValid = false 

        } else { 

         sanitizedData[property.name] = NSDate(timeIntervalSince1970: value.doubleValue/1000) 

        } 

       default: 
        break 

      } 


      if !isValid { 

       log.error("Found invalid value: \(value) for property \(property.name) of \(dynamicSelf)") 

       sanitizedData.removeValueForKey(property.name) 

      } 

     } 

     self.init(value: sanitizedData) 

    } 

} 
0

あなたはすべてがJSONパラメータ

static func createFromJSONDictionary(json: JSONDictionary) throws -> MyObject { 
     guard let 
       property1 = json["property1"] as? Int, 
       property2 = json["property1"] as? String else { 
        // Throw error.... or create with default values 
        throw NSError(domain: "", code: 0, userInfo: nil) 
     } 
     // Everything is fine, create object and return it 
     let object = MyObject() 
     object.something = property1 
     return object 
    } 
+0

右。しかし、これは私が別の場所で私のスキーマを再現するように強制します。私はそれが最適ではなくエレガントであると信じています。モデル宣言は、Realmに各フィールドのタイプを通知します。なぜ、検証コードに許容可能なタイプのリストも保持する必要があるのでしょうか? 私は、https://realm.io/docs/swift/1.0.1/api/Classes/ObjectSchema.htmlを使って、これよりもさらに精巧なものを作ることができます。これにより、プロパティとタイプにアクセスできます。しかし、私は欠けているより良いワークフローがあると思います。 – SuitedSloth

3

あなたはObjectMapperのように、レルムのオブジェクトにマッピングするJSONのためのサードパーティ製のフレームワークを使用して、それがあなたのJSONを検証するfailable初期化子です使用することができますして大丈夫ですかどうかを確認するためにこれを使用することができます。

この初期化子は、オブジェクトのシリアル化の前にJSON検証に使用できます。関数内でnilを返すと、マッピングが発生しなくなります。 Mapオブジェクト内に格納されているJSONを検査して検証を行うことができます。

+0

これは有望な解決策です、ありがとう:) – SuitedSloth

関連する問題