Issue with converting data string to UTF8 - ios

I am getting some datas with JSON but when I get data the names tring is something like this :
{
code = 200;
found = 1;
name = "\\u0635\\u0641\\u062d\\u0647 \\u0631\\u0633\\u0645\\u06cc \\u0633\\u0627\\u06cc\\u062a \\u0648\\u0631\\u0632\\u0634 \\u06f3";
}
How can fix it ? I tried to convert it to UTF8 encoding and still nothing ! I have to say the URL works fine in Safari with UTF8 encoding
Here is my code :
let userURL: String = "https://myurl.com/xxx"
let ut8 = userURL.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
NSURLSession.sharedSession().dataTaskWithURL(NSURL(string:ut8!)!, completionHandler: { (data, response, error) -> Void in
// Check if data was received successfully
if error == nil && data != nil {
do {
if let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary {
print(jsonResult)
}
.....
}
Problem Solved: There was a problem in server , now fixed

It's just what the print method outputs and it sometimes has problem with encoding. You should be fine when render those text in your UI.

To convert the data string into UTF8 string in Swift
yourNSStringObject.utf8
To convert the data string into UTF8 string in Objective C use
[yourNSStringObject UTF8String];

Related

use of "po" to get data from server response in console log

i know this is very basic question that i am gonna ask but i need to ask how can i access data which is dictionary that is getting from server.
here is my response
JSON: {
message = "The email must be a valid email address.";}
now i want to do "po" in console log so what to write after in po statement
Thanks
All you need type
po yourResponseAsDictionary["message"]
UPDATED
Sorry I was thinking you already converted it.
If you are not using anything like SwiftyJSON or ObjectMapper to parse your json data then you can do just the following.
But I would recommend to use some lib to convert response directly to your model
let yourResponseFromNetwork = "{ \"country_code\" : \"+9\", \"user_id\" : 123456}"
if let data = yourResponseFromNetwork.data(using: String.Encoding.utf8) {
do {
if let dic = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String:Any] {
let countryCode = dic["country_code"]
let userId = dic["user_id"]
}
} catch {
print("Error occurred")
}
}

Cleaning malformed UTF-8 data

Background
With Swift, I'm trying to fetch HTML via URLSession rather than by loading it into a WKWebView first as I only need the HTML and none of the subresources. I'm running into a problem with certain pages that work when loaded into WKWebView but when loaded via URLSession (or even a simple NSString(contentsOf: url, encoding String.Encoding.utf8.rawValue)) the UTF-8 conversion fails.
How to reproduce
This fails (prints "nil"):
print(try? NSString(contentsOf: URL(string: "http://www.huffingtonpost.jp/techcrunch-japan/amazon-is-gobbling-whole-foods-for-a-reported-13-7-billion_b_17171132.html?utm_hp_ref=japan&ir=Japan")!, encoding: String.Encoding.utf8.rawValue))
But changing the URL to the site's homepage, it succeeds:
print(try? NSString(contentsOf: URL(string: "http://www.huffingtonpost.jp")!, encoding: String.Encoding.utf8.rawValue))
Question
How can I "clean" the data returned by a URL that contains malformed UTF-8? I'd like to either remove or replace any invalid sequences in the malformed UTF-8 so that the rest of it can be viewed. WKWebView is able to render the page just fine (and claims it's UTF-8 content as well), as you can see by visiting the URL: http://www.huffingtonpost.jp/techcrunch-japan/amazon-is-gobbling-whole-foods-for-a-reported-13-7-billion_b_17171132.html?utm_hp_ref=japan&ir=Japan
Here is an approach to create a String from (possibly) malformed
UTF-8 data:
Read the website contents into a Data object.
Append a 0 byte to make it a "C string"
Use String(cString:) for the conversion. This initializer replaces ill-formed UTF-8 code unit sequences with the Unicode replacement character ("\u{FFFD}").
Optionally: Remove all occurrences of the replacement character.
Example for the "cleaning" process:
var data = Data(bytes: [65, 66, 200, 67]) // malformed UTF-8
data.append(0)
let s = data.withUnsafeBytes { (p: UnsafePointer<CChar>) in String(cString: p) }
let clean = s.replacingOccurrences(of: "\u{FFFD}", with: "")
print(clean) // ABC
Swift 5:
var data = Data([65, 66, 200, 67]) // malformed UTF-8
data.append(0)
let s = data.withUnsafeBytes { p in
String(cString: p.bindMemory(to: CChar.self).baseAddress!)
}
let clean = s.replacingOccurrences(of: "\u{FFFD}", with: "")
print(clean) // ABC
Of course this can be defined as a custom init method:
extension String {
init(malformedUTF8 data: Data) {
var data = data
data.append(0)
self = data.withUnsafeBytes { (p: UnsafePointer<CChar>) in
String(cString: p).replacingOccurrences(of: "\u{FFFD}", with: "")
}
}
}
Swift 5:
extension String {
init(malformedUTF8 data: Data) {
var data = data
data.append(0)
self = data.withUnsafeBytes{ p in
String(cString: p.bindMemory(to: CChar.self).baseAddress!)
}.replacingOccurrences(of: "\u{FFFD}", with: "")
}
}
Usage:
let data = Data(bytes: [65, 66, 200, 67])
let s = String(malformedUTF8: data)
print(s) // ABC
The cleaning can be done more "directly" using transcode with
extension String {
init(malformedUTF8 data: Data) {
var utf16units = [UInt16]()
utf16units.reserveCapacity(data.count) // A rough estimate
_ = transcode(data.makeIterator(), from: UTF8.self, to: UTF16.self,
stoppingOnError: false) { code in
if code != 0xFFFD {
utf16units.append(code)
}
}
self = String(utf16CodeUnits: utf16units, count: utf16units.count)
}
}
This is essentially what String(cString:)
does, compare
CString.swift and
StringCreate.swift.
Yet another option is to use the UTF8 codecs decode() method
and ignore errors:
extension String {
init(malformedUTF8 data: Data) {
var str = ""
var iterator = data.makeIterator()
var utf8codec = UTF8()
var done = false
while !done {
switch utf8codec.decode(&iterator) {
case .emptyInput:
done = true
case let .scalarValue(val):
str.unicodeScalars.append(val)
case .error:
break // ignore errors
}
}
self = str
}
}

How to remove xml tags before send to the json parser in swift

I want to use JSON data in my app. So I am using this webservice calling method to convert my json data to an array.
func getData(path: String, completion: (dataArray: NSArray)->()) {
let semaphore = dispatch_semaphore_create(0)
// var datalistArray = NSArray()
let baseUrl = NSBundle.mainBundle().infoDictionary!["BaseURL"] as! String
let fullUrl = "\(baseUrl)\(path)"
print("FULL URL-----HTTPClient \(fullUrl)")
guard let endpoint = NSURL(string:fullUrl) else {
print("Error creating endpoint")
return
}
let request = NSMutableURLRequest(URL: endpoint)
NSURLSession.sharedSession().dataTaskWithRequest(request,completionHandler: {(data,response,error) in
do {
guard let data = data else {
throw JSONError.NoData
}
guard let json = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? NSArray else {//NSJSONReadingOptions.AllowFragments
throw JSONError.ConversionFailed
}
print(json)
if let data_list:NSArray = json {
completion(dataArray: data_list)
dispatch_semaphore_signal(semaphore);
}
}catch let error as JSONError {
print(error.rawValue)
} catch let error as NSError {
print(error.debugDescription)
}
}) .resume()
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
}
But now my service sending json data within xml tags like <string xmlns="http://tempuri.org/">json data</string so I am getting an exception when I try to convert my json data. The exception is this.
Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.}
What should I change in my code to remove those tags before sending to json parser?
Please help me.
Thanks
I think your response that you get from server is in xml format not in json. If it is in xml format then you must do xml parsing instead of json parsing.
NSJSONSerialization.JSONObjectWithData is json parsing that give json object from data (data in json format).
But if you getting response in xml format from server then you should use NSXMLParser to parse the data.
If you don't have much idea about it then you can refer tutorial like
XML Parsing using NSXMLParse in Swift by The appguruz or can use third party libraries.

