在alamofire响应之后附加到现有阵列

时间:2018-01-18 10:41:21

标签: ios arrays json swift alamofire

我有以下代码从API端点获取数据并将此数据格式化为我可以在我的应用程序中使用的对象。然后将此对象添加到可在应用程序中的其他位置访问的数组中:

let headers: HTTPHeaders = [
    "x-api-version": "2",
    "accept": "application/json",
    "content-type": "application/json"
]

Alamofire.request(jsonURLString, headers: headers).responseJSON { response in

    do {
        let establishmentsFromJSON = try JSONDecoder().decode(EstablishmentsFromJSON.self, from: response.data!)

        if !(establishmentsFromJSON.establishments.isEmpty) {
            //print(establishmentsFromJSON.establishments.first?.RatingValue)

            establishment.hygieneRating = establishmentsFromJSON.establishments.first?.RatingValue
            establishment.hygieneRatingKey = establishmentsFromJSON.establishments.first?.RatingKey
            //convert to date object:
            establishment.hygieneRatingDate = ISO8601DateFormatter().date(from: establishmentsFromJSON.establishments[0].RatingDate)
            establishment.hygieneRatingPending = establishmentsFromJSON.establishments.first?.NewRatingPending
            establishment.localAuthorityName = establishmentsFromJSON.establishments.first?.LocalAuthorityName
            establishment.localAuthorityWebsite = establishmentsFromJSON.establishments.first?.LocalAuthorityWebSite
            establishment.localAuthorityEmail = establishmentsFromJSON.establishments.first?.LocalAuthorityEmailAddress

            // only show places I want to see
            self.establishments.append(establishment)
        }
    } catch {
        print("We have an error")
        print(error)
    }

}

// do UI stuff
self.showCount(self.establishments.count)

self.arView.displayItemsAroundCurrentLocation(currentLocation: currentPlace, establishments: self.establishments)

我正在尝试追加到我的alamo请求self.establishments.append(establishment)中的数组。

print(self.establishments.count)之后立即添加append,可以让我看到要添加的元素.. 但是,如果我尝试在请求之外访问该数组,则元素不会存在/不会被追加。为什么是这样?

我有一种感觉它归于线程?我已经尝试了几个完整处理程序示例,例如this questionthis one,但我的数组仍然是空的。

添加

DispatchQueue.main.sync {
    self.establishments.append(establishment)
}

在我的alamo请求中并没有帮助解决此问题。

我知道我在某个地方出错了。只是无法解决问题。有什么想法吗?

修改 https://gist.github.com/anonymous/e1fd8809e0013529106d936af61032cd

establishments数组在类声明的下方创建。

class ContainerViewController: UIViewController, CLLocationManagerDelegate 
{
    @IBOutlet var headingLabel: UILabel!
    @IBOutlet var nameLabel: UILabel!
    @IBOutlet var addressLabel: UILabel!

    @IBOutlet var countLabel: UILabel!
    @IBOutlet var refreshButton: CustomButton!

    var arView: ARViewController!
    var showsDebuggingLabels: Bool = false
    // location
    fileprivate let locationManager = CLLocationManager()
    var placesClient: GMSPlacesClient!
    var requestedItems: Bool = false
    // motion
    let debugHeading: Bool = true // make true to track heading
    let mmgr = CMMotionManager()

    var establishments = [Establishment]()

API结构如下:http://api.ratings.food.gov.uk/Help/Api/GET-Establishments_name_address_longitude_latitude_maxDistanceLimit_businessTypeId_schemeTypeKey_ratingKey_ratingOperatorKey_localAuthorityId_countryId_sortOptionKey_pageNumber_pageSize

编辑2:

print(truncatedEstablishmentName[0].replacingOccurrences(of: "'", with: ""))
print(self.getPostalCode(place: place).replacingOccurrences(of: " ", with: "%20"))
print(place.coordinate.latitude.description)
print(place.coordinate.longitude.description)

返回:

Freeman
S1%202NG
53.3770956
-1.4682824

所以API请求将是

let jsonURLString = "http://api.ratings.food.gov.uk/Establishments?address=S1%202NG&latitude=53.3770956&longitude=-1.4682824&maxDistanceLimit=0&name=Freeman" 

编辑3:

                let headers: HTTPHeaders = [
                    "x-api-version": "2",
                    "accept": "application/json",
                    "content-type": "application/json"
                ]
                self.tryingWithCompletionHandler(jsonURLString: jsonURLString, headers: headers, establishment: establishment, completion: {
                    self.showCount(self.establishments.count)
                    print("place count: \(self.establishments.count)")
                    self.arView.displayItemsAroundCurrentLocation(currentLocation: currentPlace, establishments: self.establishments)
                })



            }
        }


    })
}

func tryingWithCompletionHandler(jsonURLString: String, headers: HTTPHeaders, establishment: Establishment, completion : ()->()) {

    Alamofire.request(jsonURLString, headers: headers).responseJSON { response in

        do {
            let establishmentsFromJSON = try JSONDecoder().decode(EstablishmentsFromJSON.self, from: response.data!)

            if !(establishmentsFromJSON.establishments.isEmpty) {
                //print(establishmentsFromJSON.establishments.first?.RatingValue)

                establishment.hygieneRating = establishmentsFromJSON.establishments.first?.RatingValue
                establishment.hygieneRatingKey = establishmentsFromJSON.establishments.first?.RatingKey
                //convert to date object:
                establishment.hygieneRatingDate = ISO8601DateFormatter().date(from: establishmentsFromJSON.establishments[0].RatingDate)
                establishment.hygieneRatingPending = establishmentsFromJSON.establishments.first?.NewRatingPending
                establishment.localAuthorityName = establishmentsFromJSON.establishments.first?.LocalAuthorityName
                establishment.localAuthorityWebsite = establishmentsFromJSON.establishments.first?.LocalAuthorityWebSite
                establishment.localAuthorityEmail = establishmentsFromJSON.establishments.first?.LocalAuthorityEmailAddress

                // only show places I want to see

                self.establishments.append(establishment)

            }
        } catch {
            print("We have an error")
            print(error)
        }

    }
    completion()
}

以上也给了我一个0的计数。我哪里错了?

1 个答案:

答案 0 :(得分:1)

嘿,欢迎来到异步编程的世界。你的感觉是正确的,并且链接的解决方案实际上应该至少以某种方式帮助你。您没有展示如何使用完成闭包解决方案。 但是,您的代码还有一些问题。您可以逐个迭代并请求您的项目,这可能意味着许多不必要的http请求和相同数量的UI更新可能会相互干扰。最好只有一个,并在完成后,通知用户界面,如链接的示例。

如果无法使用某种批处理API,请考虑使用DispatchGroup(请参阅:https://developer.apple.com/documentation/dispatch/dispatchgroup),等待所有请求完成,然后只通知UI一次。