2016-09-01 6 views
0

私はコードでオプションのバインディングを使用しようとしましたが、実行してデバッグするときにnilと表示されるので、間違ったメソッドを使用しているのだろうかと疑問に思っていましたか?json要素がnilでないことを保証する方法を教えてください。

Here is the code which shows me trying to parse my JSON

ここで私は私のJSONを試してみて、解析に使用コードです:

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 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 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. 
    } 
    */ 


} 
+0

ここを見ていますか? http://stackoverflow.com/a/28129484/1585677 –

+1

イメージではなく、テキストとしてコードを投稿してください。 – pedrouan

答えて

0

投稿するコードとコメントは正しくありません。

//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でない場合、プロパティを入力して設定することを確認しています。

また、上記のプロパティのいずれかがur json応答のStringでない場合、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ステートメントは、もはやゼロにならないのでもう不要です。

+0

しかし、問題は、データベースに値があるので、変数のどれもがnilではないということです。私はちょうどこれらの変数にデータベース内の値を追加し、テーブルのセルにそれらを表示したい – KONADO

+0

あなたは、デバッグし、jsonElementsを見て、すべての変数がURデータベースのように存在するかどうかを確認しますか? –

+0

これをもう一度見ると、おそらく 'price'と' distance'のjsonレスポンスは文字列ではないからです。したがってそこにはありません。今私の答えを更新します。あなたのデータベースの「価格」と「距離」は何ですか? @AdamKona –

0

オプションのバインディング条件(if let)を使用して、これらのjson値がnilでなく、正しいタイプである場合にそれらを取得しています。

しかし、そうではなく、1つ以上のjsonキーが見つからないか、間違ったタイプの値が含まれているとどうなりますか?あなたの空のPropertyModelはまだproperties配列に追加されますが、propertyTypeprice、およびdistanceは決して設定されていません(オプションであると思われます)ので、ほとんどデフォルト値はありません。

properties.addObject(property)if let条件ブロック(property.distance = distanceの直下、}の直下)内になるように上に移動する必要があります。次に、配列にnil値を持つPropertyModelを追加しません。

+0

これを実行すると、テーブルビュー(最終的な目標)にプロパティが追加されなくなりますが、実際にはプロパティは作成されません。私は上記のコードを追加して、すべてが正しく見えるようにしました。 – KONADO

+0

@AdamKona PoropertyModelオブジェクトがない場合は、jsonにエラーがあります(探しているキーが1つ以上ありません)。コードは、あなたのjsonの数字である場合、またはコードが1つ以上のキーの間違った名前にアクセスしようとしているときに、1つ以上の値を文字列にキャストしようとしています。あなたは解析しているjsonの例を投稿できますか? –

関連する問題