This question already has answers here:
How do I decode HTML entities in Swift?
(23 answers)
Closed 5 years ago.
I'm using NSURLSession to communicate with a Webservice. However, in the JSON from Webservice I'm getting strings like this Biblotecas de cat& aacute;logos de Marcas i.e. Biblotecas de catálogos de Marcas. I need to get rid of the text cat& aacute;logos and get the original string. How can i do this.
I'm using this code for parsing the JSON.
guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String:Any] else{
self.showalertview(messagestring: parseError)
return
}
The best way is to ask the owner of the webservice to send UTF-8 compliant text.
If this is not possible NSAttributedString can decode HTML entities in a very convenient way, this is a String extension adding the computed property htmlDecoded. As the conversion can fail for several reasons the return value is an optional:
extension String {
var htmlDecoded : String? {
guard let encodedString = self.data(using: .utf8) else { return nil }
let options : [String:Any] = [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue]
return try? NSAttributedString(data: encodedString, options: options, documentAttributes: nil).string
}
}
And use it:
let string = "Biblotecas de catálogos de Marcas"
print(string.htmlDecoded) // "Biblotecas de catálogos de Marcas"
Related
This question already has answers here:
Decoding a JSON without keys in Swift 4
(3 answers)
Closed 8 months ago.
I am trying to access each title in a returned json. This is the JSON
[
"Hyouka",
"Youjo Senki",
"Bungou Stray Dogs 2nd Season",
"Fullmetal Alchemist: Brotherhood",
"Tokyo Ghoul √A",
"Mahouka Koukou no Rettousei",
"Boku wa Tomodachi ga Sukunai NEXT",
"Joker Game",
"Avatar: The Last Airbender",
"Charlotte"
]
It's just a bunch of values and no key for me to construct my model object. This is how I would plan to do it
struct AllNames {
let name: String
}
But there's no key name for me to access. How would you go about accessing this data to print each name to the console in Swift?
Your json is an array of strings , so no model is here and you only need
do {
let arr = try JSONDecoder().decode([String].self, from: jsonData)
print(arr)
}
catch {
print(error)
}
Convert JSON string to array:
func getArrayFromJSONString(jsonStr: String) -> Array<Any> {
let jsonData: Data = jsonStr.data(using: .utf8)!
let arr = try? JSONSerialization.jsonObject(with: jsonData, options: .mutableContainers)
if arr != nil {
return arr as! Array<Any>
}
return []
}
Test case:
let jsonStr = """
[
\"Hyouka\",
\"Youjo Senki\",
\"Bungou Stray Dogs 2nd Season\",
\"Fullmetal Alchemist: Brotherhood\",
\"Tokyo Ghoul √A\",
\"Mahouka Koukou no Rettousei\",
\"Boku wa Tomodachi ga Sukunai NEXT\",
\"Joker Game\",
\"Avatar: The Last Airbender\",
\"Charlotte\"
]
"""
let arr = getArrayFromJSONString(jsonStr: jsonStr)
print(arr)
Print log:
[Hyouka, Youjo Senki, Bungou Stray Dogs 2nd Season, Fullmetal Alchemist: Brotherhood, Tokyo Ghoul √A, Mahouka Koukou no Rettousei, Boku wa Tomodachi ga Sukunai NEXT, Joker Game, Avatar: The Last Airbender, Charlotte]
How to Convert this one. "{\n ID = \"d9a7c7bf-781d-47b3-bb4e-e1022ec4ce1b\";\n Name = Headquarters;\n}"; To this format {
"ID": "d9a7c7bf-781d-47b3-bb4e-e1022ec4ce1b",
"Name": "Headquarters"
}
if let jsonString = text as? String {
let objectData = jsonString.data(using: String.Encoding.utf8)
do {
let json = try JSONSerialization.jsonObject(with: objectData!, options: .allowFragments) as! [String:Any] //try JSONSerialization.jsonObject(with: objectData!, options: JSONSerialization.ReadingOptions.mutableContainers)
print(String(describing: json))
return json
} catch {
// Handle error
print(error)
}
}
Blockquote
First of all and already mentioned the string format is clearly not JSON.
It's the string format which is returned when calling the description property of a Foundation collection type (NSArray / NSDictionary).
For example a print statement calls description and this format appears also in output of Terminal.app.
However there is a solution: This string format is called openStep (an OpenStep / NeXt legacy format) and is available in PropertyListSerialization
This code reads the format:
let string = "{\n ID = \"d9a7c7bf-781d-47b3-bb4e-e1022ec4ce1b\";\n Name = Headquarters;\n}"
let data = Data(string.utf8)
do {
let dictionary = try PropertyListSerialization.propertyList(from: data, format: nil)
print(dictionary)
} catch { print(error) }
Note:
I'm pretty sure that the original data format is not openStep and somewhere you created the string unnecessarily with the String(describing initializer like in the question.
your json format is incorrect. If you try it with jsonformatter it will throw this error:
so first you need to replace ; with ,. The second is that Strings should be wrapped in double quotes, replace Name = Headquarters with Name = "Headquarters".
This is the right form
{\n ID = \"d9a7c7bf-781d-47b3-bb4e-e1022ec4ce1b\",
\n Name = "Headquarters"\n}
This question already has answers here:
How to parse a JSON file in swift?
(18 answers)
Closed 3 years ago.
I want to print just value for key "User_number"
[
{
"User_fullname": null,
"User_sheba": null,
"User_modifiedAT": "2019-01-31T18:37:02.716Z",
"_id": "5c53404e91fc822c80e75d23",
"User_number": "9385969339",
"User_code": "45VPMND"
}
]
I suppose this is some JSON in Data format
let data = Data("""
[ { "User_fullname": null, "User_sheba": null, "User_modifiedAT": "2019-01-31T18:37:02.716Z", "_id": "5c53404e91fc822c80e75d23", "User_number": "9385969339", "User_code": "45VPMND" } ]
""".utf8)
One way is using SwiftyJSON library, but, this is something what I don't suggest since you can use Codable.
So, first you need custom struct conforming to Decodable (note that these CodingKeys are here to change key of object inside json to name of property of your struct)
struct User: Decodable {
let fullname, sheba: String? // these properties can be `nil`
let modifiedAt, id, number, code: String // note that all your properties are actually `String` or `String?`
enum CodingKeys: String, CodingKey {
case fullname = "User_fullname"
case sheba = "User_sheba"
case modifiedAt = "User_modifiedAT"
case id = "_id"
case number = "User_number"
case code = "User_code"
}
}
then decode your json using JSONDecoder
do {
let users = try JSONDecoder().decode([User].self, from: data)
} catch { print(error) }
So, now you have Data decoded as array of your custom model. So if you want to, you can just get certain User and its number property
let user = users[0]
let number = user.number
The following code takes takes in Data and saves "User_number" as an Int
if let json = try? JSONSerialization.jsonObject(with: Data!, options: []) as! NSDictionary {
let User_number= json["User_number"] as! Int
}
I send the text from a TextView to my Backend. To include linebreaks, i try to serialize the textView.text to JSON.
let jsonObject: NSMutableDictionary = NSMutableDictionary()
jsonObject.setValue(textView.text, forKey: "text")
let jsonData: NSData
do {
jsonData = try JSONSerialization.data(withJSONObject: jsonObject, options: JSONSerialization.WritingOptions()) as NSData
let jsonString = NSString(data: jsonData as Data, encoding: String.Encoding.utf8.rawValue) as! String
print(jsonString)
} catch _ {
print ("JSON Failure")
}
}
But since this is a Dictionary, the resulting text looks like this:
{"text":"test\nstack\n\noverflow"}
i actually just need: test\nstack\n\noverflow
Is there a pretty way to transform a multiline String in swift to have these "\n" for linebreaks without any extra characters?
Edit:
I expect to type into my textView something like this:
and as a result get the string "hello\n\n"
The source looks like this:
let text = textView.text
let components = text?.components(separatedBy: CharacterSet.newlines).filter({!$0.isEmpty})
let textWithLineFeeds = components?.joined(separator:"\n")
print(textWithLineFeeds!)
print(textView.text)
the first print gives:
test
hello
linebreak above
the second print statement:
test
hello
linebreak above
i wish i could see:
test\nhello\n\nlinebreak above
To convert text with arbitrary new line characters (CR, LF, CRLF etc.) to distinct - only LF - line breaks use:
let text = "test\r\nstack\n\noverflow\rfoo"
let components = text.components(separatedBy: CharacterSet.newlines).filter({!$0.isEmpty})
let textWithLineFeeds = components.joined(separator:"\n")
If the server accepts only CR, change \n to \r.
This question already has answers here:
How do I decode HTML entities in Swift?
(23 answers)
Closed 7 years ago.
When I read the data from, say http://www.weather-forecast.com/, with the code below:
let urlContent = NSString(data: data!, encoding: NSUTF8StringEncoding)
The urlContent data is coming up as "°". How do you convert it to "°" (i.e degree symbol)?
EDIT: Go with the accepted answer for scalability. But if you have a weird case where you only want to replace a single kind of character this answer will do.
The degree symbol is represented in Swift by the string \u{00B0}. You can use this fact with stringByReplacingOccurencesOfString() to do something like this:
let formattedUrlContent = urlContent.stringByReplacingOccurrencesOfString("°", withString: "\u{00B0}")
this worked too in Swift 2.0 !
stringByReplacingOccurrencesOfString("°", withString: "°")
It really isn't a good practice to go manually replacing HTML escape characters like this. Cocoa has built in utilities to do this for you with NSAttributedString:
let input = "75°, partly cloudy"
let options: [String : AnyObject] = [NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute : NSUTF8StringEncoding]
if let data = input.dataUsingEncoding(NSUTF8StringEncoding) {
do {
let unescaped = try NSAttributedString(data: data, options: options, documentAttributes: nil)
print(unescaped.string) // "75°, partly cloudy"
} catch {
print(error)
}
}