简体   繁体   中英

Cannot convert value of type '()' to expected argument type 'String'

I am taking the zip code entered by my user and converting it into a City name. After it is converted to the City name I will save the information into my Firebase Database. I am getting an error "Cannot convert value of type '()' to expected argument type 'String'" when I try to do this. I am getting the zip code from a text field and passing it from the previous ViewController. error

 //first ViewController


 override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{


    if let destination = segue.destination as? SignUpSecondViewController{

    destination.zipCode = zipCodeInput.text! 
    destination.name = nameText.text!
    destination.email = emailText.text!
    destination.password = passwordText.text!
    destination.pictureData = userImageView.image!
    }}

}

   //second ViewController

    var zipCode = String()

 func getLocationFromPostalCode(postalCode : String){
    let geocoder = CLGeocoder()

    geocoder.geocodeAddressString(postalCode) {
        (placemarks, error) -> Void in
        // Placemarks is an optional array of type CLPlacemarks, first item in array is best guess of Address

        if let placemark = placemarks?[0] {

            if placemark.postalCode == postalCode{
                // you can get all the details of place here
                print("\(placemark.locality)")
                print("\(placemark.country)")
            }
            else{
                print("Please enter valid zipcode")
            }
        }
    }
}




 @IBAction func completeButtonAction(_ sender: Any) {

let nameText = name
let emailField = email.lowercased()
let finalEmail = emailField.trimmingCharacters(in: .whitespacesAndNewlines)
let location = getLocationFromPostalCode(postalCode: zipCode)
let biography = bioTextView.text!
let passwordText = password
let interests = options.joined(separator: " , ")

    var pictureD: NSData?


    if let imageView = self.sentPic.image {
        pictureD = UIImageJPEGRepresentation(self.sentPic.image!, 0.70) as! NSData
    }


    if  finalEmail.isEmpty || biography.isEmpty || password.isEmpty || pictureD == nil {
        self.view.endEditing(true)
        let alertController = UIAlertController(title: "OOPS", message: " You must fill all the fields", preferredStyle: .alert)
        alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
        present(alertController, animated: true, completion: nil)

    }else {
        SVProgressHUD.show()

        self.view.endEditing(true)
        authService.signUP(firstLastName: nameText, email: finalEmail, location: location, biography: biography, password: password, interests: interests, pictureData: pictureD as NSData!)

    }
    SVProgressHUD.dismiss()


    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let vc = storyboard.instantiateViewController(withIdentifier: "NewTabBarViewController") as! UIViewController
    // Alternative way to present the new view controller
     self.navigationController?.present(vc, animated: true, completion: nil)


}

Your problem begins with this line:

let location = getLocationFromPostalCode(postalCode: zipCode)

The problem is that your getLocationFromPostalCode has no return value so the compiler thinks that the implicit type of location is () which means a function with no return (void) type.

So, in theory, you would want to change:

func getLocationFromPostalCode(postalCode : String) {

to:

func getLocationFromPostalCode(postalCode : String) -> String {

and have the function return a String value.

But, you can't do that either since the implementation of your getLocationFromPostalCode consists of getting the location from an asynchronous network call.

The proper solution is to rewrite that function to take a completion handler that returns the obtained location.

func getLocationFromPostalCode(postalCode: String, completion: (String?) -> Void) {
    let geocoder = CLGeocoder()

    geocoder.geocodeAddressString(postalCode) { (placemarks, error) -> Void in
        // Placemarks is an optional array of type CLPlacemarks, first item in array is best guess of Address

        if let placemark = placemarks?.first {
            if placemark.postalCode == postalCode {
                // you can get all the details of place here
                print("\(placemark.locality)")
                print("\(placemark.country)")
                completion(placemark.locality) // or whatever value you want
                return
            }
            else{
                print("Please enter valid zipcode")
            }
        }

        completion(nil) // no location found
    }
}

Now, with that all fixed up, you need to redo how you get the location.

@IBAction func completeButtonAction(_ sender: Any) {
    var pictureD: Data? = nil
    if let imageView = self.sentPic.image {
        pictureD = UIImageJPEGRepresentation(imageView, 0.70)
    }

    let emailField = email.lowercased()
    let finalEmail = emailField.trimmingCharacters(in: .whitespacesAndNewlines)
    let biography = bioTextView.text!
    let passwordText = password

    if  finalEmail.isEmpty || biography.isEmpty || password.isEmpty || pictureD == nil {
        self.view.endEditing(true)
        let alertController = UIAlertController(title: "OOPS", message: " You must fill all the fields", preferredStyle: .alert)
        alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
        present(alertController, animated: true, completion: nil)
    }else {
        getLocationFromPostalCode(postalCode: zipCode) { (location) in
            guard let location = location else {
                print("no location")
                return
            }

            let nameText = name
            let interests = options.joined(separator: " , ")

            SVProgressHUD.show()

            self.view.endEditing(true)
            authService.signUP(firstLastName: nameText, email: finalEmail, location: location, biography: biography, password: password, interests: interests, pictureData: pictureD!)
            SVProgressHUD.dismiss()
        }
    }

    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let vc = storyboard.instantiateViewController(withIdentifier: "NewTabBarViewController") as! UIViewController
    // Alternative way to present the new view controller
    self.navigationController?.present(vc, animated: true, completion: nil)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM