我正在玩弄/学习Swift和JSON atm,并且在正确围绕我的响应进行转换时遇到了问题。
因此,我想要实现的是通过Alamofire请求显示“帖子”列表。我没有显示“第一级” json项(如post-ID或“message”)的问题,但是当涉及到author数组时,我有点迷失了。
json响应以没有名称的Array的形式出现,因此第一个[
[
-{
__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 () {
}
}
和作者
class Author {
var id:String?
var userId:String?
var userName:String?
init () {
}
这里最好的方法是什么?您是否应该将返回的数组重铸为字典,然后通过.valueforkey访问它?您是否以某种方式遍历数组以获取这些东西?
显然你不能说
author.name = authorArray [3]作为字符串
最佳答案
假设您有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)
}
}