首页 > 解决方案 > 令人困惑的 Swift 错误:表达式类型不明确,没有更多上下文

问题描述

我收到了这个令人困惑的错误:Type of expression is ambiguous without more context在下面的函数中,我不知道是什么原因造成的。我认为这与我的三个let常量有关,因为当我在那里进行一些更改时,出现了错误。

private func FetchOriginCoordinates(completion: @escaping ([NominationStructure]) -> ()) {
        let locationUrl = "https://nominatim.openstreetmap.org/search?country=Sweden&city=Stockholm&street=\(self.origin.input)&format=json"
        
        let encodedLink = locationUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
        let encodedURL = URL(string: encodedLink!)
        
        URLSession.shared.dataTask(with: locationUrl!) {data, response, error in
            if let data = data {
                do {
                    if let decodedJson = try? JSONDecoder().decode([NominationStructure].self, from: data) {
                        
                        DispatchQueue.main.async {
                            completion (decodedJson)
                        }
                    }
                } catch {
                    print(error)
                }
            }
        }.resume() // This is where the error appears 
    }

标签: swiftfunctionurl

解决方案


大多数时候 Swift 中的错误并没有真正的帮助。您的问题是您试图将字符串而不是 URL 传递给数据任务方法。除此之外,您应该始终处理错误而不是忽略它。我还将更改方法声明以在您的完成处理程序中包含错误:

注意:以小写字母开头的方法命名是 Swift 命名约定。

private func fetchOriginCoordinates(completion: @escaping ([Place]?, Error?) -> ()) {
    let url = URL(string:  "your APY string")!
    URLSession.shared.dataTask(with: url) { data, response, error in
        guard let data = data else {
            completion(nil, error)
            return
        }
        do {
            let decodedJson = try JSONDecoder().decode([Place].self, from: data)
            DispatchQueue.main.async {
                completion(decodedJson, nil)
            }
        } catch {
            completion(nil, error)
        }
    }.resume()
}

编辑/更新:

要正确编码您的 URL,您应该使用 URLComponents 并将地址组件添加到其查询项中:


private func fetchOriginCoordinates(for street: String,
                                country: String = "Sweden",
                                city: String = "Stockholm",
                                format: String = "json",
                                completion: @escaping ([Place]?, Error?) -> ()) {
    var urlComp = URLComponents()
    urlComp.scheme = "https"
    urlComp.host = "nominatim.openstreetmap.org"
    urlComp.path = "/search"
    urlComp.queryItems = [
        .init(name: "country", value: country),
        .init(name: "city", value: city),
        .init(name: "street", value: street),
        .init(name: "format", value: format)
    ]
    guard let url = urlComp.url else {
        completion(nil, URL.Error.invalidCharacterFound(street))
        return
    }
    URLSession.shared.dataTask(with: url) { data, response, error in
        guard let data = data else {
            completion(nil, error)
            return
        }
        do {
            let decodedJson = try
                JSONDecoder().decode([Place].self, from: data)
            DispatchQueue.main.async {
                completion(decodedJson, nil)
            }
        } catch {
            completion(nil, error)
        }
    }.resume()
}

用法:

struct Place: Codable {
    let placeID: Int
    let licence: String
    let osmType: OsmType
    let osmID: Int
    let boundingbox: [String]
    let lat, lon, displayName: String
    let rootClass: Class
    let type: TypeEnum
    let importance: Double

    enum CodingKeys: String, CodingKey {
        case placeID = "place_id", licence, osmType = "osm_type", osmID = "osm_id", boundingbox, lat, lon, displayName = "display_name", rootClass = "class", type, importance
    }
}

enum OsmType: String, Codable {
    case way
}

enum Class: String, Codable {
    case highway
}

enum TypeEnum: String, Codable {
    case residential, secondary, unclassified
}

extension URL {
    enum Error: Swift.Error {
        case invalidCharacterFound(String)
    }
}


fetchOriginCoordinates(for: "Valhallavägen") { results, error in
    guard let results = results else {
        print("error:", error ?? "nil")
        return
    }
    for result in results {
        print(result)
    }
}

这将打印:

