2016-12-05 2 views
0

Перед лицом unrecognized selector sent to instance Ошибка при использовании NSKeyedArchiver.archivedData.NSKeyedArchiver - Непризнанный селектор отправлен на ошибку экземпляра

Я пытался хранить синтаксический анализ вывода JSON в пользовательский объект класса и хранить его в NSUserDefaults при успешном входе в систему. Я хотел использовать эти данные в других контроллерах, чтобы сделать некоторые другие вызовы POST. Но, сохраняя их в моем LoginController, я получаю эту ошибку. Может ли кто-то помочь в разрешении этого.

Мой класс:

class UserDetails : NSObject,NSCoding { 


    var token:String? 
    var agentId: Int? 
    var userId:Int? 


    //to directly get values from JSON output 

    init?(user: [String: Any]) { 

     guard let token = user["token"] as? String, 
      let agentId = user["agent_id"] as? Int, 
      let userId = user["user_id"] as? Int 
     else{ 
      return nil 
     } 


       self.token = token; 
       self.agentId = agentId; 
       self.userId = userId; 
     } 

    init(pToken:String,pAgentId:Int,pUserId:Int) 
    { 
     token = pToken; 
     agentId = pAgentId; 
     userId = pUserId; 
    } 

    //TO SAVE IN NSUSERDEFAULTS 

    required init?(coder aDecoder: NSCoder){ 
     self.token = aDecoder.decodeObject(forKey: "token") as? String 
     self.agentId = aDecoder.decodeObject(forKey: "agentId") as? Int 
     self.userId = aDecoder.decodeObject(forKey: "userId") as? Int 

     return self 
    } 

    public func encode(with aCoder: NSCoder) { 
     aCoder.encode(token,forKey:"token") 
     aCoder.encode(agentId,forKey:"agentId") 
    } 

} 

И успешной регистрации, я храню эти детали.

LoginViewController:

if let userDict = json["user"] as? [String:Any] 
         { 
          guard let userObject = UserDetails(user:userDict) else { 
           print("Failed to create user from dictionary") 
           return 
          } 
          DispatchQueue.main.async { 

           self.saveUserItemToDefault(userObject: userObject); 

           self.dismiss(animated: true, completion: nil) 
           self.performSegue(withIdentifier: "loginSuccessIdentifier", sender: userObject) 

          } 
         } 




func saveUserItemToDefault(userObject:UserDetails) -> Void { 
      let encodedToken = NSKeyedArchiver.archivedData(withRootObject: userObject.token) //error is thrown on the first archiver call 
      let encodedAgentId = NSKeyedArchiver.archivedData(withRootObject: userObject.agentId) 
      let encodedUserId = NSKeyedArchiver.archivedData(withRootObject: userObject.userId) 

let encodedArray:[NSData] = [encodedToken as NSData,encodedAgentId as NSData,encodedUserId as NSData] 

      self.prefs.set(encodedArray, forKey: "UserDetailsItem") 
      self.prefs.synchronize() 
     } 

ОШИБКА СООБЩЕНИЕ:

2016-12-05 18:08:57.917 ABCAPP[2800:183556] -[_SwiftValue encodeWithCoder:]: unrecognized selector sent to instance 0x600000079f00 
2016-12-05 18:08:57.920 ABCAPP[2800:183556] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_SwiftValue encodeWithCoder:]: unrecognized selector sent to instance 0x600000079f00' 
*** First throw call stack: 
(
    0 CoreFoundation      0x0000000104b5e34b __exceptionPreprocess + 171 
    1 libobjc.A.dylib      0x00000001045bf21e objc_exception_throw + 48 
    2 CoreFoundation      0x0000000104bcdf34 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132 
    3 CoreFoundation      0x0000000104ae3c15 ___forwarding___ + 1013 
    4 CoreFoundation      0x0000000104ae3798 _CF_forwarding_prep_0 + 120 
    5 Foundation       0x00000001040f855c _encodeObject + 1263 
    6 Foundation       0x000000010412d29a +[NSKeyedArchiver archivedDataWithRootObject:] + 156 
    7 ABCAPP      0x0000000103fa8d4b _TFC15ABCAPP19LoginViewController21saveUserItemToDefaultfT10userObjectCS_11UserDetails_T_ + 235 
    8 ABCAPP      0x0000000103face3d _TFFFC15ABCAPP19LoginViewController10checkLoginFPs9AnyObject_T_U_FTGSqV10Foundation4Data_GSqCSo11URLResponse_GSqPs5Error___T_U_FT_T_ + 77 
    9 ABCAPP      0x0000000103f9d627 _TTRXFo___XFdCb___ + 39 
    10 libdispatch.dylib     0x0000000108112980 _dispatch_call_block_and_release + 12 
    11 libdispatch.dylib     0x000000010813c0cd _dispatch_client_callout + 8 
    12 libdispatch.dylib     0x000000010811c8d6 _dispatch_main_queue_callback_4CF + 406 
    13 CoreFoundation      0x0000000104b224f9 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9 
    14 CoreFoundation      0x0000000104ae7f8d __CFRunLoopRun + 2205 
    15 CoreFoundation      0x0000000104ae7494 CFRunLoopRunSpecific + 420 
    16 GraphicsServices     0x000000010910da6f GSEventRunModal + 161 
    17 UIKit        0x0000000104f81f34 UIApplicationMain + 159 
    18 ABCAPP      0x0000000103faff2f main + 111 
    19 libdyld.dylib      0x000000010818868d start + 1 
    20 ???         0x0000000000000001 0x0 + 1 
) 
libc++abi.dylib: terminating with uncaught exception of type NSException 
+1

