2016-09-01 3 views
0

내 코드에서 선택적 바인딩을 사용하려고했지만 잘못된 메서드를 사용했는지 궁금해서 디버깅 및 실행시 nil로 표시됩니다. 여기 json 요소가 0이 아닌 것을 어떻게 보장 할 수 있습니까?

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이 아니라면 속성을 입력하고 설정한다는 것을 확인합니다.

또한 위 속성 중 하나라도 urson 응답의 문자열이 아니면 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

u 디버그하고 jsonElements 살펴보고 모든 변수가 UR 데이터베이스에 존재하는지 확인하십시오? –

+0

'가격'과 '거리'에 대한 json 응답이 문자열이 아니기 때문에 다시 보았을 수 있습니다. 그러므로 거기에 있지 않습니다. 지금 내 대답을 업데이트 할 것입니다. 데이터베이스에 '가격'과 '거리'가 무엇인지 알려주시겠습니까? @AdamKona –

0

선택적 바인딩 조건 (if let)을 사용하여 해당 json 값이 nil이 아니고 올바른 유형 인 경우 검색합니다.

하지만 그런 경우가 아니며 하나 이상의 json 키가 누락되었거나 잘못된 유형의 값을 포함하면 어떻게됩니까? 그것은 당신의 비어있는 PropertyModel이 여전히 properties 배열에 추가되지만, propertyType, price, 그리고 distance이 결코 설정되지 않았기 때문에 (그것들은 옵션 인 것 같이 들리지만), 그것들은 대부분 0 일 가능성이있는 디폴트 값을 가질 것입니다.

properties.addObject(property) 라인을 if let 조건 블록 (property.distance = distance 바로 아래, } 바로 아래)까지 이동해야합니다. 그런 다음 배열에 nil 값이있는 PropertyModel을 추가하지 않습니다.

+0

그렇게하면 더 이상 테이블 뷰 (궁극적 인 목표)에 속성을 넣지 않지만 실제로는 아무 것도 생성하지 않습니다.위의 코드를 추가하여 모두 제대로 볼 수 있습니다. – KONADO

+0

@AdamKona 그 결과 PoropertyModel 객체가 없으면 json에 오류 (찾고있는 키가 하나 이상 누락 됨)가 있거나 코드가 json의 숫자 일 때 하나 이상의 값을 문자열로 캐스팅하려고하거나 코드가 하나 이상의 키에 잘못된 이름에 액세스하려고 시도하고 있습니다. 파싱하는 json의 예를 게시 할 수 있습니까? –

관련 문제