我如何能够确保 json 元素不为零?
Posted
技术标签:
【中文标题】我如何能够确保 json 元素不为零?【英文标题】:How would I be able to ensure json elements are not nil? 【发布时间】:2016-09-01 21:27:07 【问题描述】:我尝试在我的代码中使用可选绑定,但是当我执行和调试时它仍然显示为 nil,所以我想知道我是否使用了不正确的方法?
Here is the code which shows me trying to parse my JSON
这是我用来尝试解析 JSON 的代码:
import Foundation
protocol ListingModelProtocol: class
func itemsDownloaded(items: NSArray)
class ListingModel: NSObject, NSURLSessionDataDelegate
weak var delegate: ListingModelProtocol!
var data : NSMutableData = NSMutableData()
let urlPath: String = "http://booksmart.hol.es/service.php" // this will be changed to the path where service.php lives
func downloadItems()
let url: NSURL = NSURL(string: urlPath)!
var session: NSURLSession!
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
session = NSURLSession(configuration: configuration, delegate: self, delegateQueue: nil)
let task = session.dataTaskWithURL(url)
task.resume()
func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData)
self.data.appendData(data);
func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?)
if error != nil
print("Failed to download data")
else
print("Data downloaded")
self.parseJSON()
func parseJSON()
var jsonResult: NSMutableArray = NSMutableArray()
do
jsonResult = try NSJSONSerialization.JSONObjectWithData(self.data, options:NSJSONReadingOptions.AllowFragments) as! NSMutableArray
catch let error as NSError
print(error)
var jsonElement: NSDictionary = NSDictionary()
let properties: NSMutableArray = NSMutableArray()
for(var i = 0; i < jsonResult.count; i+=1)
jsonElement = jsonResult[i] as! NSDictionary
let property = PropertyModel()
//the following insures none of the JsonElement values are nil through optional binding
if let propertyType = jsonElement["Property Type"] as? String,
let price = jsonElement["Price"] as? String,
let distance = jsonElement["Distance"] as? String
property.propertyType = propertyType
property.price = price
property.distance = distance
properties.addObject(property)
dispatch_async(dispatch_get_main_queue(), () -> Void in
self.delegate.itemsDownloaded(properties)
)
这是我用来从数据库下载数据的代码:
import Foundation
class PropertyModel: NSObject
//properties
var propertyType: String?
var price: String?
var distance: String?
//empty constructor
override init()
//construct with @propertyType, @price and @distance parameters
init(propertyType: String, price: String, distance: String)
self.propertyType = propertyType
self.price = price
self.distance = distance
//prints object's current state
override var description: String
return "Property Type: \(propertyType), Price: \(price), Distance: \(distance)"
最后,这是我用来尝试将其快速放入表格单元格的代码:
import UIKit
class First_ResultsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, ListingModelProtocol
//Properties
var feedItems: NSArray = NSArray()
var selectedProperties : PropertyModel = PropertyModel()
@IBOutlet weak var PropertyListTableView: UITableView!
override func viewDidLoad()
super.viewDidLoad()
//set delegates and initialize homeModel
self.PropertyListTableView.delegate = self
self.PropertyListTableView.dataSource = self
let listingModel = ListingModel()
listingModel.delegate = self
listingModel.downloadItems()
// Do any additional setup after loading the view.
func itemsDownloaded(items: NSArray)
feedItems = items
self.PropertyListTableView.reloadData()
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
// Return the number of feed items
return feedItems.count
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
// Retrieve cell
let cellIdentifier: String = "BasicCell"
let myCell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier)!
// Get the location to be shown
let item: PropertyModel = feedItems[indexPath.row] as! PropertyModel
// Get references to labels of cell
myCell.textLabel!.text = item.propertyType
return myCell
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
*/
【问题讨论】:
你看过这里吗? ***.com/a/28129484/1585677 请将您的代码发布为文本,而不是图片。 【参考方案1】:您发布的以下代码和您的评论不正确。
//the following insures none of the JsonElement values are nil through optional binding
if let propertyType = jsonElement["Property Type"] as? String,
let price = jsonElement["Price"] as? String,
let distance = jsonElement["Distance"] as? String
以上内容并不能确保这些值不是nil
。您的 if
语句正在检查如果所有此 jsonElement 不是 nil
则它将进入并设置您的属性。
另外,如果上述任何一个属性在你的 json 响应中不是一个字符串,它就不会进入if
语句。您应该使用返回的类型对其进行检查。将 as? Double
替换为您的 json 响应返回的类型。
if let propertyType = jsonElement["Property Type"] as? String,
let price = jsonElement["Price"] as? Double,
let distance = jsonElement["Distance"] as? Double
property.propertyType = propertyType
property.price = "\(price)"
property.distance = "\(distance)"
如果您想在nil
时将其设置为空字符串,您应该使用as String ?? ""
。
//the following ensure that when the element is nil, we change it to a empty string and update our attributes
let propertyType = jsonElement["Property Type"] as? String ?? ""
let price = jsonElement["Price"] as? String ?? ""
let distance = jsonElement["Distance"] as? String? ??
property.propertyType = propertyType
property.price = price
property.distance = distance
您不再需要 if
语句,因为它不会是 nil。
【讨论】:
但是问题是数据库中有值所以没有一个变量应该是零?我只想将数据库中的值添加到这些变量中并在表格单元格中显示它们 让你调试并查看 jsonElements 看看是否所有变量都像你的数据库一样存在? 再看一遍,可能是因为price
和distance
的json响应不是字符串。因此它不存在。我现在将更新我的答案。让我知道您的数据库中的price
和distance
是什么? @AdamKona
我对表中的所有数据(VARCHAR)都使用了相同的数据类型,所以我不太清楚为什么这不起作用【参考方案2】:
如果这些 json 值不是 nil 且类型正确,则您正在使用可选绑定条件 (if let
) 来检索它们。
但是,如果不是这种情况,并且其中一个或多个 json 键丢失或包含错误类型的值,会发生什么?看起来你的空PropertyModel
仍然被添加到你的properties
数组中,但是因为propertyType
、price
和distance
从未设置过(听起来它们是可选的),它们将它们的默认值很可能为零。
您应该将properties.addObject(property)
行向上移动到if let
条件块内(直接在property.distance = distance
之下和 之上)。然后,您不会将任何具有 nil 值的 PropertyModel 添加到您的数组中。
【讨论】:
当我这样做时,它不再将属性放入表视图(这是最终目标),但实际上没有创建。我在上面添加了更多代码,以便可以正确查看所有代码 @AdamKona 如果这样做会导致没有 PoropertyModel 对象,那么要么您的 json 有错误(缺少您要查找的一个或多个键),要么您的代码正在尝试转换一个或多个当它们是 json 中的数字时,字符串的值,或者您的代码试图访问一个或多个键的错误名称。你能发布一个你正在解析的json的例子吗?以上是关于我如何能够确保 json 元素不为零?的主要内容,如果未能解决你的问题,请参考以下文章