응용 프로그램 대리인의 경우 코어 위치의 사용자 좌표를 가져온 후 두 번의 API 호출을 원합니다. 하나는 내 서버에, 우리가있는 도시 이름의 슬러그를 얻는 것입니다. 호출은 비동기이므로 전역 변수 배열에 모든 내용을로드하기 전에 google map api에 대한 두 번째 호출을 수행하여 async 호출을 사용하여 google에서 도시 이름을 가져 오려고합니다. 그리고 마지막으로 모든 Google 데이터를로드 한 후 두 개의 배열을 비교하고 도시 이름을 비교하여 우연의 일치를 찾습니다. 그렇게하기 위해서는 처음 두 작업이 끝났어야합니다. 이를 위해 클로저를 사용하여 다음 작업 시작 전에 모든 데이터가로드되는지 확인합니다. 하지만 내 프로그램을 시작할 때 두 개의 배열이 일치하지 않는 것을 발견하고 중단 점을 설정하면 두 번째 배열 (google)이로드됩니다. 후에 비교가 이루어 졌는데 이는 매우 불편합니다. 클로저를 많이 설정하고이 단계에서 내 문제의 출처를 찾을 수 없습니다. 어떤 도움을 주시면 감사하겠습니다.신속한 폐쇄가 무엇이든하고 있습니다. 내 코드 실행이 예상대로 작동하지 않습니다.
import Foundation
import CoreLocation
let weatherApiKey : String = "" //weather api key
var globWeatherTemp : String = ""
var globWeatherIcon : String = ""
var globCity : String = ""
var globCountry : String = ""
let googleMapsApiKey : String = ""
let googlePlacesApiKey : String = ""
var TableData:Array<String> = Array <String>()
var nsDict = []
var locValue : CLLocationCoordinate2D = CLLocationCoordinate2D()
typealias SuccessClosure = (data: String?) -> (Void)
typealias FinishedDownload =() ->()
typealias complHandlerAsyncCall = (success : Bool) -> Void
typealias complHandlerCitySlug = (success:Bool) -> Void
typealias complHandlerAllShops = (success:Bool) -> Void
typealias googleCompareSlugs = (success:Bool) -> Void
var flagCitySlug : Bool?
var flagAsyncCall : Bool?
var flagAllShops : Bool?
var values : [JsonArrayValues] = []
var citySlug : [SlugArrayValues] = []
var asyncJson : NSMutableArray = []
let googleJson : GoogleApiJson = GoogleApiJson()
이로드 내 서버에 전화를 걸 애플 대리자에서 호출 된 첫 번째 함수입니다 : 이것은 내 전역 변수 신속한 파일입니다
let locationManager = CLLocationManager()
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
//Language detection
let pre = NSLocale.preferredLanguages()[0]
print("language= \(pre)")
//Core Location
// Ask for Authorisation from the User.
self.locationManager.requestAlwaysAuthorization()
//Clore Location
// For use in foreground
self.locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
//Load cities slug via api call
let apiCall : webApi = webApi()
apiCall.loadCitySlugs(){(success) in
//Slug loaded in background
//Call google api to compare the slug
apiCall.loadGoogleContent(){(success) in //this function is called after compareGoogleAndApiSlugs()
apiCall.compareGoogleAndApiSlugs() //this one called before
}
}
}
return true
}
:
이
는 애플 대리자입니다 도시 슬러그 :func loadCitySlugs(completed: complHandlerCitySlug){
//Configure Url
self.setApiUrlToGetAllSlugs()
//Do Async call
asyncCall(userApiCallUrl){(success)in
//Reset Url Async call and Params
self.resetUrlApi()
//parse json
self.parseSlugJson(asyncJson)
flagCitySlug = true
completed(success: flagCitySlug!)
}
}
이것은 두 번째 기능으로, Google 콘텐츠를로드하지만 ca (compareGoogleAndApiSlugs 후 채워) 전에 호출해야하는데 ...
/*
Parse a returned Json value from an Async call with google maps api Url
*/
func loadGoogleContent(completed : complHandlerAsyncCall){
//Url api
setGoogleApiUrl()
//Load google content
googleAsyncCall(userApiCallUrl){(success) in
//Reset API URL
self.resetUrlApi()
}
flagAsyncCall = true // true if download succeed,false otherwise
completed(success: flagAsyncCall!)
}
을 마지막으로 비동기 호출은 두가 있지만 거의 동일한 코드입니다 :
/**
Simple async call.
*/
func asyncCall(url : String, completed : complHandlerAsyncCall)/* -> AnyObject*/{
//Set async call params
let request = NSMutableURLRequest(URL: NSURL(string: url)!)
request.HTTPMethod = "POST"
request.HTTPBody = postParam.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
guard error == nil && data != nil else {
// check for fundamental networking error
print("error=\(error)")
return
}
if let httpStatus = response as? NSHTTPURLResponse where httpStatus.statusCode != 200 {
// check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
asyncJson = responseString!.parseJSONString! as! NSMutableArray
flagAsyncCall = true // true if download succeed,false otherwise
completed(success: flagAsyncCall!)
}
task.resume()
}
사람이 볼 수 있다면 문제 또는 일부 빛을 던져 매우 감사하겠습니다. 상기 완료 블록이 googleAsyncCall 블록의 외측이라고
func loadGoogleContent(completed : complHandlerAsyncCall){
setGoogleApiUrl()
googleAsyncCall(userApiCallUrl){(success) in
self.resetUrlApi()
}
flagAsyncCall = true
completed(success: flagAsyncCall!) //THIS LINE IS CALLED OUTSIDE THE googleAsyncCall..
}
:
미안 변수가 원자가 아닌 경우 문제가 될 수있는 것에 대해 더 설명 할 수 있습니까? 나는 신속하고이 정보는 나를 위해 매우 도움이 될 수있는 새로운이야. 또한 글로벌 변수 완성 처리기에 대해 묻고 싶습니다. 항상 글로벌해야합니다. 현지인들과 함께 완성 처리사를 할 수있는 방법이 없을까요? 또한 전역 변수를 재사용 할 수 있는지 알고 싶습니다. 어떻게 다시 false로 설정할 수 있습니까? 감사합니다. 내 문제가 해결되었습니다. – user3033437
변수가 원자가 아니고 여러 스레드가 동시에 쓰기를 위해 액세스하는 경우 변수는 여전히 있습니까? 각 스레드는 다른 값을 볼 수 있습니다. 아니요, 항상 전역 변수가 필요하지는 않습니다. 실제로, 당신은 거의 절대 필요 없을 것입니다. 예, 재사용 할 수 있습니다. – Brandon