0

I am new to iOS please consider.I want to post some data to server, but I am not able to send Mobile number +91 and bloodGroup A+..it was sending to firebase + is replace with space " " like this ( 91) and (A )

 func addEmployees(){
    let photoUrl = "https://firebasestorage.googleapis.com/v0/b/pickcel-1241.appspot.com/o/task.careGallery%2FGroup%2018aasa.png?alt=media&token=4e0ac8f6-134a-4807-9fef-f44eabe9f6a8";

    let userID = Auth.auth().currentUser!.uid
    let mobilenumber = Auth.auth().currentUser?.phoneNumber
    var employeeDetails = [String : AnyObject]()
    employeeDetails["OID"] =  getOID() as AnyObject
    employeeDetails["MID"] = userID as AnyObject
    employeeDetails["email"] = "ssinth@gmail.com" as AnyObject
    employeeDetails["firstName"] =  "First Name" as AnyObject
    employeeDetails["lastName"] =  "last name" as AnyObject
    employeeDetails["isManager"] = "true" as AnyObject
    employeeDetails["regMedia"] = "mobile" as AnyObject
    employeeDetails["shortDestination"] =  "btm" as AnyObject
    employeeDetails["address"] =  "+btm" as AnyObject
    employeeDetails["createdDate"] = getdateformat() as AnyObject
    employeeDetails["orgName"] = "Test Org" as AnyObject
    employeeDetails["photoUrl"] =  photoUrl as AnyObject
    employeeDetails["officeOpenTime"] =  "09:00" as AnyObject
    employeeDetails["officeCloseTime"]  = "18:00" as AnyObject
    employeeDetails["phoneNumber"] =  labelmobile.text as AnyObject
    employeeDetails["bloodGroup"] =  "A+" as AnyObject
    employeeDetails["empId"] = "abcd" as AnyObject

    let convertedvalue : String = convertToParameters(employeeDetails)

    print("convertedvalues :   \(convertedvalue)")


    let myUrl = URL(string: "https://us-central1-pickceltest.cloudfunctions.net/rebliss/createNewUser");

    var request = URLRequest(url:myUrl!)

    request.httpMethod = "POST"// Compose a query string
    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    let postString = convertedvalue;

    print("start create employee")
    request.httpBody = postString.data(using: String.Encoding.utf8);

    let task = URLSession.shared.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in

        if error != nil
        {
            print("error=\(String(describing: error))")
            return
        }
          print("start create employee  =successfull")

        print("response = \(String(describing: response))")

        do {
             print("start create employee  =parsing problems   ")
            let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary

            if let parseJSON = json {
               // print("resultjson=one : ",self.json)
                print("resultjson=two   : ",parseJSON)       
            }
        } catch {
            print(error)
        }
    }
    task.resume()
 }

function convertToParameters

  func convertToParameters(_ params: [String: AnyObject?]) -> String {
        var paramList: [String] = []

        for (key, value) in params {
            guard let value = value else {
                continue
            }
           let scapedKey = key
           let scapedValue = value
            print("employee add status objects   =   ","\(scapedKey)=\(scapedValue as AnyObject)")
            paramList.append("\(scapedKey)=\(scapedValue as AnyObject)")
        }
        return paramList.joined(separator: "&")
    }

Json Error:

resultjson=two   :  {
    error =     {
        code = "auth/invalid-phone-number";
        message = "The phone number must be a non-empty E.164 standard compliant identifier string.";
    };
    success = 0;
}

Error in firebase console:

enter image description here

Gowthaman M
  • 8,057
  • 8
  • 35
  • 54
  • you need to percentage encode the `+` symbol explicitly, otherwise it is interpreted as a _space_ – you can read more about [how Apple handles the `+` character as default](https://developer.apple.com/documentation/foundation/nsurlcomponents/1407752-queryitems), _(spoiler: it does not do percentage encoding on that)_ – holex Dec 17 '18 at 08:52
  • @holex can you please suggest some reference link how to solve this issues ... – Gowthaman M Dec 17 '18 at 09:24
  • 2
    https://stackoverflow.com/questions/24551816/swift-encode-url may help. – holex Dec 17 '18 at 09:46

2 Answers2

1

Actual issue with you is your parameters not getting properly url encoded.

Temporary Solution for your code:

In your convertToParams method, make following changes:

let scapedKeyEncoded =  scapedKey.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed);
let scapedValueEncoded =  scapedValue.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed);
paramList.append("\(scapedKeyEncoded)=\(scapedValueEncoded)"

Note: Your scapedValue must be String, so, make employeeDetails as [String:String].

Permanent Solution(Perfect way for encoding query parameters):

For this, you can change your code to something like this:

  1. Remove convertToParameters method
  2. Add following method in place of it

    class func getURLRequestWith(urlStr:String, paramsDict:[String:String]?, isParamsAsQuery:Bool, isParamsAsBody:Bool) -> URLRequest? {
    
    guard var components = URLComponents(string: urlStr) else { return nil }
    
    if paramsDict != nil{
        components.queryItems = paramsDict!.map({ (key, value) -> URLQueryItem in
            return URLQueryItem(name: key, value: value)
        })
    }
    
    if isParamsAsQuery{
        let request = URLRequest(url: components.url!);
        return request;
    }
    
    if isParamsAsBody{
        let url = URL(string: urlStr);
        var request = URLRequest(url: url!);
    
        let bodyStr = components.percentEncodedQuery;
        if bodyStr != nil{
            request.httpBody = bodyStr!.data(using: String.Encoding.utf8);
        }
        return request;
    }
    
    let url = URL(string: urlStr);
    let request = URLRequest(url: url!);
    return request;
    }
    
  3. Remove below lines from your code:

    let convertedvalue : String = convertToParameters(employeeDetails)
    
    print("convertedvalues :   \(convertedvalue)")
    
    
    let myUrl = URL(string: "https://us-central1-pickceltest.cloudfunctions.net/rebliss/createNewUser");
    
    var request = URLRequest(url:myUrl!)
    request.httpBody = postString.data(using: String.Encoding.utf8);
    
  4. Add following code instead of above removed code

    let urlStr = "https://us-central1-pickceltest.cloudfunctions.net/rebliss/createNewUser"
    
    var request = getURLRequestWith(urlStr: urlStr, paramsDict: employeeDetails, isParamsAsQuery: false, isParamsAsBody: true)
    
  5. convert employeeDetails dictionary to type [String:String] instead of [String:AnyObject]

Now, try your code and it will surely work.

Mehul Thakkar
  • 12,440
  • 10
  • 52
  • 81
  • Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackoverflow.com/rooms/185404/discussion-on-answer-by-mehul-thakkar-how-to-append-special-character-in-ios-usi). – Samuel Liew Dec 18 '18 at 10:01
0

Please check if below solution works. Add percent encoding to you url.

// Create NSURL Ibject
let url : NSString = urlWithParams as NSString

let urlStr = url.addingPercentEncoding( withAllowedCharacters: .urlQueryAllowed)

let searchURL : NSURL = NSURL(string: urlStr! as String)!

// Creaste URL Request
let request = NSMutableURLRequest(url: searchURL as URL, cachePolicy: NSURLRequest.CachePolicy.reloadIgnoringCacheData, timeoutInterval: 120)

// Set request HTTP method to GET. It could be POST as well
request.httpMethod = "POST"
Yogesh Tandel
  • 1,738
  • 1
  • 19
  • 25