我在使用Cloud Firestore的GeoPoint初始化商店的位置时尝试设置代码时遇到麻烦。我在尝试设置初始化程序以能够处理数据时遇到2个错误,我对问题所在的位置发表了评论。

错误显示在我的private init?(documentID: String, dictionary: [String: Any]) {中:

'let'不能嵌套在另一个'var'或'let'模式和期望模式内

条件绑定的初始化程序必须具有可选类型,而不是“ CLLocationCoordinate2D”

我一直在尝试修改我的模型,使其代码更整洁,以便更好地处理数据,减少错误和故障,而这只是与在此结构中设置的GeoPoint费劲。

struct Stores {
    var documentID: String
    var name: String
    var category: String
    var price: Int
    var imageURL: URL
    var description: String
    var location: CLLocationCoordinate2D
    var distanceFromUser: Double
    var rating: Int

//    self.distanceFromUser = (CLLocationManager().location?.distance(from: CLLocation(latitude: location.latitude, longitude: location.longitude)))!
//    print("look here!", self.distanceFromUser)
}

extension Stores: DocumentSerializable {

     init(name: String,
          category: String,
          price: Int,
          description: String,
          rating: Int,
          imageURL: URL,
          location: CLLocationCoordinate2D,
          distanceFromUser: Double) {
       let document = Firestore.firestore().products.document()
       self.init(documentID: document.documentID,
                 name: name,
                 category: category,
                 price: price,
                 imageURL: imageURL,
                 description: description,
                 location: location,
                 distanceFromUser: (CLLocationManager().location?.distance(from: CLLocation(latitude: location.latitude, longitude: location.longitude)))!,
                 rating: rating)
     }

     /// Initializes a stores from a documentID and some data, ostensibly from Firestore.
     private init?(documentID: String, dictionary: [String: Any]) {
        guard let name = dictionary["name"] as? String,
           let category =  dictionary["category"] as? String,
           let price =  dictionary["price"] as? Int,
           let rating = dictionary["rating"] as? Int,
           let description =  dictionary["description"] as? String,
           let imageURLString = dictionary["photoURL"] as? String,

           //ERRORS HERE\\
           let geoPoint = dictionary["location"] as? GeoPoint else { return nil}
           let latitude = geoPoint.latitude,
           let longitude = geoPoint.longitude, // errors: 'let' cannot appear nested inside another 'var' or 'let' pattern & Expected pattern

       guard let location =  CLLocationCoordinate2D(latitude: latitude, longitude: longitude) else { return nil }     // error: Initializer for conditional binding must have Optional type, not 'CLLocationCoordinate2D'
           // ERRORS END \

       guard let imageURL =  URL(string: imageURLString) else { return nil }

       self.init(documentID: documentID,
                 name: name,
                 category: category,
                 price: price,
                 imageURL: imageURL,
                 rating: rating,
                 description: description,
                 location: location)
     }

     init?(document: QueryDocumentSnapshot) {
        self.init(documentID: document.documentID, dictionary: document.data())
     }

     init?(document: DocumentSnapshot) {
        guard let data = document.data() else { return nil }
        self.init(documentID: document.documentID, dictionary: data)
     }

     /// The dictionary representation of the restaurant for uploading to Firestore.
     var documentData: [String: Any] {
        return [
         "name": name,
         "category": category,
         "price": price,
         "imageURL": imageURL.absoluteString,
         "description": description
         "rating": rating,
         "location": location
       ]
     }
}




public protocol DocumentSerializable {

    init?(document: QueryDocumentSnapshot)

    init?(document: DocumentSnapshot)

    var documentID: String { get }

    var documentData: [String: Any] { get }

 }

extension Firestore {
  /// Returns a reference to the top-level stores collection.
    var stores: CollectionReference {
        return self.collection("stores")
    }
}

最佳答案

您只是忘记了以guard结尾长的else { return nil }表达式。
更换

let geoPoint = dictionary["location"] as? GeoPoint,




let geoPoint = dictionary["location"] as? GeoPoint else { return nil }


然后放置

let latitude = geoPoint.latitude
let longitude = geoPoint.longitude


在下面,您应该会很好。最后两个分配不会失败,因此您可以将它们放在guard语句中。

10-02 08:26