NSURLSession does not returns data for http/https

I need to get the data from the url it works for other url like udemy but returns nil for url="http://www.google.com/finance/converter?a=1&from=USD&to=INR"
how to solve this issue. i have added app transport security too..
screen
let url = NSURL(string: "https://www.udemy.com/the-complete-ios-9-developer-course/")!
let task = NSURLSession.sharedSession().dataTaskWithURL(url) { (data, response, error) -> Void in
if let url_content = data{
let webcontent = NSString(data: url_content, encoding: NSUTF8StringEncoding)
print(webcontent)
}
}
task.resume()
This is a text encoding problem. The webpage at http://www.google.com/finance/converter?a=1&from=USD&to=INR is not encoded with UTF-8 but with ISO-8859-1.
In this case, you have to use NSISOLatin1StringEncoding instead of NSUTF8StringEncoding for NSString:
let webcontent = NSString(data: url_content, encoding: NSISOLatin1StringEncoding)
You can check the "error" variable to see if you have an error returned by the call. Most probably you have an error accessing that url.
Note that I tried the code and I could get data.

How can I get the Swift/Xcode console to show Chinese characters instead of unicode?

I am using this code:
import SwiftHTTP
var request = HTTPTask()
var params = ["text": "这是中文测试"]
request.requestSerializer.headers["X-Mashape-Key"] = "jhzbBPIPLImsh26lfMU4Inpx7kUPp1lzNbijsncZYowlZdAfAD"
request.responseSerializer = JSONResponseSerializer()
request.POST("https://textanalysis.p.mashape.com/segmenter", parameters: params, success: {(response: HTTPResponse) in if let json: AnyObject = response.responseObject { println("\(json)") } },failure: {(error: NSError, response: HTTPResponse?) in println("\(error)") })
The Xcode console shows this as a response:
{
result = "\U8fd9 \U662f \U4e2d\U6587 \U6d4b\U8bd5";
}
Is it possible to get the console to show the following?:
{
result = "这 是 中文 分词 测试"
}
If so, what do I need to do to make it happen?
Thanks.
Instead of
println(json)
use
println((json as NSDictionary)["result"]!)
This will print the correct Chinese result.
Reason: the first print will call the debug description for NSDictionary which escapes not only Chinese chars.
Your function actually prints the response object, or more accurately a description thereof. The response object is a dictionary and the unicode characters are encoded with \Uxxxx in their descriptions.
See question: NSJSONSerialization and Unicode, won't play nicely together
To access the result string, you could do the following:
if let json: AnyObject = response.responseObject {
println("\(json)") // your initial println statement
if let jsond = json as? Dictionary<String,AnyObject> {
if let result = jsond["result"] as? String {
println("result = \(result)")
}
}
}
The second println statement will print the actual string and this code actually yields:
{
result = "\U8fd9 \U662f \U4e2d\U6587 \U6d4b\U8bd5";
}
result = 这 是 中文 测试

Resources