How to send Apostrophe ('s) in API request(Alamofire) swift 5? - ios

I'm trying to send Apostrophe('s) in request using Alamofire.
I've tried below things but didn't get success
1) addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
2) addingPercentEncoding(withAllowedCharacters: .alphanumerics)
3) func utf8EncodedString()-> String {
let messageData = self.data(using: .nonLossyASCII)
let text = String(data: messageData!, encoding: .utf8) ?? ""
return text
}

After, searching relentlessly then finally I found one solution that we can turn off smart punctuation on particular textfield(smartQuotesType method).

try this:
let stringText = "This is my string"
let datas = ["myString": stringText]
guard let upload = try? JsonEncoder().encode(datas) else { return }
at this point send "upload" on your server, decode Json and use "myString" as variable for example in php:
$json = file_get_contents('php://input');
$array = json_decode($json, true);
$myString = $array["myString"];

Related

Swift String escaping when serializing to JSON using Codable

I'm trying to serialize my object as following:
import Foundation
struct User: Codable {
let username: String
let profileURL: String
}
let user = User(username: "John", profileURL: "http://google.com")
let json = try? JSONEncoder().encode(user)
if let data = json, let str = String(data: data, encoding: .utf8) {
print(str)
}
However on macOS I'm getting the following:
{"profileURL":"http:\/\/google.com","username":"John"}
(note escaped '/' character).
While on Linux machines I'm getting:
{"username":"John","profileURL":"http://google.com"}
How can I make JSONEncoder return the unescaped?
I need the string in JSON to be strictly unescaped.
For iOS 13+ / macOS 10.15+
You can use .withoutEscapingSlashes option to json decoder to avoid escaping slashes
let user = User(username: "John", profileURL: "http://google.com")
let jsonEncoder = JSONEncoder()
jsonEncoder.outputFormatting = .withoutEscapingSlashes
let json = try? jsonEncoder.encode(user)
if let data = json, let str = String(data: data, encoding: .utf8) {
print(str)
}
Console O/P
{"profileURL":"http://google.com","username":"John"}
NOTE: As mention by Martin R in comments \/ is a valid JSON escape sequence.
I ended up using replacingOccurrences(of:with:), which may not be the best solution, but it resolves the issue:
import Foundation
struct User: Codable {
let username: String
let profileURL: String
}
let user = User(username: "John", profileURL: "http://google.com")
let json = try? JSONEncoder().encode(user)
if let data = json, let str = String(data: data, encoding: .utf8)?.replacingOccurrences(of: "\\/", with: "/") {
print(str)
dump(str)
}
I got it. The thing was that it didn't contain any \ character. It is just the property of swift that it will always return such a string on a console. The workaround is to j-son parse it.
Still, you can be used below solution of replacing '\/' with "/" string
let newString = str.replacingOccurrences(of: "\\/", with: "/")
print(newString)
While playing around JSONEncoder/JSONDecoder,
I found that the URL type is lossy on encode -> decode.
Initializes with a string, relative to another URL.
init?(string: String, relativeTo: URL?)
Might be help this apple document: https://developer.apple.com/documentation/foundation/url
using the PropertyList version, however:
let url = URL(string: "../", relativeTo: URL(string: "http://google.com"))!
let url2 = PropertyListDecoder().decode([URL].self, from: PropertyListEncoder().encode([User]))
Other way
let url = URL(string: "../", relativeTo: URL(string: "http://google.com"))!
let url2 = JSONDecoder().decode([URL].self, from: JSONEncoder().encode([User]))
Hope will helpful to you!!
Actually you cannot do that since in macOS and Linux are a bit different escaping systems. On linux // is allowed, macOS - not(it uses NSSerialization). So, you can just add percent encoding on your string, which guarantees you equal strings on macOS and linux, right string posting to a server and right validating. On adding percent escaping set CharacterSet.urlHostAllowed. Could be done like this:
init(name: String, profile: String){
username = name
if let percentedString = profile.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlHostAllowed){
profileURL = percentedString
}else{
profileURL = ""
}
}
In the same manner, you can removePercentEncoding
AND YOU DONT NEED MODIFY SERVER SIDE!!!

Got string Url but the url have "\/".How to get each correct value in string like array type swift3

I got a string from server,but the url string looks strange, and it also like array type. I don't know how to get each value. Sorry I am beginner.Thanks.
let string:String = "[\"http:\/\/aaa.com\/user\/head\/111.jpg?1495612713419\",\"http:\/\/aaa.com\/user\/head\/222.jpg?1496215823622\",\"http:\/\/aaa.com\/user\/head\/333.jpg?1495251220764\",\"http:\/\/aaa.com\/user\/head\/444.jpg?1495773694237\",\"http:\/\/aaa.com\/user\/head\/555.jpg?1495597839001\"]"
let tempArr = string.components(separatedBy: ",")
var stringArr = Array<String>()
for a in tempArr {
var b = a.replacingOccurrences(of: "\"", with: "")
b = b.replacingOccurrences(of: "[", with: "")
b = b.replacingOccurrences(of: "]", with: "")
stringArr.append(b)
}
print(stringArr)
print log
["http:\\/\\/aaa.com\\/user\\/head\\/111.jpg?1495612713419", "http:\\/\\/aaa.com\\/user\\/head\\/222.jpg?1496215823622", "http:\\/\\/aaa.com\\/user\\/head\\/333.jpg?1495251220764", "http:\\/\\/aaa.com\\/user\\/head\\/444.jpg?1495773694237", "http:\\/\\/aaa.com\\/user\\/head\\/555.jpg?1495597839001"]
The server is sending the url of images that converted into the string and string have by default property to add \ in Json so just convert the string into the url the \ will auto remove.
eg.
let url = NSURL(string: urlstring)
print("the url = (url)")
Thanks
The \ is added as escaping character while the string is encoded to JSON and it seems you are directly using the JSON string without decoding it first. How are you getting this result? are you using Alamofire?. Please let me know to help you further.
func fetchMyImages() {
let url = "some url to call the image api"
let request = Alamofire.request(url)
request.validate().responseJSON { [unowned self] (response) in
switch response.result {
case .success(let result):
self.doSomething(with: result) //the result is Any object
case .failure(let error):
print("Oh my Error: \(error)")
}
}
}
This will give you the JSON decoded object and then you can cast it appropriately to Dictionary if it is Dictionary or Array if it is Array

