我有以下代码从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 question和this 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]()
编辑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的计数。我哪里错了?
答案 0 :(得分:1)
嘿,欢迎来到异步编程的世界。你的感觉是正确的,并且链接的解决方案实际上应该至少以某种方式帮助你。您没有展示如何使用完成闭包解决方案。 但是,您的代码还有一些问题。您可以逐个迭代并请求您的项目,这可能意味着许多不必要的http请求和相同数量的UI更新可能会相互干扰。最好只有一个,并在完成后,通知用户界面,如链接的示例。
如果无法使用某种批处理API,请考虑使用DispatchGroup(请参阅:https://developer.apple.com/documentation/dispatch/dispatchgroup),等待所有请求完成,然后只通知UI一次。