Place(placeID: 100830896, licence: "数据 © OpenStreetMap 贡献者, ODbL 1.0. https://osm.org/copyright" , osmType: OsmType.way, osmID: 41510350, boundingbox: ["59.3431062", "59.3438379", " 18.0792506", "18.0821732"], lat: "59.3434756", lon: "18.0807072", displayName: "Valhallavägen, Ladugårdsgärdet, Östermalms stadsdelsområde, Stockholm, Stockholms kommun, Stockholm County, 114 36, Sweden类型:TypeEnum.secondary,重要性:0.6138276880810758)
地点(placeID:110921085,许可证:“数据© OpenStreetMap 贡献者,ODbL 1.0。https://osm.org/copyright ,osmType:OsmType.way,osmID:95305155,边界框:[“59.3473458”,“59.3475855”,“18.0653022”,“18.0654864”],纬度:“59.3475219”,lon:“18.0653483”,显示名称:“Valhallämen Norra Djurgården, Östermalms stadsdelsområde, Stockholm, Stockholms kommun, Stockholm County, 114 24, Sweden", rootClass: Class.highway, type: TypeEnum.secondary, 重要性: 0.6138276880810758)
Place(placeID: 98613676, licence: "数据 © OpenStreetMap 贡献者, ODbL 1.0。https ://osm.org/copyright ", osmType: OsmType.way, osmID: 33057170, boundingbox: ["59.3458032", "59.3459006", "18.0692504", "18.0695413"], lat: "59.3459006", lon: "18.0692504", displayName: "Valärkstaden Östermalm, Östermalms stadsdelsområde, Stockholm, Stockholms kommun, Stockholm County, 100 41, Sweden", rootClass: Class.highway, type: TypeEnum.secondary, 重要性: 0.6138276880810758)
Place(placeID: 97771827, licence: "Data © OpenStreetMap贡献者, ODbL 1.0. https://osm.org/copyright”, osmType: OsmType.way, osmID: 32125128, boundingbox: ["59.3435989", "59.3440214", "18.0767179", "18.0788456"], lat: "59.3437642", lon: "18.0781052", Villa,name: "Valstadenägen Östermalm, Östermalms stadsdelsområde, Stockholm, Stockholms kommun, Stockholm County, 114 36, Sweden", rootClass: Class.highway, type: TypeEnum.secondary, 重要性: 0.6138276880810758) Place(placeID: 217216781, licence: "Data © OpenStreetMap贡献者, ODbL 1.0. https://osm.org/copyright”, osmType: OsmType.way, osmID: 621715886, boundingbox: ["59.3400363", "59.3400593", "18.0943109", "18.0944135"], lat: "59.3400593", lon: "18.0943109", displayName: "Valdhallavetä,genårds" Östermalms stadsdelsområde, Stockholm, Stockholms kommun, Stockholm County, 115 24, Sweden", rootClass: Class.highway, type: TypeEnum.secondary, 重要性: 0.6138276880810758) Place(placeID: 91379768, licence: "Data © OpenStreetMap 贡献者, ODbL 1.0. https://osm.org/copyright”,osmType:OsmType.way,osmID:16620413,boundingbox:[“59.3500575”,“59.3502804”,“18.0588563”,“18.0593429”],lat:“59.3500575”,lon:“18.0593429”,显示名称:“Valhalägen” Norra Djurgården, Östermalms stadsdelsområde, Stockholm, Stockholms kommun, Stockholm County, 113 54, Sweden", rootClass: Class.highway, type: TypeEnum.secondary, 重要性: 0.6138276880810758)
Place(placeID: 122081536, licence: "Data © OpenStreetMap贡献者, ODbL 1.0。https ://osm.org/copyright ", osmType: OsmType.way, osmID: 137883176, boundingbox: ["59.3467668", "59.3469813", "18.0671955", "18.0678302"], lat: "59.3468409", lon: "18.0676219", Rumenädam Norra Djurgården, Östermalms stadsdelsområde, Stockholm, Stockholms kommun, Stockholm County, 100 41, Sweden", rootClass: Class.highway, type: TypeEnum.residential, 重要性: 0.6138276880810758) Place(placeID: 210614450, licence: "Data © OpenStreetMap贡献者, ODbL 1.0。https ://osm.org/copyright ",osmType:OsmType.way,osmID:571062827,boundingbox:[“59.3469813”,“59.3471276”,“18.067152”,“18.0671955”],lat:“59.3469813”,lon:“18.0671955”,显示名称:“Valhallämen Norra Djurgården, Östermalms stadsdelsområde, Stockholm, Stockholms kommun, Stockholm County, 114 24, Sweden", rootClass: Class.highway, type: TypeEnum.residential, 重要性: 0.6138276880810758)
Place(placeID: 100832986, licence: "Data © OpenStreetMap贡献者, ODbL 1.0。https ://osm.org/copyright ",osmType:OsmType.way,osmID:40886504,boundingbox:[“59.3459069”,“59.3467668”,“18.0678302”,“18.0702113”],lat:“59.3464817”,lon:“18.0686787”,显示名称:“Valhallägen” Norra Djurgården, Östermalms stadsdelsområde, Stockholm, Stockholms kommun, Stockholm County, 100 41, Sweden", rootClass: Class.highway, type: TypeEnum.unclassified, 重要性: 0.6138276880810758)
Place(placeID: 172222242, licence: "Data © OpenStreetMap贡献者, ODbL 1.0。https ://osm.org/copyright ",osmType:OsmType.way,osmID:345280785,boundingbox:[“59.3453872”,“59.3458192”,“18.0701008”,“18.0715971”],纬度:“59.3457283”,lon:“18.0702244”,显示名称:“Valhallavdam” Norra Djurgården, Östermalms stadsdelsområde, Stockholm, Stockholms kommun, Stockholm County, 114 26, Sweden", rootClass: Class.highway, type: TypeEnum.unclassified, 重要性: 0.6138276880810758)


推荐阅读