2015-08-21 4 views
2

В одном из моих приложений мне нужно указать адресную строку geocode. Сначала я рассмотрел использование CLGeocoder. Однако после того, как я попробовал, я наткнулся на проблему, которую я описал в this.Alamofire с геокодированием google api

Решение заключается в использовании API геокодирования Google. Теперь я переключился на них и удалось заставить их работать, имея следующие функции:

func startConnection(){ 
    self.data = NSMutableData() 
    let urlString = "https://maps.googleapis.com/maps/api/geocode/json?address=\(searchBar.text!)&key=MYKEY" 

    let linkUrl:NSURL = NSURL(string:urlString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!)! 
    let request: NSURLRequest = NSURLRequest(URL: linkUrl) 
    let connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false)! 
     connection.start() 
} 

func connection(connection: NSURLConnection!, didReceiveData data: NSData!){ 
    self.data.appendData(data) 
} 

func connectionDidFinishLoading(connection: NSURLConnection!) { 
    do { 
     if let json = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers) as? [String: AnyObject] { 
      print(json) 
     } 
    } 
    catch { 
     print("error1") 
    } 
} 

Это прекрасно работает и решает проблему, которую я имел с CLGeocoder. Однако, помимо извлечения координат места, мне нужно также использовать API часовых поясов Google для извлечения часового пояса для каждого места.

Выполнение этого с помощью NSURLConnection или NSURLSession представляется мне немного сложным, поскольку мне нужно будет отслеживать, какая сессия/соединение вернется. Итак, я хотел бы иметь некоторое решение, которое использует обработчики завершения.

Я попытался использовать рамку Alamofire (используя правильную ветку для Swift 2.0). Однако, похоже, что функция request() является неправильной для использования в этом случае. Я пробовал:

let parameters = ["address":searchBar.text!,"key":"MYKEY"] 
Alamofire.request(.GET, "https://maps.googleapis.com/maps/api/geocode/json", parameters: parameters).responseJSON(options:.AllowFragments) { _, _, JSON in 
      print(JSON) 
     } 

И все, что я печатаю, это «УСПЕХ». Я надеюсь, что я делаю что-то неправильно, и это может быть исправлено, потому что я действительно хотел бы иметь возможность использовать закрытие вместо делегированных вызовов.

Мои вопросы:

  1. Можно ли использовать Alamofire с Google API, геокодирования?
  2. Если да, не могли бы вы рассказать мне, что я делаю неправильно?
  3. Если это невозможно, можете ли вы предложить мне, как разработать систему с NSURSession или NSURLConnection, что позволило бы мне использовать обработчики завершения для каждого вызова вместо делегатов?

P.S. Я знаю, что я могу использовать синхронные запросы, но я бы очень хотел, чтобы избежать использования этой опции

Update

Было высказано предположение, что добавление .MutableContainers как вариант следует сделать responseJSON работы. Я пробовал код ниже:

let apiKey = "MYKEY" 
var parameters = ["key":apiKey,"components":"locality:\(searchBar.text!)"] 
Alamofire.request(.GET, "https://maps.googleapis.com/maps/api/geocode/json", parameters: parameters).responseJSON(options:.MutableContainers) { one, two, JSON in 
    print(JSON) 
} 

И все, что я печатаю, это «УСПЕХ».

ответ

-1

Хорошо, я, наконец, понял это (с помощью @cnoon). Возвращаемое значение имеет тип Result. Я не мог найти документацию для него, но исходный код доступен here.

Для извлечения JSON ниже реализации могут быть использованы:

Alamofire.request(.GET, "https://mapss.googleapis.com/maps/api/geocode/json", parameters: parameters).responseJSON(options:.MutableContainers) { _, _, JSON in 
    switch JSON { 

    case .Failure(_, let error): 
     self.error = error 
     break 

    case .Success(let value): 
     print(value) 
     break 

    } 
} 

value напечатано правильное представление ответа от геокодирования API.

+1

Это, безусловно, будет работать с 'responseJSON'. Вам просто нужно передать пользовательские параметры чтения в сериализатор. По умолчанию используется значение '.AllowFragments', и вам, по-видимому, требуется '.MutableContainers'. – cnoon

+0

@cnoon, к сожалению, он не работает. См. Раздел «Обновление» в моем вопросе. Кроме того, если вы в состоянии, можете ли вы взглянуть на этот вопрос, который у меня есть о отправке для бета-тестирования (проблема определенно из-за рамки) http://stackoverflow.com/questions/32158112/alamofire-swift-2 -cannot-submit-for-beta-testing-xcode-7-beta-5 –

+1

Успех означает, что он 'IS' работает. В ветке 'swift-2.0'' responseJSON' теперь возвращает тип результата, который при печати печатает 'SUCCESS' или' FAILURE'. Если вам нужна дополнительная информация, используйте «debugPrint». Посмотрите на тип «Результат» и примеры в документах о том, как получить фактические значения из «результата». – cnoon

Смежные вопросы