Невозможно сопоставить объекты JSON с Realm

ОБНОВЛЕНИЕ 2 Я пытался обработать ошибки переноса, добавив сценарий автоматической очистки, но получаю сообщение об ошибке

Ожидаемая декларация

Ошибка при добавлении скрипта в делегат приложения

ОБНОВЛЕНИЕ 1

Я пытался заменить (response: Response<Particulars, NSError>) на (response: Response<AnyObject, NSError>) и получаю эту ошибку на let realm = try! Realm()

фатальная ошибка: "попробуй!" выражение неожиданно вызвало ошибку

Фатальная ошибка

Это мой POST-запрос:

import Foundation
import Alamofire
import SwiftyJSON
import RealmSwift
import ObjectMapper
import AlamofireObjectMapper


class Login {
init(userName: String, passWord: String) {
Data.sharedInstance.userName = userName
Data.sharedInstance.passWord = passWord
}
// call this method to login
func getRequest() {
Alamofire.request(.POST, Data.todoEndpoint, parameters: ["username": Data.sharedInstance.userName!, "password": Data.sharedInstance.passWord!])
    .responseJSON { (response: Response<AnyObject, NSError>) in
        if let result = response.result.value
        {
            let value = JSON(result)
               let realm = try! Realm()
               do{
                  try realm.write{
                      realm.add(result as! Object, update: true)
                                 }
                 }
                 catch let err as NSError {
                        print("Error with realm: " + err.localizedDescription)
                    }                        
        }
        else
        {
            print("JSON data is nil.")
        }

 }
 }
 }

Старый пост

У меня есть ответ JSON, который я могу получить с помощью почтового запроса с помощью Alamofire. Теперь я хочу сопоставить свои данные с базой данных в Realm, используя AlamofireObjectMapper, но мне выдается эта ошибка

Невозможно преобразовать значение типа '(Response)->()' в ожидаемый тип аргумента 'Response->Void'

Произошла ошибка

{
 "name" : "Jonny Walker",
 "api_token" : "qwertyuiop1234567890",
 "profile_picture" : "http:default_profile_picture.jpg",
 "id" : 10,
 "email" : "[email protected]"
 "username" : "jonny"
}

Как решить эту проблему?

Это мой запрос POST

Alamofire.request(.POST, Data.todoEndpoint, parameters: ["username": Data.sharedInstance.userName!, "password": Data.sharedInstance.passWord!])
.responseJSON { (response: Response<Particulars, NSError>) in
  var errorFound = Bool()
  var errorMessage = String()
  if let result = response.result.value
  {
    let value = JSON(result)
    let realm = try! Realm()
    try! realm.write {
      for particular in result {
        realm.add(particular,update: true)
      }
    }
  }
}

Здесь я инициализирую свои объекты Realm

class Particulars: Object, Mappable {
  dynamic var name = ""
  dynamic var email = ""
  dynamic var id = 0
  dynamic var profilePicture = ""
  dynamic var username = ""
  dynamic var apiToken = ""
  override static func primaryKey() -> String? {
    return "id"
  }
  //Impl. of Mappable protocol
  required convenience init?(_ map: Map) {
    self.init()
  }
  func mapping(map: Map) {
    id    <- map["id"]
    name <- map["name"]
    email <- map["email"]
    profilePicture <- map["profile_picture"]
    username <- map["username"]
    apiToken <- map["api_token"]
  }  
}

person noobdev    schedule 17.05.2016    source источник


Ответы (3)


Что касается второй части вашего вопроса об ошибке миграции. Вы получаете сообщение об ошибке, потому что вы изменили определения своих объектов, и они больше не соответствуют тому, что хранится в базе данных Realm. Вам нужно будет аккуратно выполнить миграцию с одной версии на другую. Или, если ваши данные являются просто кэшированными данными сервера и не нуждаются в сохранении для пользователя, поскольку они могут быть воссозданы (или вы находитесь в режиме отладки/тестирования), вы можете добавить это в свой AppDelegate (в в верхней части didFinishLaunchingWithOptions..., прежде чем что-либо делать с Realm):

    // Auto wipe Realm store if schema has changed
    do {
        let _ = try Realm()
    }
    catch {
        DataController.deleteRealmFilesAtPath(Realm.Configuration.defaultConfiguration.fileURL!)
    }

А затем в свой класс DataController включите этот метод static:

static func deleteRealmFilesAtPath(fileURL: NSURL) {
    guard let path = fileURL.path else { return }
    let fileManager = NSFileManager.defaultManager()
    guard fileManager.fileExistsAtPath(path) else { return }

    do {
        try fileManager.removeItemAtPath(path)
        try fileManager.removeItemAtPath(path + ".lock")
        try fileManager.removeItemAtPath(path + ".note")
    }
    catch {
        print("Unable to delete Realm files: \(error)")
    }
}

Это сотрет старые файлы базы данных при запуске приложения, если схема изменилась. Конечно, вы также потеряете все данные, поэтому вы можете использовать это только в некоторых случаях.

person Dave Wood    schedule 20.05.2016
comment
Привет, @Dave. Кажется, я не могу добавить do {} catch {} в свой AppDelegate. Вы знаете, как я могу это исправить? Кроме того, когда вы упомянули класс DataController, вы имеете в виду класс, в котором я использую realm.write и realm.add? (см. обновленный пост) - person noobdev; 23.05.2016
comment
do/catch должен быть в порядке в AppDelegate, просто убедитесь, что он находится в вашем методе func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool. И DataController может быть любым классом, который вы используете для группировки своих функций данных, это может быть даже ваш AppDelegate, если у вас нет выделенного класса данных. Обновление: увидел ваше обновление, вам нужно переместить do/catch в метод, где у вас есть // Override... - person Dave Wood; 23.05.2016
comment
Я получаю сообщение «Не удалось преобразовать» значение типа «__NSCFDictionary» (0x10c127178) в «RealmSwift.Object» (0x10bc7f770). в моем пусть царстве = попробуй! Строка Realm(). Вы знаете, как я могу это исправить? - person noobdev; 23.05.2016
comment
Конечно, вот ссылка на мой код codeshare.io/xkjul (строки 66–81) и код, где я сопоставил данные codeshare.io/1oQw9 - person noobdev; 23.05.2016
comment
Хорошо, сначала удалите ! из try (строка 69). Он находится внутри замыкания do, поэтому в случае сбоя его обработает замыкание catch. Далее, избегайте использования ! везде. Старайтесь никогда не использовать его. Преобразуйте свой код, чтобы проверить типы, например, as? Object. Проверьте, например, перед подачей на realm.add. Похоже, что user на самом деле Dictionary, а не Object, отсюда и ваш сбой. - person Dave Wood; 23.05.2016

Как говорится в сообщении об ошибке, ваш блок завершения должен принимать Response<AnyObject, NSError>, а не Response<Particulars, NSError>.

person Thomas Goyne    schedule 17.05.2016
comment
если бы я заменил Details на AnyObject, как бы я смог связать класс Particulars с моим POST-запросом? - person noobdev; 18.05.2016

Чтобы ответить на ваше обновление, когда вы вносите изменения в Realm, вам нужно будет удалить приложение и установить его заново. Это должно избавиться от вашей ошибки миграции.

person Mackarous    schedule 20.05.2016