wlm*_*sda 4 arrays xcode json nsdictionary swift
我试图在调试区域显示我的JSON信息,但我遇到了一个问题,我没有找到解决方案.
首先,让我显示我到目前为止的代码:
BBUpJSON.swift
import Foundation
class BBUpJSON {
func loadBbup(completion: ((AnyObject) -> Void)!) {
var urlString = "http://xxxdsgn.xxxhost.com/json/jnslst.json"
let session = NSURLSession.sharedSession()
let bbupUrl = NSURL(string: urlString)
var task = session.dataTaskWithURL(bbupUrl!){
(data, response, error) -> Void in
if error != nil {
println(error.localizedDescription)
} else {
var error : NSError?
var bbupData = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error: &error) as! NSArray
var jnslst = [JSONExtrct]()
for jnsextrct in bbupData{
let jnsextrct = JSONExtrct(data: jnsextrct as! NSDictionary)
jnslst.append(jnsextrct)
}
let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
dispatch_async(dispatch_get_global_queue(priority, 0)) {
dispatch_async(dispatch_get_main_queue()) {
completion(jnslst)
}
}
}
}
task.resume()
}
}
Run Code Online (Sandbox Code Playgroud)
JSONExtrct.swift
import Foundation
class JSONExtrct {
var titulo : String!
var imageUrl : String!
var imageData : NSData?
var imageUrl2 : String!
var imageData2 : NSData?
var imageUrl3 : String!
var imageData3 : NSData?
var marca : String!
var color : String!
var tipo : String!
var ref : Int!
init(data : NSDictionary) {
self.titulo = getStringFromJSON(data, key: "titulo")
let image = data["image"] as! NSDictionary
self.imageUrl = getStringFromJSON(image, key: "image")
let image2 = data["image2"] as! NSDictionary
self.imageUrl2 = getStringFromJSON(image, key: "image2")
let image3 = data["image3"] as! NSDictionary
self.imageUrl3 = getStringFromJSON(image, key: "image3")
self.marca = getStringFromJSON(data, key: "marca")
self.color = getStringFromJSON(data, key: "color")
self.tipo = getStringFromJSON(data, key: "tipo")
self.ref = data["ref"] as! Int
}
func getStringFromJSON(data: NSDictionary, key: String) ->String{
//let info : AnyObject? = data[key]
if let info = data[key] as? String {
return info
}
return ""
}
}
Run Code Online (Sandbox Code Playgroud)
ViewController.swift
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let json = BBUpJSON()
json.loadBbup(nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Run Code Online (Sandbox Code Playgroud)
因此,当我for jnsextrct in bbupData{在BBUpJSON.swift文件中运行带有断点的应用程序时,它在调试区域的左侧显示我有20个值.每次我po bbupData在调试区域的右侧输出中运行时,它只是部分地显示了我在JSON文件中的20个值中的3个值.当我completion(jnslst)在同一个swift文件的末尾添加另一个断点并按继续程序执行时,我收到以下错误:Could not cast value of type '__NSCFString' (0x10c3c2c50) to 'NSDictionary' (0x10c3c38d0).然后它将错误重定向到let image = data["image"] as! NSDictionary位于我的JSONExtrct.swift中的错误.
这是尝试提取信息的json文件的链接.
-----更新------
将JSONExtrct.swift中的字符串值修改为:
if let imageUrl = data["image"] as? String {
self.imageUrl = imageUrl
}
if let imageUrl2 = data["image2"] as? String {
self.imageUrl2 = imageUrl2
}
if let imageUrl3 = data["image3"] as? String {
self.imageUrl3 = imageUrl3
}
Run Code Online (Sandbox Code Playgroud)
并添加相同的断点以查看BBUpJSON.swift中的结果.从断点开始for jnsextrct in bbupData{,当我输入po bbupData输出区域时,它仍然显示我所拥有的20个相同的3个值(不知道是否应该显示该方式).当我继续执行程序时completion(jnslst),它不会显示上一个错误,但它在键入时显示以下输出结果po jnslst:
(lldb) po jnslst
[BonBonUp.JSONExtrct, BonBonUp.JSONExtrct, BonBonUp.JSONExtrct, BonBonUp.JSONExtrct, BonBonUp.JSONExtrct, BonBonUp.JSONExtrct, BonBonUp.JSONExtrct, BonBonUp.JSONExtrct, BonBonUp.JSONExtrct, BonBonUp.JSONExtrct, BonBonUp.JSONExtrct, BonBonUp.JSONExtrct, BonBonUp.JSONExtrct, BonBonUp.JSONExtrct, BonBonUp.JSONExtrct, BonBonUp.JSONExtrct, BonBonUp.JSONExtrct, BonBonUp.JSONExtrct, BonBonUp.JSONExtrct, BonBonUp.JSONExtrct]
Run Code Online (Sandbox Code Playgroud)
当我继续并在最后一个括号添加一个断点时,它显示以下错误:fatal error: unexpectedly found nil while unwrapping an Optional value它将错误重定向到completion(jnslst)显示Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP,subcode=0x0)
更新2
它似乎只读取一个值jnsextrct并将其返回jnslst.然后,当我在下一个屏幕截图中添加另一个断点时,它将转到下一个值.当我输入po jnslst第二个屏幕截图时,它会返回一个[BonBonUp.JSONExtrct]而不是之前的更新中的20个.
更新3
已经添加CollectionView到了Main.StoryBoard但是当我尝试将JSON信息(还没有图像)上传到每个网格时,我收到以下错误.在JnsGridController.swift下,为了从我的JSON文件接收信息,我不得不创建一个回调为的新方法didLoadJns.以下是该代码的一部分:
jns = [JsonExtrct]()
let json = JnsJson()
json.loadJns(didLoadJns)
}
func didLoadJns(jns: [JsonExtrct]){
self.jns = jns
collectionView.reloadData()
Run Code Online (Sandbox Code Playgroud)
在json.loadJns(didLoadJns),didLoadJns使用是nil之前我加入了func,但我收到以下错误方法:Cannot invoke 'loadJns' with an argument list of type '(([JsonExtrct]) -> ())'
同样在JnsJson.swift中,因为我在JnsGridController中添加了回调函数,它将接收数组,JsonExtrct而不是AnyObject因此我将函数方法更改func loadJns(completion: ((AnyObject) -> Void)!) {为func loadJns(completion: ((JsonExtrct) -> Void)!) {,现在我收到类似于JnsGridController中的错误:Cannot invoke 'dispatch_async' with an argument list of type '(dispatch_queue_t!, () -> _)'
错误很明显,您正在尝试将字符串转换为字典.在您发布密钥"图像"的json中,"image2"和"image3"是字符串.
{
"titulo": "Verox's 1002",
"image": "http://wlodsgn.x10host.com/img/jeans/vrxjns1002/veroxjeans1002_front.jpg",
"image2": "http://wlodsgn.x10host.com/img/jeans/vrxjns1002/veroxjeans1002_rightside.jpg",
"image3": "http://wlodsgn.x10host.com/img/jeans/vrxjns1002/veroxjeans1002_front_b.jpg",
"marca": "Verox",
"color": "Azul",
"tipo": "Jean",
"ref": 1002
}
Run Code Online (Sandbox Code Playgroud)
所以获取这些值的正确方法是:
if let let imageURL = data["image"] as? String {
self.imageUrl = imageURL
}
Run Code Online (Sandbox Code Playgroud)
如果您不确定要尝试转换的对象的类型,请避免使用显式展开.
UPDATE
新错误与前一个错误具有相同的性质,您隐式地展开了一个nil值,在这种情况下是闭包completion.你对闭包的定义是completion: ((AnyObject) -> Void)!对编译器说的:
不要担心,当你需要使用这个闭包它肯定会有一个非零值.
但相反,你在nil这里传递一个值:
json.loadBbup(nil)
隐式解包很有用,但是你以错误的方式使用它.如果您希望完成闭包,则nil必须以这种方式将其定义为可选:
completion: ((AnyObject) -> Void)?
并以这种方式调用它:
completion?(jnslst)
关于数组只包含3个值而不是20个的事实,有很多原因.我建议在这一行放一个断点jnslst.append(jnsextrct)并观察它的价值jnsextrct.
作为一般建议: