Swift Struct is Codable but can't encode - swift

struct KOTextPrompt: Codable {
let prompt: String
let response: String
}
I have a very simple struct that is Codable. I'm been trying to pass this as a parameter using Alamofire and got a crash
2019-07-31 14:52:00.894242-0700 Kirby[8336:1685359] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (__SwiftValue)'
I tried printing the code below and got "false". What am I doing wrong?
let gg = KOTextPrompt(prompt: "testprompt", response: "testresponse")
print(JSONSerialization.isValidJSONObject(gg))

The issue here is that gg which is an instance of KOTextPromptit is not a valid JSON object. You need to encode your struct:
struct KOTextPrompt: Codable {
let prompt, response: String
}
let gg = KOTextPrompt(prompt: "testprompt", response: "testresponse")
do {
let data = try JSONEncoder().encode(gg)
print("json string:", String(data: data, encoding: .utf8) ?? "")
let jsonObject = try JSONSerialization.jsonObject(with: data)
print("json object:", jsonObject)
} catch { print(error) }
This will print
json string: {"response":"testresponse","prompt":"testprompt"}
json
object: {
prompt = testprompt;
response = testresponse; }

Related

Issue while displaying correctly an error message for Invalid credentials

I would like to display the content of the error received from my server in my iPad apps using Swift, but I can not display it correctly:
(lldb) po (response.rawString)
"{\"message\":\"Invalid Credentials\"}"
I would like to display only :
Invalid Credentials
You could add a custom type for your error and make it conform to Codable
struct ServerError: Error, Codable {
let message: String
}
and then decode value of response.rawString using JSONDecoder
let decoder = JSONDecoder()
guard
let data = response.rawString.data(using: .utf8),
let error = try? decoder.decode(ServerError.self, from: data)
else {
return
}
print(error.message) // output: Invalid Credentials

Alamofire, Swift: What could be causing this error?

What could be causing this error?
All of a sudden out of nowhere I started getting the error below. I have reinstalled the cocoapod, cleaned the build folder, and reinstalled the app already and none of that has fixed the error.
ERROR: Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
CODE:
let recoverUrl = "http://www.website.com/recover.php?email=\(emailData)&local=application"
let urlEncodedString = recoverUrl.replacingOccurrences(of: " ", with: "%20")
parseRecover(url: urlEncodedString)
//////////////
func parseRecover(url : String){ AF.request(url).responseJSON(completionHandler: { response in self.parseData(JSONData: response.data!) }) }
func parseData(JSONData : Data){
do {
var readableJSON = try JSONSerialization.jsonObject(with: JSONData, options: .mutableContainers) as! JSONObject
if let recoverJSON = readableJSON["Recover"] as? [JSONObject] {
for i in 0..<recoverJSON.count {
let JSON = recoverJSON[i]
let status = JSON["status"] as! String
let message = JSON["message"] as! String
if status == "Error" {self.Alert01("\(message)")}
else if status == "Success" { self.Alert02("\(message)") }
}}}
catch { print(error) }
}
ERROR IS OCCURING AT:
func parseRecover(url : String){ AF.request(url).responseJSON(completionHandler: { response in self.parseData(JSONData: response.data!) }) }
There's no guarantee that a response has data, so force unwrapping the value can lead to crashes. I suggest you create Decodable types to parse your responses and use Alamofire's responseDecodable method to handle your responses.
Additionally, even if you don't adopt Decodable, responseJSON already parses your response Data using JSONSerialization, so you can just access the response.result to see the output.
SOLVED: The issue was within my php file. I was using $_GET[''] and it should have been a $_POST[''] or $_REQUEST['']

How to convert String to JSON in Swift

I am receiving text from a web socket. And I want to convert the text to JSON.
Text received from the socket:
{'id': 920, 'location': {'lat': 11.0368754733495, 'lon': -47.203396772120247}}
Tried this:
func websocketDidReceiveMessage(socket: WebSocketClient, text: String) {
print("got some text: \(text)")
let data = Data(text.utf8)
do {
// make sure this JSON is in the format we expect
if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
// try to read out a string array
if let id = json["id"] as? Int {
print(id)
}
}
} catch let error as NSError {
print("Failed to load: \(error.localizedDescription)")
}
But I am getting Failed to load: The data couldn’t be read because it isn’t in the correct format. error.
This is not valid JSON. The keys must be wrapped in double quotes.
You can replace the single quotes with double quotes on the fly
let data = Data(text.replacingOccurrences(of: "\'", with: "\"").utf8)
Side note:
Never print .localizedDescription in JSONSerialization/JSONDecoder catch blocks. And bridge casting to NSError is redundant
catch {
print("Failed to load:", error)
}

error when convert JSON to Dictionary Swift

can you help me,
I'm facing an issue if the JSON came with multilines like this
"{\"groupId\":\"58\",\"chat\":\"send 2lines\nsecondline\"}"
I'm taking the response from server and convert it with this function
let dataDic = self.convertToDictionary(text: (remoteMessage.appData["message"]! as AnyObject) as! String)
print(dataDic!)
and this is my function
func convertToDictionary(text: String) -> [String: AnyObject]? {
if let data = text.data(using: String.Encoding.utf8) {
do {
let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String:AnyObject]
return json
} catch {
print(error.localizedDescription)
}
}
return nil
}
but the problem came if the code have multilines because it's put \n in the return and
it gives me
The data couldn’t be read because it isn’t in the correct format
Error Domain=NSCocoaErrorDomain Code=3840 "Unescaped control character around character 145." UserInfo={NSDebugDescription=Unescaped control character around character 145.}
You should put an extra "\" before "\n", before parsing your JSON. Try using "replacingOccurencesOf" function.
That way your JSON is formatted before parsing.

Convert Dictionary to Base64: error Segmentation fault 11

I am trying to create JSON Web Token using JSONSerialization class, Swift 3 and Xcode 8.1, but my project fails to build with error:
Command failed due to signal: Segmentation fault 11.
Anyone knows why my code is not correct?
If I comment out this code from the project, the project builds.
let customerError = "Custom Error"
enum headerError: Error {
case customerError
}
let headerJWT: [Dictionary] = ["alg":"RS256","typ":"JWT"]
//Convert headerJWT to Data
do {
let headerJWTData: Data = try? JSONSerialization.data(withJSONObject:headerJWT,options: JSONSerialization.WritingOptions.prettyPrinted)
} catch headerError.customerError {
print("could not make data")
}
//Convert headerData to string utf8
do {
let headerJWTString = try String(data: headerJWTData,encoding:String.Encoding.utf8) as! String
} catch {
print("string could not be created")
}
//Convert headerJWTString to base64EncodedString
do {
let headerJWTBase64 = try Data(headerJWTString.utf8).base64EncodedString()
} catch {
"base64 could not be created"
}
Once you create the Data from using JSONSerialization, you simply use the method from Data to get a base64 encoded string.
let headerJWT: [Dictionary] = ["alg":"RS256","typ":"JWT"]
do {
let headerJWTData: Data = try? JSONSerialization.data(withJSONObject:headerJWT,options: JSONSerialization.WritingOptions.prettyPrinted)
let headerJWTBase64 = headerJWTData.base64EncodedString()
} catch headerError.customerError {
print("could not make data")
}
You can pass different options to base64EncodedString() depending on what format you need the base64 string to be in.