-1

I have an array of dictionnaries: [[String:String]]. Every dictionnary countain a string parameter (text) in french.

When I put this array in a dictionnary: [String:AnyObject], accents in the string text parameter are converted in ASCII.

For example é become \U00e9

Here's my code :

var args: [String:AnyObject] = [
        "action":"share",
        "id": NSNumber(longLong: id)
    ]
    var shareOn = [[String:String]]()
    if let sharers = User.currentUser?.sharers {
        for (index, object) in enumerate(sharers) {
            if object.enabled == true {
                var sharerContent: [String:String] = ["sharerId": object.sharerId, "cnxId": String(object.cnxId)]
                if object.shareAsImageEnable == true {
                    sharerContent["shareAsImage"] = "true"
                }
                if object.mustSpecifyShareText == true {
                    var text : String! = (title != nil) ? title : ""
                    if object.sharerId.lowercaseString.rangeOfString("twitter") != nil {
                        let maxLength = 140 - 27 // Twitter limit - max URL long
                        if text.length > maxLength {
                            let index: String.Index = advance(text.startIndex, maxLength-3)
                            text = text.substringToIndex(index) + "... http://ppo.az/..."
                        } else {
                            text = text + " http://ppo.az/..."
                        }
                    }
                    sharerContent["text"] = text
                }
                shareOn.append(sharerContent)
            }
        }
    }

    println(shareOn)

    args["shareOn"] = shareOn

    println(args)

And the results of println:

println(shareOn) => accent OK =>

[[sharerId: facebook, cnxId: 4230821, shareAsImage: true, text: Le kit de réparation de portable est toulousain]]

println(args) => accent NOT OK =>

[action: share, id: 4049850929, shareOn: ( { cnxId = 4150811; shareAsImage = true; sharerId = facebook; text = "Le kit de r\U00e9paration de portable est toulousain"; } )]

EDIT : My Router and my function makeRequest :

import UIKit
import Alamofire
import OAuthSwift

enum Router: URLRequestConvertible {

static let baseURLString: String! = Global.kClientAPIURL
static var oauthClient: OAuthSwiftClient!

case Login([String: AnyObject])
case LoginSocial([String: AnyObject])
case Profil([String: AnyObject])
case GetCompilation([String: AnyObject])
case GetSavedSearch([String: AnyObject])
case sharePost([String: AnyObject])


var URLRequest: NSURLRequest {
    let (method: Alamofire.Method, path: String, parameters : [String: AnyObject]?) = {
        switch self {
        case .Login(let params):
            return (.POST, "api/1/login", params)
        case .LoginSocial(let params):
            return (.POST, "api/1/login-with-social-account", params)
        case .Profil(let params):
            return (.GET, "api/1/profile", params)
        case .GetCompilation(let params):
            return (.GET, "api/1/compilation", params)
        case .GetSavedSearch(let params):
            return (.GET, "api/1/search", params)
        case .sharePost(let params):
            return (.POST, "api/1/post", params)
        }
    }()

    let URL = NSURL(string: Router.baseURLString)!
    let URLWithPath = URL.URLByAppendingPathComponent(path)

    let auth = OAuthSwiftClient.authorizationHeaderForMethod(method.rawValue,
        url: URLWithPath,
        parameters: parameters!,
        credential: Router.oauthClient.credential)
    let URLRequest = makeRequest(URLWithPath, method.rawValue, ["Authorization" : auth], parameters!, NSUTF8StringEncoding)

    return URLRequest
  }
}

