2017-10-26 26 views
0

Alamofire에서 새로 왔으며 JSON을 구문 분석하고 tableview를 채우려 고 시도하는 REST API로 IOS Apps 책을 따라 가고 있지만 문제는 loadGists 함수가 끝나기 전에 numberOfRowsInSection을 호출한다는 것입니다. 배열을 채우고 그에 따라 tableview를 채울 수 있도록 Alamofire 체인 요청을 호출하면 .responseArray 함수가 비동기 호출되거나 numberOfRowsInSection 함수 후에 호출되는 것으로 보입니다. 여러 개의 Alamofire 연결 요청으로 tableview 채우기

var gists: [Gist]! 

@IBOutlet var tabelView1: UITableView! 
override func viewDidLoad() { 
    super.viewDidLoad() 



self.tabelView1.delegate = self 
     self.tabelView1.dataSource = self 
} 

override func viewDidAppear(animated: Bool) { 
    super.viewDidAppear(animated) 
    loadGists() 
    } 


func loadGists() { 
GitHubAPIManager.sharedInstance.getPublicGists() { result in 
guard result.error == nil else { 
print(result.error) 
// TODO: display error 
return 
} 
if let fetchedGists = result.value { 
self.gists = fetchedGists 
} 
DispatchQueue.main.async { 
    self.tableView1.reloadData() 
    } 

} 
    } 

어디 GitHubAPIManager 클래스가 있습니다

class GitHubAPIManager: NSObject { 


static let sharedInstance = GitHubAPIManager() 

func getPublicGists(completionHandler: (Result<[Gist]>) -> Void) { 
Alamofire.request(GistRouter.GetPublic()) 
.responseArray { (response) in 
completionHandler(response.result) 
} 
} 
} 

그리고 responseArray은 다음과 같습니다

func tableView(tableView: UITableView, 
numberOfRowsInSection section: Int) -> Int { 
return gists.count 
} 

func tableView(tableView: UITableView, cellForRowAtIndexPath 
indexPath: NSIndexPath) -> UITableViewCell { 
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) 
let gist = gists[indexPath.row] 
cell.textLabel!.text = gist.description 
cell.detailTextLabel!.text = gist.ownerLogin 

return cell 
} 

GistRouter은 다음과 같습니다 :

테이블보기 위해

public func responseArray<T: ResponseJSONObjectSerializable>(
completionHandler: Response<[T]) -> Self { 
let serializer = ResponseSerializer<[T]> { request, response, data, error in 
guard error == nil else { 
return .Failure(error!) 
} 
guard let responseData = data else { 
let failureReason = "Array could not be serialized because input data was nil." 
let error = Error.errorWithCode(.DataSerializationFailed, 
failureReason: failureReason) 
return .Failure(error) 
} 
let JSONResponseSerializer = Request.JSONResponseSerializer(options: .AllowFragments) 
let result = JSONResponseSerializer.serializeResponse(request, response, 
responseData, error) 
switch result { 
case .Success(let value): 
let json = SwiftyJSON.JSON(value) 
var objects: [T] = [] 
for (_, item) in json { 
if let object = T(json: item) { 
objects.append(object) 
} 
} 
return .Success(objects) 
case .Failure(let error): 
return .Failure(error) 
} 
} 
return response(responseSerializer: serializer, completionHandler: completionHandler) 
} 

enum GistRouter: URLRequestConvertible { 

    static let baseURLString:String = "https://api.github.com" 

    case getPublic() 




     var method: HTTPMethod { 

      switch self { 

      case .getPublic: 
       return .get 
      } 
     } 

     func asURLRequest() throws -> URLRequest { 

     let result: (path: String, parameters: [String: AnyObject]?) = { 

      switch self { 
      case .getPublic: 
       return ("/gists/public", nil) 
      } 
     }() 


     let URL = Foundation.URL(string: GistRouter.baseURLString)! 




      var UrlRequest: URLRequest? = URLRequest(url: URL.appendingPathComponent(result.path)) 

      UrlRequest = try URLEncoding.default.encode(UrlRequest!, with: result.parameters) 


     UrlRequest?.httpMethod = method.rawValue 

     return UrlRequest! 
    } 

그리고 요점 클래스는 다음과 같습니다

class Gist: ResponseJSONObjectSerializable { 


    var id: String? 
    var description: String? 
    var ownerLogin: String? 
    var ownerAvatarURL: String? 
    var url: String? 


    required init(json: SwiftyJSON.JSON) { 
     self.description = json["description"].string 
     self.id = json["id"].string 
     self.ownerLogin = json["owner"]["login"].string 
     self.ownerAvatarURL = json["owner"]["avatar_url"].string 
     self.url = json["url"].string 
    } 
    required init() { 
    } 

} 
내가 DispatchQueue.global (QoS를 : .utility) 시도

.async을 또한 세마포어 = DispatchSemaphore하자 (값 : 0) 행운과 다른 방법으로 , 나는 먼저 Alamofire 연결 요청을 모두 한 다음 numberOfRowsInSection이라고 부르도록 요청해야합니다. 도와주세요.

var gists = [Gist]() { 
     didSet { 

      self.tabelView1.reloadData() 

     } 
    } 
+0

이'numberOfRowsInSection'와'cellForRowAt'에 대한 귀하의 방법을 추가하십시오 : – Barns

+0

tableView1을 정의했지만 tableView.reloadData()를 요청하고 있습니다. 그리고 실제로 완료 처리기를 실행 중인지 확인할 수 없습니다. 그래서 reloadData가 실행되고 있지 않습니다. Alamo Fire가 그 일을하는 동안 정상적인 Table View 동작 만 실행됩니다. –

+0

tableview 메소드를 추가하고 self.tableView1.reloadData()로 수정했지만 GitHubAPIManager.sharedInstance.getPublicGists() {결과의 ...} 블록 안에있는 것과 동일한 것은 numberOfRowsInSection이 호출되기 전에 실행되지 않습니다. 대신 – bcrich

답변

0

그것은 나를 위해 일했습니다.