Что сообщение вся ошибка? Это могло бы помочь точно определить, где проблема, а не читать весь ваш код. – Larme

+0

@ Larme добавил сообщение об ошибке. Пожалуйста, смотрите. – ASN

ответ

1

Наряду с входами от JPetric и Valentin Radu Я немного изменил код и ошибка удалена.

Ниже мое решение:

class UserDetails : NSObject,NSCoding { 

     //var token:String? 
     var token:String! 

     //var agentId: Int? 
     var agentId: Int! 

     //var userId:Int? 
     var userId:Int! 


    //to directly get values from JSON output 

    init?(user: [String: Any]) { 

     guard let token = user["token"] as? String, 
      let agentId = user["agent_id"] as? Int, 
      let userId = user["user_id"] as? Int 
     else{ 
      return nil 
     } 


       self.token = token; 
       self.agentId = agentId; 
       self.userId = userId; 
     } 

    init(pToken:String,pAgentId:Int,pUserId:Int) 
    { 
     token = pToken; 
     agentId = pAgentId; 
     userId = pUserId; 
    } 

    //TO SAVE IN NSUSERDEFAULTS 

    required init?(coder aDecoder: NSCoder){ 
     self.token = aDecoder.decodeObject(forKey: "token") as? String 
     self.agentId = aDecoder.decodeObject(forKey: "agentId") as? Int 
     self.userId = aDecoder.decodeObject(forKey: "userId") as? Int 

     return self 
    } 

    public func encode(with aCoder: NSCoder) { 
     aCoder.encode(token,forKey:"token") 
     aCoder.encode(agentId,forKey:"agentId") 
    } 

} 
3

Проблема может быть вызвана тем, что вы пытаетесь архивировать и необязательным Optional не метод encodeWithCoder (отсюда сообщение об ошибке).

Попробуйте сделать это:

public func encode(with aCoder: NSCoder) { 
     if let token = token { 
      aCoder.encode(token,forKey:"token") 
     } 
     if let agentId = agentId { 
      aCoder.encode(agentId,forKey:"agentId") 
     } 
    } 
+0

привет JPetric. Я попытался изменить код на то, что вы упомянули выше. Еще одна ошибка. – ASN

+0

Как раз для моей curtesy, вы можете попытаться объявить токен и agentId как String и Int (не optionals) в объявлении класса (var token: String вместо var token: String?)? – JPetric

+0

Я попытался изменить его на то, что вы предложили (не опционально). Теперь он выдает ошибку примерно так: «Инициализатор для условной привязки должен иметь необязательный тип, а не строку» рядом с 'if let token = token {aCoder.encode (токен, forKey:" токен ")}' – ASN

1

В дополнение к тому, что @JPetric уже сказал, что может меня так, когда вы получите такого рода исключений, в общем, проблема заключается в том, что вы пытаетесь архивировать данные тип, который не представлен в Objective-C. Это может быть необязательное, быстрое перечисление, быстрое закрытие и т. Д. Добавьте контрольную точку исключения, чтобы увидеть фактический объект, который не может закодировать, а затем найти способ использования объекта Objective-C.

+0

Согласен. Добавление контрольной точки исключения является обязательным (http://stackoverflow.com/questions/17802662/exception-breakpoint-in-xcode) – JPetric

Смежные вопросы