func makeRequest(URL: NSURL, method: String, headers: [String : String], parameters: Dictionary<String, AnyObject>, dataEncoding : NSStringEncoding) -> NSMutableURLRequest {
var request = NSMutableURLRequest(URL: URL)
request.HTTPMethod = method

for (key, value) in headers {
    request.setValue(value, forHTTPHeaderField: key)
}

let charset = CFStringConvertEncodingToIANACharSetName(CFStringConvertNSStringEncodingToEncoding(dataEncoding))

var nonOAuthParameters = parameters.filter { key, _ in !key.hasPrefix("oauth_") }

if nonOAuthParameters.count > 0 {
    if request.HTTPMethod == "GET" || request.HTTPMethod == "POST" {
        let queryString = nonOAuthParameters.urlEncodedQueryStringWithEncoding(dataEncoding)
        request.URL = URL.URLByAppendingQueryString(queryString)
        request.setValue("application/x-www-form-urlencoded; charset=\(charset)", forHTTPHeaderField: "Content-Type")
    }
    else {
        var error: NSError?
        if let jsonData: NSData = NSJSONSerialization.dataWithJSONObject(nonOAuthParameters, options: nil, error: &error)  {
            request.setValue("application/json; charset=\(charset)", forHTTPHeaderField: "Content-Type")
            request.HTTPBody = jsonData
        }
        else {
            println(error!.localizedDescription)
        }
    }
}
return request
}
Gautier
  • 47
  • 1
  • 13

2 Answers2

0

The string \U00e9 is not an ascii character, but simply the Unicode format for the letter é. In other words, nothing is changed, but only printed in a different way.

When the value is printed as String, it is printed "correctly".

On the other hand, the library function that prints a value of type AnyObject try to be more generic possible, and render non-english characters with their Unicode code point.

Renzo
  • 26,848
  • 5
  • 49
  • 61
0

Your dictionary and the text are OK, the "problem" comes from println.

Paste this in a Playground for demonstration:

var args = [String:AnyObject]()
var shareOn = [[String:String]]()
shareOn.append(["key":"clé"])
println(shareOn)
args["shareOn"] = shareOn
println(args)

args["shareOn"]

The output of println looks wrong but in the Playground you see that the actual content of the dictionary is right, the accented letter is still here.

println doesn't know how to treat accented characters if the object type is not String.

enter image description here

If you declare the String type for the values, then println works correctly:

var args = [String:[[String:String]]]()
var shareOn = [[String:String]]()
shareOn.append(["key":"clé"])
println(shareOn)
args["shareOn"] = shareOn
println(args)

enter image description here

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
  • Thanks but the server receive this string too "Le kit de rU00e9paration de portable est toulousain" and I use NSUTF8StringEncoding... I have edited my question to add my Router and my function makeRequest() – Gautier Aug 21 '15 at 13:04
  • Gautier, you said that "println(shareOn)" worked but "println(args)" didn't. I've answered that. Now you say your string isn't good anyway. But how could it be not good if it was ok in "println(shareOn)" and if it's ok, as I demonstrated, in "println(args)" too? Your router and other stuff is irrevelant. *Don't trust the output of println, that's all.* Check for yourself programmatically by comparing strings with a reference if you have doubts. – Eric Aya Aug 21 '15 at 13:06
  • That's my question. When I print the text in UITextView I have the correct text but when I send the dictionnary to the server, the server had the wrong text with \U00e9. I've done another version of this app in Obj-C and it worked like a charm.. – Gautier Aug 21 '15 at 13:10
  • You should have started by this in your question... "I know my string is ok but it's wrong in the server" is an *entirely* different question from the one you asked. I feel like wasting my time here. – Eric Aya Aug 21 '15 at 13:12
  • I strongly suggest you ask a *new* question with a *clear* statement of your problem, based on what you just told me in the comment, and not the irrelevant stuff you posted in the question here. – Eric Aya Aug 21 '15 at 13:15
  • I'm sorry and I think the problem come from the AnyObject or the NSUTF8StringEncoding but I can't figure out. – Gautier Aug 21 '15 at 13:16
  • Have you even tried to change the type of `args` like in the second part of my answer? Of course the problem comes from AnyObject, that's what I explained... And if after understanding my answer you still have problems with *your server*, then ask a *new* question precisely on this topic with relevant information. As for this question, I'm done. – Eric Aya Aug 21 '15 at 13:20