如何使用Swift在iOS中附加特殊字符?

时间:2018-12-17 07:58:22

标签: ios swift firebase

请考虑一下我是iOS新手。我想向服务器发布一些数据,但是我无法发送手机号码 +91 bloodGroup A+ ..它正在发送到Firebase +,被" "这样的空间( 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()
 }

功能 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错误:

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;
}

firebase控制台错误:

enter image description here

2 个答案:

答案 0 :(得分:1)

您的实际问题是您的参数没有正确地进行网址编码。

您的代码的临时解决方案:

在您的convertToParams方法中,进行以下更改:

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

注意:您的scapedValue必须为String,因此,将employeeDetails设置为[String:String]。

永久解决方案(完美的查询参数编码方式):

为此,您可以将代码更改为以下内容:

  1. 删除convertToParameters方法
  2. 添加以下方法代替

    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. 从代码中删除以下行:

    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. 添加以下代码,而不是上面删除的代码

    let urlStr = "https://us-central1-pickceltest.cloudfunctions.net/rebliss/createNewUser"
    
    var request = getURLRequestWith(urlStr: urlStr, paramsDict: employeeDetails, isParamsAsQuery: false, isParamsAsBody: true)
    
  5. employeeDetails词典转换为键入[String:String]而不是[String:AnyObject]

现在,尝试您的代码,它肯定会工作。

答案 1 :(得分:0)

请检查以下解决方案是否有效。在您的网址中添加百分比编码。

// 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"