使用多个 Alamofire 链接请求填充 tableview

Posted

技术标签:

【中文标题】使用多个 Alamofire 链接请求填充 tableview【英文标题】:Populate tableview with multiple Alamofire chained requests 【发布时间】:2017-10-26 20:44:30 【问题描述】:

我是 Alamofire 的新手,我正在关注 ios Apps with REST APIs 这本书,我尝试解析 JSON 并填充 tableview,但问题是它在函数 loadGists 完成调用 Alamofire 链接请求之前调用 numberOfRowsInSection,所以我可以填充数组,然后相应地填充表格视图,似乎 .responseArray 函数被称为异步或在 numberOfRowsInSection 函数之后调用。

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是:

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)

对于表格视图:

    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 是:

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!
    

而 Gist 类是:

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 以及 let semaphore = DispatchSemaphore(value: 0) 以不同的方式没有运气,我需要先完成所有 Alamofire 链式请求,然后调用 numberOfRowsInSection,请帮助。

【问题讨论】:

请添加numberOfRowsInSectioncellForRowAt的方法。 您已经定义了 tableView1 但正在询问 tableView.reloadData()。而且我看不出你是否真的在运行你的完成处理程序,只是传递它。所以 reloadData 没有运行,它只是正常的 Table View 行为,而 Alamo Fire 正在执行它的工作。 我添加了 tableview 方法并使用 self.tableView1.reloadData() 进行了更正,但同样的事情以及 GitHubAPIManager.sharedInstance.getPublicGists()result in ... 块内的任何内容都不是在调用 numberOfRowsInSection 之前执行,而是在之后调用它 public func responseArray(completionHandler: Response Self 你有没有误码这个....Response) -> Self 。我可以看到现在正在调用完成处理程序(格式化没有帮助!!) 我的意思是:我仍然看不到完成处理程序被调用,但格式没有帮助 【参考方案1】:

它对我有用:

var gists = [Gist]() 
        didSet 

            self.tabelView1.reloadData()

        
    

【讨论】:

以上是关于使用多个 Alamofire 链接请求填充 tableview的主要内容,如果未能解决你的问题,请参考以下文章

如何使用来自 Alamofire 发布请求的 SwiftyJSON 填充下拉列表?

如何从 alamofire 发布请求中使用 switfyJson 填充 UItableview 中的单元格

使用 AlamoFire 获取数据以根据 UISearchBar 值填充 UITableView

对表格视图的每个单元格的 Alamofire 请求

如何使用操作查询发出多个 Alamofire 请求

我如何使用 Alamofire 取消多个请求?