2017-05-15 10 views
0

'configureLabels()'라는 함수를 작성했습니다. 'getLabels()'함수는 'GET'요청을하고 레이블 텍스트로 설정된 값을 검색한다고 가정합니다. 요청은 비동기 적이므로 요청이 완료 될 때 이스케이프 클로저를 사용하여 UI를 업데이트 할 수 있다고 생각했습니다. 나는 상대적으로 코딩에 익숙하지 않아, 내가 뭘 잘못했는지 확신 할 수 없다. 나는 이것을 알아내는 데 도움이되는 사람의 도움에 정말 감사 할 것입니다.이탈 및 비동기 호출을 이스케이프 처리하는 UI를로드하는 방법은 무엇입니까?

import UIKit 

수입 SwiftyJSON이 클래스 ItemDetailViewController이

: UIViewController에가 {

@IBOutlet weak var numberOfFiberGrams: UILabel! 

var ndbnoResults = [JSON]() 
var ndbno = "" 

let requestManager = RequestManager() 

override func viewDidLoad() { 
    super.viewDidLoad() 
    // Do any additional setup after loading the view. 
    configureLabels() 
} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 


func configureLabels() { 

    requestManager.ndbnoRequest(ndbno: ndbno) { (results) in 
     let json = JSON(results) 
     let fiber = json["food"]["nutrients"][7].dictionaryValue 
     for (key, value) in fiber { 
      if key == "value" { 
       self.numberOfFiberGrams.text = "\(value.stringValue)" 
      } else { 
       self.numberOfFiberGrams.text = "Fail" 
      } 
     } 
    } 
} 

/* 
// MARK: - Navigation 

// In a storyboard-based application, you will often want to do a little preparation before navigation 
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
    // Get the new view controller using segue.destinationViewController. 
    // Pass the selected object to the new view controller. 
} 
*/ 

}

그리고 여기가

은 'configureLabels을()'이 포함 된 코드 방법 'configureLabels()'가 호출하는 함수를 포함하는 코드 :

func ndbnoRequest(ndbno: String, apiKey: String, completionHandler: @escaping (_ results: JSON?) -> Void) { 
    Alamofire.request("https://api.nal.usda.gov/ndb/V2/reports?ndbno=\(ndbno)&type=f&format=json&api_key=\(apiKey)", method: .get).validate().responseJSON { response in 
     switch response.result { 
     case .success(let value): 
      let json = JSON(value) 
      completionHandler(json) 
      print("successful ndbno request") 
     case .failure(let error): 
      completionHandler(nil) 
      print(error) 
     } 
    } 
} 
+0

무슨 일이 있었습니까? 앱이 종료됩니까? 아무 일도하지? –

+0

요청에서 검색 한 데이터로 레이블이 업데이트되지 않습니다. –

답변

0

코드는 내가 코드 당신이 completionHandlerfailure에 참여를 호출하지 않는 것입니다 함께 당신 아이디어를 준 것입니다, 그래서 당신은 응답을 얻었다 여부 등이 항상 완료 블록을 호출 할 필요가 찾을 수있는 확인에만 문제를 보이는 귀하의 completionHandler 인수의 유형은 이 아니고 failure 부분에 응답이 없으므로 [JSON] 유형입니다. 할 수있는 일은 optional으로 만들고 failure의 경우 completionHandlernil 인수로 호출하십시오.

func ndbnoRequest(ndbno: String, completionHandler: @escaping (_ results: [JSON]?) -> Void) { 
    let parameters = ["api_key": "tIgopGnvNSP7YJOQ17lGVwazeYI1TVhXNBA2Et9W", "format": "json", "ndbno": "\(ndbno)"] 
    Alamofire.request("https://api.nal.usda.gov/ndb/reports/V2", method: .get, parameters: parameters).responseJSON { response in 
     switch response.result { 
     case .success(let value): 
      let json = JSON(value) 
      let ndbnoResults = json["foods"].arrayValue 
      completionHandler(ndbnoResults) 
      print("successful ndbno request") 
     case .failure(let error): 
      completionHandler(nil) 
      print("error with ndbno request") 
     } 
    }   
} 

이제이 방법을 호출하고 완료 블록의 선택 사항을 래핑하여 응답을 받았음을 확인할 수 있습니다. UI 관련

requestManager.ndbnoRequest(ndbno: ndbno) { (results) in 
    if let result = results { 
     let json = JSON(result) 
     let fiber = json["food"]["nutrients"][7].dictionaryValue 
     for (key, value) in fiber { 
      if key == "value" { 
       self.numberOfFiberGrams.text = "\(value.stringValue)" 
      } else { 
       self.numberOfFiberGrams.text = "Fail" 
      } 
     } 
    } 
    else { 
     print("Problem to get response") 
    } 
} 
+0

안녕하세요 Nirav, 답변 해 주셔서 대단히 감사합니다. 내 코드를 제안 사항으로 업데이트했는데 레이블이 아직 업데이트되지 않습니다. IBOutlet도 확인했습니다. 어떤 이슈가 될 수있는 아이디어가 있습니까? –

+0

@BenNalle 완료 블록에서 결과를 인쇄 한 후'response'를 시도하고 있는지 확인하십시오. –

+0

응답을받지 못했으나 레이블을 수정하지 않고도 여전히로드되지 않습니다. 두 가지 문제가 있음이 밝혀졌습니다. 응답을 얻지 못하고 JSON을 잘못 구문 분석하여 SwiftyJSON을 사용하여 값을 검색 할 때 값을 검색하지 못했습니다. 도와 주셔서 정말 감사합니다. –

0

모든 것은 항상는 주 스레드에서 수행해야합니다. 이렇게 해보십시오 :

DispatchQueue.main.async { 
    let json = JSON(results) 
    let fiber = json["food"]["nutrients"][7].dictionaryValue 
    for (key, value) in fiber { 
     if key == "value" { 
      self.numberOfFiberGrams.text = "\(value.stringValue)" 
     } else { 
      self.numberOfFiberGrams.text = "Fail" 
     } 
    } 
} 

P. 나는 약 실패 콜백 Nirav 동의 - 당신도 그것을 처리해야합니다. 그리고 "ndbnoRequest"와 "ndbno"가 아닌, 더 읽기 쉽고 의미있는 이름을 함수와 변수에 부여 할 것을 강력히 권장합니다. 몇 주 후에 무슨 뜻인지 기억하지 못할 것입니다.

+0

도움 주셔서 감사합니다. 지금 일하고있다. 응답을 얻지 못하는 두 가지 문제가 있었고 JSON을 올바르게 파싱했습니다. –