How do I convert response.body from Vapor to String in Swift 3?

I'm using Vapor to try to get an XML file from another server, the problem is I don't know how to convert the response body to a swift String.
let bikesResponse = try drop.client.get("http://www.c-bike.com.tw/xml/stationlistopendata.aspx")
let bodyBytes = bikesResponse.body
let string = String(bytes) // <-- WHAT DO I DO HERE?
Thanks
Ah, ok I figured it out eventually.
let bikesResponse = try drop.client.get("http://www.c-bike.com.tw/xml/stationlistopendata.aspx")
if let bodyBytes = bikesResponse.body.bytes {
let string = String(bytes: bodyBytes, encoding: String.Encoding.utf8) {
}

use emoji in label from ios default keyboard

i want to use text input and emoji from iOS default keyboard and send it to server and show that text to label but i am not able to display emojis.it only display text but not emojis.
if i do it locally than it will display emoji.
self.labelName.text = TextFiled.text
output : "test 😘😝"
but when i send send it to server and receive from it from api than emoji is gone.
output : "test"
please dont down vote my question without any reason
Swift 3.0 Extension solution:
You need to encode and decode emoji's on iOS side when sending it to server. You can do it as below.
extension String {
func encodeChatString() -> String? {
if let encodedTextData = self.data(using: .nonLossyASCII) {
return String(data: encodedTextData, encoding: .utf8)
}
return nil
}
func decodeChatString() -> String? {
let trimmedString = self.trimmingCharacters(in: .whitespacesAndNewlines)
if let stringData = trimmedString.data(using: .utf8) {
let messageString = String(data: stringData, encoding: .nonLossyASCII)
return messageString
}
return nil
}
}
When you send message encode string like below:
message.encodeChatString()
When you receive message decode string like below:
message.decodeChatString()
When send a data to server use this method .
let data1 = txtMessage.text.dataUsingEncoding(NSNonLossyASCIIStringEncoding)!
let finalmessage = String(data: data1, encoding: NSUTF8StringEncoding)
when you get a response from server before set in label use this method.
let trimmedString = YOURSERVER_RESPONSE_STRING.stringByTrimmingCharactersInSet(
NSCharacterSet.whitespaceAndNewlineCharacterSet())
let data2 = trimmedString.dataUsingEncoding(NSUTF8StringEncoding)!
let messagestring = String(data: data2, encoding: NSNonLossyASCIIStringEncoding)
YOURLABEL.text = messagestring as String
Try this your problem solve.

(Payload was not valid JSON) trying to print to slack room in swift

let str = "payload={'channel': '#bottest', 'username': 'garrettogrady', 'text': 'This post is coming from swift.'}"
let strData = (str as NSString).dataUsingEncoding(NSUTF8StringEncoding)
let cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData
let url = NSURL(string: "web hook url (leaving it out for privacy reasons")
var request = NSMutableURLRequest(URL: url!, cachePolicy: cachePolicy, timeoutInterval: 2.0)
request.HTTPMethod = "POST"
request.HTTPBody = strData
println("printing to slack")
var error : NSError? = nil
if let data = NSURLConnection.sendSynchronousRequest(request, returningResponse: nil, error: &error) {
let results = NSString(data:data, encoding:NSUTF8StringEncoding)
println(results)
}
else
{
println("data invalid")
println(error)
}
So when I run this code, I don't get in error. But when I print results, it says "Payload was not valid JSON"
Slack expects double quotes on JSONs. The result you're getting is from Slack rejecting your JSON as it's presently formed.
Here is code from my own stuff, which lets you incorporate variable values for the various fields, which I figure is your next step anyway.
let channel = "#bottest"
let username = "garrettogrady"
let text = "This post is coming from swift."
let payload = "payload={\"channel\": \"\(channel)\", \"username\": \"\(username!)\", \"text\": \"\(text)\""}"
EDIT: This question inspired me to create an object to implement the Slack webhook API. Here it is for anyone interested: https://github.com/pfj3/SwiftSlackbots
Well, this is because your JSON is not valid, as stated by the error message.
In the JSON string, keys have to be inside double quotes; dictionaries are delimited with {} and arrays with []. Also, use :, not =.
let str = "{\"payload\":{\"channel\": \"#bottest\", \"username\": \"garrettogrady\"}}"
You can check if your JSON string is valid by creating an object with it:
if let strData = (str as NSString).dataUsingEncoding(NSUTF8StringEncoding) {
var error: NSError?
if let json = NSJSONSerialization.JSONObjectWithData(strData, options: NSJSONReadingOptions.allZeros, error: &error) as? [String:AnyObject] {
println(json)
}
}
What's printed is the object representation of the JSON content (syntax look different of course, don't mix it up with the JSON syntax or the Swift syntax):
["payload": {
channel = "#bottest";
username = garrettogrady;
}]
Then you're sure that your JSON string is ok to be sent, because you were able to make an object with it.

Resources