'[CLPlacemark]?" не конвертируется в '[CLPlacemark]' -> swift2

это часть кода, который я нашел на StackOverflow.
Он работал в Swift 1.2 Почему этот код больше не работает в Swift 2:

geoCoder.reverseGeocodeLocation(location, completionHandler: { (placemarks, error) -> Void in
        let placeArray = placemarks as [CLPlacemark] // !!! ERROR HERE !!!

        // Place details
        var placeMark: CLPlacemark!
        placeMark = placeArray[0]

        // Address dictionary
        print(placeMark.addressDictionary)

        // Location name
        if let locationName = placeMark.addressDictionary["Name"] as? NSString {
            print(locationName)
        }

        // Street address
        if let street = placeMark.addressDictionary["Thoroughfare"] as? NSString {
            print(street)
        }

        // City
        if let city = placeMark.addressDictionary["City"] as? NSString {
            print(city)
        }

        // Zip code
        if let zip = placeMark.addressDictionary["ZIP"] as? NSString {
            print(zip)
        }

        // Country
        if let country = placeMark.addressDictionary["Country"] as? NSString {
            print(country)
        }

    })

Ошибка GetLocationViewController.swift:67:41: '[CLPlacemark]?' is not convertible to '[CLPlacemark]'


person VivienG    schedule 18.06.2015    source источник


Ответы (3)


Похоже, вам нужно развернуть массив меток (неявно или необязательно) перед назначением его типу [CLPlacemarks]

В вашем примере вы должны использовать необязательную цепочку, поэтому

if let validPlacemark = placemarks?[0]{
     let placemark = validPlacemark as? CLPlacemark;
}

Затем поместите всю свою логику в фигурные скобки, чтобы, если она найдет допустимый массив меток, она выполнила нужные вам команды. Если нет, он ничего не сделает или вы можете справиться с этим, как хотите.

person Josh Hamet    schedule 18.06.2015
comment
Все равно вернуть ошибку. Невозможно подписать значение типа '[CLPlacemark]?' с индексом типа «Int» - person VivienG; 18.06.2015
comment
Все еще не работает :/ 'CLPlacemark?' не конвертируется в 'CLPlacemark' - person VivienG; 18.06.2015
comment
Теперь принудительное приведение предупреждений из 'CLPlacemark' в 'CLPlacemark' всегда завершается успешно; ты хотел сказать "как"? Выглядит лучше, но предупреждение - это ошибка будущего :) - person VivienG; 18.06.2015
comment
да!! извините за это, не было площадки передо мной, чтобы проверить это очень быстро - person Josh Hamet; 18.06.2015
comment
И что же мне делать ? Для того, чтобы удалить это предупреждение :) - person VivienG; 18.06.2015
comment
Моя новая редакция работает? Вы могли бы использовать как? вместо этого и проверьте ноль, чтобы убедиться, что он развернут, или я предпочитаю просто использовать необязательную цепочку. - person Josh Hamet; 18.06.2015
comment
Все еще нет:/ Условное приведение от «CLPlacemark» к «CLPlacemark» всегда завершается успешно. - person VivienG; 18.06.2015
comment
Теперь Initializer для условной привязки должен иметь дополнительный тип, а не CLPlacemark. - person VivienG; 18.06.2015
comment
Блин, я должен просто вернуться к версии, которая работала раньше. - person Josh Hamet; 18.06.2015
comment
@VivienG использует код, который я отредактировал; пока не утверждено (осталось 350 реп), вот оно: if let validPlacemark = placemarks?[0]{ // use validPlacemark } - person vrwim; 24.06.2015

метки не обязательно имеют значение, вы можете сделать это:

let placeArray: [CLPlacemark] = placemarks as? [CLPlacemark] ?? []

Что читается как,

если placemarks можно преобразовать в [CLPlacemark], сделайте это. В противном случае назначьте пустой массив.

Вот этот код на практике:

введите здесь описание изображения

Теперь я понимаю, что вы на Xcode 7! Там еще проще, все, что вам нужно, это:

let placeArray = placemarks ?? []
person Logan    schedule 18.06.2015
comment
Это по-прежнему возвращает ошибку. Понижен с "[CLPlacemark]?" to '[CLPlacemark]' разворачивает только необязательные элементы; Вы хотели использовать '!'? - person VivienG; 18.06.2015
comment
@VivienG - я только что понял, что ты на новой бета-версии! См. нижнее обновление, вы можете сделать это еще проще, так как дженерики Objective-C были обновлены для типов массивов! - person Logan; 19.06.2015

В Xcode 7.0 Objective-C имеет общие массивы, поэтому ваш массив placemarks больше не [AnyObject]?, а теперь [CLLocation]?. Вам не нужно приводить массив, вы можете просто развернуть необязательный. С добавлением защитных операторов ваш блок завершения теперь так же прост, как:

geocoder.reverseGeocodeLocation(location) { placemarks, error in
    guard let placemarks = placemarks else { print(error); return; }
    guard let placemark = placemarks.first else { return; }
    // ...
}
person kubi    schedule 18.06.2015