Ios 在Alamofire中等待后台请求完成,并加载阵列,然后继续swift

Ios 在Alamofire中等待后台请求完成,并加载阵列,然后继续swift,ios,swift,alamofire,Ios,Swift,Alamofire,我知道这里还有一个类似的问题,但没有人明确回答,也没有被接受的答案。我有一个loadDetail方法,它使用UIBackgroundFetchResult获取completionHandler。当我选择一个单元格以从数组中加载该单元格的详细数据时,将调用此方法。当调用此方法时,我希望从中调用的方法等到detailResults数组被填充后再继续。我该怎么做?我做错了什么 func loadDetail(urlPath: String, completionHandler: ((UIBackgro

我知道这里还有一个类似的问题,但没有人明确回答,也没有被接受的答案。我有一个loadDetail方法,它使用UIBackgroundFetchResult获取completionHandler。当我选择一个单元格以从数组中加载该单元格的详细数据时,将调用此方法。当调用此方法时,我希望从中调用的方法等到detailResults数组被填充后再继续。我该怎么做?我做错了什么

func loadDetail(urlPath: String, completionHandler: ((UIBackgroundFetchResult)     -> Void)!){
    Alamofire.request(.GET, urlPath)
        .responseJSON { _, _, result in
            switch result {
            case .Success(let data):
                let jsonObj = JSON(data)
                if let data = jsonObj["results"].arrayValue as [JSON]? {
                    //array is filled in the line below
                    self.detailResults = data
                    self.collectionView.reloadData()
                }
            case .Failure(_, let error):
                print("Request failed with error: \(error)")
            }
    }
    completionHandler(UIBackgroundFetchResult.NewData)
    print("Background Fetch Complete")
}
这里是调用loadDetail的collectionView方法,您可以看到调用它的地方的注释,该注释与我希望它执行的操作有关

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
    let data = results?[indexPath.row]
    let detailData: JSON
    var testString: String = ""
    let vc: DetailBrowseViewController = self.storyboard?.instantiateViewControllerWithIdentifier("DetailBrowseViewController") as! DetailBrowseViewController

    if let titleString = data?["title"] {
        vc.titleString = titleString.stringValue
        testString = titleString.stringValue
        testString = testString.stringByReplacingOccurrencesOfString(" ", withString: "-")
        testString = testString.lowercaseString
        reusableUrl.replaceRange(Range<String.Index>(start: reusableUrl.startIndex.advancedBy(146), end: reusableUrl.startIndex.advancedBy(146)), with: testString)

        self.loadDetail(reusableUrl, completionHandler:{(UIBackgroundFetchResult) -> Void in
            //I want this collectionView method to somehow pause and wait until the detailResults array is filled and then continue
            print("success")
        })
    }

    detailData = (detailResults?[indexPath.row])!

    if let priceString = detailResults?[indexPath.row]["price"] {
        print(detailData)
        vc.priceString = priceString.stringValue
    }
    self.navigationController?.pushViewController(vc, animated: true)
}
func collectionView(collectionView:UICollectionView,didSelectItemAtIndexPath indepath:nsindepath){
让数据=结果?[indexPath.row]
让我们看看detailData:JSON
var testString:String=“”
让vc:DetailBrowseViewController=self.storyboard?.instanceeviewcontrollerwhiteIdentifier(“DetailBrowseViewController”)作为!DetailBrowseViewController
如果让titleString=data?[“title”]{
vc.titleString=titleString.stringValue
testString=titleString.stringValue
testString=testString.StringByReplacingOfString(“,带字符串:“-”)的发生率
testString=testString.lowercaseString
replaceRange(范围(开始:reusableUrl.startIndex.advancedBy(146),结束:reusableUrl.startIndex.advancedBy(146)),带:testString)
loadDetail(reusableUrl,completionHandler:{(UIBackgroundFetchResult)->中的Void
//我希望此collectionView方法以某种方式暂停并等待detailResults数组被填充,然后继续
打印(“成功”)
})
}
detailData=(detailResults?[indexPath.row])!
如果让priceString=detailResults?[indexPath.row][“price”]{
打印(详细数据)
vc.priceString=priceString.stringValue
}
self.navigationController?.pushViewController(vc,动画:true)
}

问题是,loadDetail方法直接通过而不等待,导致在collectionView方法中调用时数组为零。

据我所知,当
self.detailResults
由响应中的JSON数据填充时,需要调用
completionHandler

我将试图找出我们的主要想法: -仅在成功解析数据时调用competitionHandler -将必要的代码(应等待响应)移动到已加载数据的位置

首先,您需要将
completionHandler
调用移动到.Success案例块的末尾。我认为,如果反应失败,你不需要前进

因此,结果将是:

func loadDetail(urlPath: String, completionHandler: ((UIBackgroundFetchResult)     -> Void)!){
    Alamofire.request(.GET, urlPath)
        .responseJSON { _, _, result in
            switch result {
            case .Success(let data):
                let jsonObj = JSON(data)
                if let data = jsonObj["results"].arrayValue as [JSON]? {
                    //array is filled in the line below
                    self.detailResults = data
                    self.collectionView.reloadData()
                    completionHandler(UIBackgroundFetchResult.NewData)
                }
            case .Failure(_, let error):
                print("Request failed with error: \(error)")
            }
    }

    print("Background Fetch Complete")
}
然后您需要将相关代码(应该等待响应)移动到
completionHandler
,如下所示:

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
    let data = results?[indexPath.row]
    let detailData: JSON
    var testString: String = ""
    let vc: DetailBrowseViewController = self.storyboard?.instantiateViewControllerWithIdentifier("DetailBrowseViewController") as! DetailBrowseViewController

    if let titleString = data?["title"] {
        vc.titleString = titleString.stringValue
        testString = titleString.stringValue
        testString = testString.stringByReplacingOccurrencesOfString(" ", withString: "-")
        testString = testString.lowercaseString
        reusableUrl.replaceRange(Range<String.Index>(start: reusableUrl.startIndex.advancedBy(146), end: reusableUrl.startIndex.advancedBy(146)), with: testString)

        self.loadDetail(reusableUrl, completionHandler:{(UIBackgroundFetchResult) -> Void in
            //I want this collectionView method to somehow pause and wait until the detailResults array is filled and then continue
            print("success")
            detailData = (detailResults?[indexPath.row])!

            if let priceString = detailResults?[indexPath.row]["price"] {
                print(detailData)
                vc.priceString = priceString.stringValue
            }
            self.navigationController?.pushViewController(vc, animated: true)
        })
    }
} 
func collectionView(collectionView:UICollectionView,didSelectItemAtIndexPath indepath:nsindepath){
让数据=结果?[indexPath.row]
让我们看看detailData:JSON
var testString:String=“”
让vc:DetailBrowseViewController=self.storyboard?.instanceeviewcontrollerwhiteIdentifier(“DetailBrowseViewController”)作为!DetailBrowseViewController
如果让titleString=data?[“title”]{
vc.titleString=titleString.stringValue
testString=titleString.stringValue
testString=testString.StringByReplacingOfString(“,带字符串:“-”)的发生率
testString=testString.lowercaseString
replaceRange(范围(开始:reusableUrl.startIndex.advancedBy(146),结束:reusableUrl.startIndex.advancedBy(146)),带:testString)
loadDetail(reusableUrl,completionHandler:{(UIBackgroundFetchResult)->中的Void
//我希望此collectionView方法以某种方式暂停并等待detailResults数组被填充,然后继续
打印(“成功”)
detailData=(detailResults?[indexPath.row])!
如果让priceString=detailResults?[indexPath.row][“price”]{
打印(详细数据)
vc.priceString=priceString.stringValue
}
self.navigationController?.pushViewController(vc,动画:true)
})
}
} 

据我所知,当
self.detailResults
由响应中的JSON数据填充时,您需要调用
completionHandler

我将试图找出我们的主要想法: -仅在成功解析数据时调用competitionHandler -将必要的代码(应等待响应)移动到已加载数据的位置

首先,您需要将
completionHandler
调用移动到.Success案例块的末尾。我认为,如果反应失败,你不需要前进

因此,结果将是:

func loadDetail(urlPath: String, completionHandler: ((UIBackgroundFetchResult)     -> Void)!){
    Alamofire.request(.GET, urlPath)
        .responseJSON { _, _, result in
            switch result {
            case .Success(let data):
                let jsonObj = JSON(data)
                if let data = jsonObj["results"].arrayValue as [JSON]? {
                    //array is filled in the line below
                    self.detailResults = data
                    self.collectionView.reloadData()
                    completionHandler(UIBackgroundFetchResult.NewData)
                }
            case .Failure(_, let error):
                print("Request failed with error: \(error)")
            }
    }

    print("Background Fetch Complete")
}
然后您需要将相关代码(应该等待响应)移动到
completionHandler
,如下所示:

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
    let data = results?[indexPath.row]
    let detailData: JSON
    var testString: String = ""
    let vc: DetailBrowseViewController = self.storyboard?.instantiateViewControllerWithIdentifier("DetailBrowseViewController") as! DetailBrowseViewController

    if let titleString = data?["title"] {
        vc.titleString = titleString.stringValue
        testString = titleString.stringValue
        testString = testString.stringByReplacingOccurrencesOfString(" ", withString: "-")
        testString = testString.lowercaseString
        reusableUrl.replaceRange(Range<String.Index>(start: reusableUrl.startIndex.advancedBy(146), end: reusableUrl.startIndex.advancedBy(146)), with: testString)

        self.loadDetail(reusableUrl, completionHandler:{(UIBackgroundFetchResult) -> Void in
            //I want this collectionView method to somehow pause and wait until the detailResults array is filled and then continue
            print("success")
            detailData = (detailResults?[indexPath.row])!

            if let priceString = detailResults?[indexPath.row]["price"] {
                print(detailData)
                vc.priceString = priceString.stringValue
            }
            self.navigationController?.pushViewController(vc, animated: true)
        })
    }
} 
func collectionView(collectionView:UICollectionView,didSelectItemAtIndexPath indepath:nsindepath){
让数据=结果?[indexPath.row]
让我们看看detailData:JSON
var testString:String=“”
让vc:DetailBrowseViewController=self.storyboard?.instanceeviewcontrollerwhiteIdentifier(“DetailBrowseViewController”)作为!DetailBrowseViewController
如果让titleString=data?[“title”]{
vc.titleString=titleString.stringValue
testString=titleString.stringValue
testString=testString.StringByReplacingOfString(“,带字符串:“-”)的发生率
testString=testString.lowercaseString
replaceRange(范围(开始:reusableUrl.startIndex.advancedBy(146),结束:reusableUrl.startIndex.advancedBy(146)),带:testString)
loadDetail(reusableUrl,completionHandler:{(UIBackgroundFetchResult)->中的Void
//我希望此collectionView方法以某种方式暂停并等待detailRes