SWIFT 4.1 无法使用类型为“(字符串?)”的参数列表调用类型“Double”的初始化程序

Posted

技术标签:

【中文标题】SWIFT 4.1 无法使用类型为“(字符串?)”的参数列表调用类型“Double”的初始化程序【英文标题】:SWIFT 4.1 Cannot invoke initializer for type 'Double' with an argument list of type '(String?)' 【发布时间】:2018-08-08 15:55:29 【问题描述】:

我正在检索发布在 Firebase 中的 mapView 注释以在地图上显示它们,但是在转换纬度和经度的字符串值以将它们重新组合成 CLLocationCoordinates2D 时出现错误。我不明白为什么,因为在另一个函数中我使用相同的方法但从数组中获取值但我没有得到错误。同样在检索数据时,我还想使用来自 firebase 的键值作为我的注释的初始化程序。但是我又收到两个错误 Use of unresolved identifier 'firebaseKey' 和 Use of unresolved identifier 'recombinedCoordinate' for initialisers。函数如下:

func displayAlerts() 
        // FIREBASE: Reference
        ref = Database.database().reference()

        // FIREBASE:Retrieve posts and listen for changes
        databaseHandle = ref?.child("Community").child("Alert Notifications").observe(.childAdded, with:  (snapshot) in

            let data = snapshot.value as? [String:String]
            if let actualData = data 
                let dataLatitude = data!["Latitude"]
                let dataLongitude = data!["Longitude"]
                self.alertIconToDisplay = data!["Description"]

                let doubledLatitude = Double(dataLatitude)
                let doubledLongitude = Double(dataLongitude)
                var recombinedCoordinate = CLLocationCoordinate2D(latitude: doubledLatitude!, longitude: doubledLongitude!)
                print("Firebase post retrieved !")
                self.dummyFunctionToFoolFirebaseObservers()
            
            let dataKey = snapshot.key as? String
            if let firebaseKey = dataKey 
                print("Longitude DataKey is \(String(describing: dataKey))")
                print("Longitude Actual DataKey is \(String(describing: firebaseKey))")

                self.dummyFunctionToFoolFirebaseObservers()
            

            print("fir long \((snapshot.value!, snapshot.key))")
            userAlertAnnotation = UserAlert(type: self.alertIconToDisplay, coordinate: recombinedCoordinate, firebaseKey: firebaseKey)
            self.mapView.addAnnotation(self.userAlertAnnotation)  
        )
     

这是注释模型:

class UserAlert: NSObject , MKAnnotation 
    var type: String?
    var firebaseKey: String?
    var coordinate:CLLocationCoordinate2D

    init(type:String, coordinate:CLLocationCoordinate2D, firebaseKey: String) 
        self.type = type
        self.firebaseKey = firebaseKey
        self.coordinate = coordinate
    

我在这里做错了什么?我知道初始化器上的错误是因为初始化发生在键闭包中,但是我如何将所有数据合并到初始化器中?

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? 

        let annotationView = MKAnnotationView(annotation: userAlertAnnotation, reuseIdentifier: "")    //  CHANGE FOR NEW ANNOTATION : FULL DATA

        //added if statement for displaying user location blue dot
        if annotation is MKUserLocation
            return nil
         else 


            annotationView.image = UIImage(named: alertIconToDisplay!)                        //    choose the image to load

            let transform = CGAffineTransform(scaleX: 0.27, y: 0.27)
            annotationView.transform = transform
            return annotationView
        
    



 func postAlertNotification() 

        // to set next notification id as the position it will have in array ( because first position is 0 ) we use the array.count as value


        let latitude = alertNotificationLatitude
        let longitude = alertNotificationLongitude
        let alertType = alertNotificationType

        let post: [String:String] = [//"Date" : date as! String,
                                     //"Time" : time as! String,
                                     "Latitude" : latitude as! String,
                                     "Longitude" : longitude as! String,
                                     "Description" : alertType as! String]

        var ref: DatabaseReference!
        ref = Database.database().reference()
        ref.child("Community").child("Alert Notifications").childByAutoId().setValue(post)
  

【问题讨论】:

纬度和经度是否在 Firebase 中存储为字符串? 【参考方案1】:

主题中的错误表明您无法从可选字符串创建 Double,这是真的。 要解决它,请强制解开 LatitudeLongitude 的值。

但主要问题是范围问题,初始化程序中使用的所有变量都必须在相同范围内。您可以使用guard 语句展平范围:

...
databaseHandle = ref?.child("Community").child("Alert Notifications").observe(.childAdded, with:  (snapshot) in

        defer  self.dummyFunctionToFoolFirebaseObservers() 
        guard let data = snapshot.value as? [String:String] else  return 
        guard let firebaseKey = snapshot.key as? String else  return 

        //                let date = data!["Date"]
        //                let time = data!["Time"]
        let dataLatitude = data["Latitude"]!
        let dataLongitude = data["Longitude"]!
        self.alertIconToDisplay = data["Description"]!

        let doubledLatitude = Double(dataLatitude)
        let doubledLongitude = Double(dataLongitude)
        let recombinedCoordinate = CLLocationCoordinate2D(latitude: doubledLatitude!, longitude: doubledLongitude!)

        print("Firebase post retrieved !")

        //                self .keyaLon = dataKey
        //                self.keyaLonArray.append(firebaseKey)

        print("Longitude Actual DataKey is \(String(describing: firebaseKey))")

        print("fir long \((snapshot.value!, snapshot.key))")
        self.userAlertAnnotation = UserAlert(type: self.alertIconToDisplay, coordinate: recombinedCoordinate, firebaseKey: firebaseKey)
        self.mapView.addAnnotation(self.userAlertAnnotation)


    )

【讨论】:

我现在看到了问题。感谢您的解释。现在我面临这个问题。所有图标都是一样的。 Firebase 实时数据库列表中的最后一个。如果我在加载后发布另一个,它会显示选择的一个。但回到之前的 viewcontoller 并回到 mapVC 中,所有图标都与我刚刚发布的相同。我将在描述中添加我分配要使用的图像和注释的 mapView 函数。 在意识到我不应该编辑这个问题的标题后,我对上一条评论提出了一个新问题。所以我把旧标题重新放了一遍。

以上是关于SWIFT 4.1 无法使用类型为“(字符串?)”的参数列表调用类型“Double”的初始化程序的主要内容,如果未能解决你的问题,请参考以下文章

使用 Swift 4.1 编译的模块无法在 Swift 3.2.3 中导入

swift 3完成处理程序返回字符串

Swift中对C语言接口缓存的使用以及数组字符串转为指针类型的方法

Swift 无法将类型“()”的值分配给类型“字符串?”

无法强制将“字符”类型的值转换为“字符串”类型

无法将类型 [NSObject : AnyObject] 转换为字符串