2014-10-18 4 views
2

Я играю вокруг/участвую в Swift и JSON atm, и у меня проблемы с правильным ответом.swift: листинг входящего массива json для словаря и объекта

Итак, что я пытаюсь достичь, отображается список «сообщений» по запросу Alamofire. У меня нет проблем с отображением «первого уровня» json-элементов, таких как post-ID или «сообщение», но когда дело доходит до массива автора, я немного потерян.

ответ JSON поставляется в виде массива без имени, следовательно, первый [

[ 
-{ 
__v: 1, 
_id: "54428691a728c80424166ffb", 
createDate: "2014-10-18T17:26:15.317Z", 
message: "shshshshshshshhshshs", 
-author: [ 
-{ 
_id: "54428691a728c80424166ffa", 
userId: "543270679de5893d1acea11e", 
userName: "foo" 
} 
] 
} 

Вот мой соответствующий VC:

Alamofire.request(.GET, "\(CurrentConfiguration.serverURL)/api/posts/\(CurrentConfiguration.currentUser.id)/newsfeed/\(CurrentConfiguration.currentMode)",encoding:.JSON) 
      .validate() 
      .responseJSON {(request, response, jsonData, error) in 

       let JSON = jsonData as? NSArray 
       self.loadPosts(JSON!) 
     } 

     tableView.delegate = self 

     tableView.dataSource = self 

    } 

    func loadPosts(posts:NSArray) { 
     for post in posts { 
      let id = post["_id"]! as NSString! 
      let message = post["message"]! as NSString! 

      var authorArray = post["author"]! as? [Author]! 
      println(authorArray) 

      var author:Author = Author() 
      author.userName = "TEST ME" 

      var postObj:Post = Post() 
      postObj.id = id 
      postObj.message = message 
      postObj.author = author 
      uppDatesCollection.append(postObj) 
     } 
     println(self.uppDatesCollection.count) 
     dispatch_async(dispatch_get_main_queue()) { 
      self.tableView.reloadData() 
     } 
    } 

мои модели почт

class Post { 
    var id:String! 
    var message:String! 
    var createDate: NSDate! 

    var author:Array<Author>! 

    init() { 

    } 
} 

и Author

class Author { 
     var id:String? 
     var userId:String? 
     var userName:String? 

     init() { 
    } 

Какой лучший подход здесь? Если вы переделаете возвращающийся массив как словарь, а затем получите его через .valueforkey? Вы как-то перебираете массив, чтобы получить этот материал?

Очевидно, что вы не можете сказать, author.name = authorArray [3] в качестве строки

ответ

2

Допустим, вы имели Post класс следующим образом:

class Post : Printable { 
    var identifier:String! 
    var message:String! 
    var createDate: NSDate! 
    var authors:[Author]! 

    var description: String { return "<Post; identifier = \(identifier); message = \(message); createDate = \(createDate); authors = \(authors)" } 
} 

Ваш JSON имеет только один автор в ней, но учитывая, что он представляется массивом в JSON, я предполагаю, что он также должен быть массивом в объектной модели, как показано выше. Author класса может быть определен как так:

class Author : Printable { 
    var identifier:String! 
    var userId:String! 
    var userName:String! 

    var description: String { return "<Author; identifier = \(identifier); userId = \(userId); userName = \(userName)>" } 
} 

Я не был уверен, почему вы сделали некоторые из ваших неявно развернутых опций (определенных с !) и других не (определены с ?), так что я просто сделал их всеми неявно разворачивается. Отрегулируйте в соответствии с вашими бизнес-правилами.

Кроме того, предположим, что ваш JSON выглядел так (я не совсем уверен, что сделать из - в формате JSON в вашем вопросе, так что я очистил его и добавил второй автор):

[ 
    { 
     "__v": 1, 
     "_id": "54428691a728c80424166ffb", 
     "createDate": "2014-10-18T17:26:15.317Z", 
     "message": "shshshshshshshhshshs", 
     "author": [ 
      { 
       "_id": "54428691a728c80424166ffa", 
       "userId": "543270679de5893d1acea11e", 
       "userName": "foo" 
      }, 
      { 
       "_id": "8434059834590834590834fa", 
       "userId": "345903459034594355cea11e", 
       "userName": "bar" 
      } 
     ] 
    } 
] 

Тогда процедура разбора это может выглядеть следующим образом:

func loadPosts(postsJSON: NSArray) { 
    var posts = [Post]() 

    for postDictionary in postsJSON { 
     let post = Post() 
     let createDateString = postDictionary["createDate"] as String 
     post.message = postDictionary["message"] as String 
     post.identifier = postDictionary["_id"] as String 
     post.createDate = createDateString.rfc3339Date() 

     if let authorsArray = postDictionary["author"] as NSArray? { 
      var authors = [Author]() 
      for authorDictionary in authorsArray { 
       let author = Author() 
       author.userId = authorDictionary["userId"] as String 
       author.userName = authorDictionary["userName"] as String 
       author.identifier = authorDictionary["_id"] as String 
       authors.append(author) 
      } 
      post.authors = authors 
     } 

     posts.append(post) 
    } 

    // obviously, do something with `posts` array here, either setting some class var, return it, whatever 
} 

И это мое преобразование рутина из String в NSDate:

extension String { 

    /// Get NSDate from RFC 3339/ISO 8601 string representation of the date. 
    /// 
    /// For more information, see: 
    /// 
    /// https://developer.apple.com/library/ios/qa/qa1480/_index.html 
    /// 
    /// :returns: Return date from RFC 3339 string representation 

    func rfc3339Date() -> NSDate? { 
     let formatter = NSDateFormatter() 

     formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ" 
     formatter.timeZone = NSTimeZone(forSecondsFromGMT: 0) 
     formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") 

     return formatter.dateFromString(self) 
    } 
} 
+0

Большое спасибо за ваш ответ! Есть ли более общий способ сделать это, будь то на борту или на базе библиотеки? Выполняя это с помощью итерации над массивом (который я с радостью реализовал), теоретически я мог бы в итоге получить 8x, вложенных в функции, которые кажутся мне довольно уродливыми. – longbow

+0

В этом ключе есть вещи, которые вы можете сделать, но это трудно сказать, не видя примера, демонстрирующего полное богатство этого JSON. Вероятно, вы хотите сделать баланс между полностью управляемым данными и чем-то более практичным. Возможно, дайте ему понять, и дайте нам знать, как вы идете. Если после добросовестных усилий с вашей стороны у вас все еще есть вопросы, задайте новый вопрос здесь, на s.o. – Rob