Please guys i need to parse a string to look like these in swift
"[{"question":9, "answer":25}", "question\":10, "answer":27}]"
where the index and value are dynamically gotten from a loop. I was able to get to these
["{\"question\":9, \"answer\":25}", "{\"question\":10, \"answer\":27}", "{\"question\":11, \"answer\":29}", "{\"question\":12, \"answer\":33}", "{\"question\":13, \"answer\":37}"]
so i have tried this
for i in 0..<answersForQuestionInPage.count{
let questions = answersForQuestionInPage[i] as Answer
do {
let data = try JSONEncoder().encode(questions)
// 2
let string = String(data: data, encoding: .utf8)!
answers.append(string)
print("This is the main value \(string)")
} catch{
}
}
this still gives me an array with this format
["{\"question\":9, \"answer\":25}", "{\"question\":10,
\"answer\":27}", "{\"question\":11, \"answer\":29}",
"{\"question\":12, \"answer\":33}", "{\"question\":13,
\"answer\":37}"]
with the object
"{\"question\":9, \"answer\":25}"
still wrapped in a string liteal " " what i want is for this return array to be in this format
[{"question":9, "answer":25}, {"question":10,
"answer":27}, {"question":11, "answer":29},
"{"question":12, "answer":33}, {"question":13,
"answer":37}]
I didn't understand the whole thing, but you said you need to parse the String, but I think you meant JSON. So, you can do it like this and get the values. Do let me know if it is what you needed, otherwise please add clarity in your question and I will edit and update my answer accordingly.
struct Quiz: Decodable {
let question, answer: Int
}
private func fetchQuizzes() {
//After getting the data from API, you can do this
guard let quiz = try? JSONDecoder().decode([Quiz].self,from: data) else { print("Unable to parse"); return }
print(quiz)
print(quiz.first?.answer) //First Answer
}
Just like Rob said before, you have a JSON here.
Using Robs code you decode the given JSON and create an array of Quiz objects (Robs struct).
You can now work with that array and transform it to your needs.
Related
I'm a little stuck with something small but that is giving me some headaches! I have a Realtime Database and I am able to retrieve the information I need from it. My only problem is that instead of printing for example (ex.: 200) is printing (ex.: [200])!
This is my code:
func readData() {
FirebaseDatabase.Database.database().reference().child("Available_Funds").observeSingleEvent(of: .value, with: { snapshot in
guard let value = snapshot.value as? [String: Any] else {
return
}
let amountWallet = value.values
print(amountWallet)
self.currentBalanceLabel.text = "$" + "\(amountWallet)"
print("\(value)")
})
}
Right now what I get printed with this code is $[200] for example, instead of just $200, which is what I intend to get.
Tried looking online, but no luck with this! Does someone know how to remove these square brackets from printing?
values is an Array -- thus the []. When you say value.values, you're asking for all of the values of the key/value pairs in snapshot.value.
If you intend to get a single value from it, you would use amountWallet[0] to get the first element. Keep in mind that this will crash if amountWallet has 0 elements (arrays are zero indexed).
amountWallet.first will give you an Optional that will be safe to use, but you would need to unwrap it for printing:
let amountWallet = value.values
if let singleAmount = amountWallet.first {
print(singleAmount)
self.currentBalanceLabel.text = "$" + "\(singleAmount)"
}
You're calling it back as an array of strings [String: Any]
You can either change this (remove []) or access the first element in the array: amountWallet[0].
In Swift, to retrieve an array from Firestore I use:
currentDocument.getDocument { (document, error) in
if let document = document, document.exists {
let people = document.data()!["people"]
print(people!)
} else {
print("Document does not exist")
}
}
And I receive data that looks like this
(
{
name = "Bob";
age = 24;
}
)
However, if I were to retrieve the name alone, normally I'd do print(document.data()!["people"][0]["name"]).
But the response I get is Value of type 'Any' has no subscripts
How do I access the name key inside that object inside the people array?
The value returned by document.data()!["people"] is of type Any and you can't access [0] on Any.
You'll first need to cast the result to an array, and then get the first item. While I'm not a Swift expert, it should be something like this:
let people = document.data()!["people"]! as [Any]
print(people[0])
A better way of writing #Frank van Puffelen's answer would be:
currentDocument.getDocument { document, error in
guard error == nil, let document = document, document.exists, let people = document.get("people") as? [Any] else { return }
print(people)
}
}
The second line may be a little long, but it guards against every error possible.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I want to get the value of NSArray, but it always gives me nil value, Anyone knows how to solve it?
it is created by swift 4.2
KCNetWorkTool.tool.getRecordListWith(UserID: userID, Date: dateLabel.text!) { (result) in
SVProgressHUD.dismiss()
if let dict = result.data as NSDictionary? {
// the value of this below line, i cann't get . array always return nil
if let array = (dict["list"] as? NSMutableArray) {
let countArray = array.count
for index in 0..<countArray {
if let dictNew = array[index] as? NSDictionary {
let row = EnvelopeModel(dictionary: dictNew)
self.recordModel.append(row)
}
}
}
}
self.recordTable.reloadData()
}
}
Most of your code is unnecessary. Mostly, you don't need to be casting to Objective-C types for arrays and dictionaries. So you need something like this:
KCNetWorkTool.tool.getRecordListWith(UserID: userID, Date: dateLabel.text!) { (result) in
SVProgressHUD.dismiss()
if let envelopes = result.data["list"] as? [[String: Any?]] {
self.recordModel.append(envelopes.forEach { EnvelopeModel(dictionary: $0) })
}
self.recordTable.reloadData()
}
Haven't checked that in a compiler, but something like that.
Well actually you need to understand the basic structure of json copy and past your json string to a json formatter online tool and,
check from root key to end key. Try to unwrap the value from result. debug properly.
On second chance you are converting direct Data to [String : Any]. What Api calling tool you are using Alamofire or other library.
you can use JsonDecoder class to convert Data to your model class which is nativ tool in iOS.
Make your json to a structs and with root struct you can parse Data to whole model structured data.
struct Root<T> : Codable
{
var yourRootKey: T?
}
struct Price : Codable
{
var yoursubKey: Double?
}
Pass in decoder like Root<Price>.self
do{
let response = try JsonDecoder().decode(Root<Price>.self, for : result.data)
}catch let error{
print(error.localizedDescription)
}
I need to send an array through HTTP to my swift client but I'm not sure how to convert the bytes I've received to a swift array.
I've looked it up on google multiple times with multiple different ways of saying what I'm trying to do but all I'm getting is topics that say "convert byte array to swift string"
AF.request(exampleUrl).response { response in
if let data = response.data, let s = String(data: data, encoding: .utf8) {
debugPrint(s)
let myArray = decodeSomehow(data: data)
debugPrint(myArray[0]) // hooray
}
}
I need to be able to decode arrays sent from my server but my efforts to find the solution to this problem have yielded no results.
btw server is made with firebase functions and is run on Google frontend
and coded with typescript
also to clarify I do not want to take the bytes and put them into an array, I want to decode the bytes into what they originally were on the server aka an array (originally a typescript array but if it is possible to make it a swift array that would be 👌)
The Data class is an advance version of [UInt8]. Normally, working directly with Data class is recommended. If you really want to convert it to [UInt8], simply
let arr = [UInt8](data)
or
let arr = Array(data)
Hope it helps... (Thanks LEO for your best Comment)
let string = "Hello World"
print(Array(string.utf8))
I figured out how to do what I was trying to do...
In the end, I solved my own problem lol
all I needed to do was decode it with swiftyjson
thank you all for your answers
AF.request(exampleUrl).response { response in
if let data = response.data, let s = String(data: data, encoding: .utf8) {
let arr = JSON(data)
debugPrint(arr)
debugPrint(arr[0][0])
debugPrint(s)
}
}
output
API gives me back a variable that has type Any. It looks like this when I print it.
{
"sender" : "Kira",
"created" : "08.05.2018",
"text" : "Cncncm"
}
I tried to use SwiftyJSON to cast it like this let mydata = JSON(data) but it failes. I tried to use Swift 4 decoding technique but that failed as well. I tried to do this let myData = data as? Dictionary<String, String> but it fails again.
I am clueless what to do here. Any tips or solutions?
Finally a chance to demonstrate one of the Codable protocols hidden gems. Please run the following in a Playground:
import Cocoa
let jsonData = """
{
"sender" : "Kira",
"created" : "08.05.2018",
"text" : "Cncncm"
}
""".data(using: .utf8)!
struct SenderText: Codable {
let sender: String
let created: Date
let text: String
}
let dayFormatter = DateFormatter()
dayFormatter.dateFormat = "dd.MM.yyyy"
let date = dayFormatter.date(from:"08.05.2018")
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(dayFormatter)
do {
let sendText = try decoder.decode(SenderText.self, from: jsonData)
print(sendText)
} catch {
print(error)
}
The sheer elegance of how easy it is to define such an intricate parser mapping a messy JSON-string to your favourite struct will hardly ever stop to amaze me. No matter how weird your date format looks, it is hardly more than 3 lines away from being parsed during the process.
There is something in regard to casting you should note though: In Swift, as in most object oriented languages, you can only cast something to something else if (and only if) it already is something else in the first place (but that knowledge has been lost somewhere). Since your String is "just" a String (in disguise of an Any maybe) you won't be able to cast it to anything else. However the Codable protocol provides you with a terrific means to decode from the Strings Data with astonishing ease. This process should not be mistaken as a cast, even if it looks largely the same. It is the creation and initialisation of another, more fittingly structured object from a simple piece of Data that you are likely to have gotten from your average web service of choice.
Great so far, at least in my book.
You can parse it like this as it's a json string
let trd = yourVar as? String
if let data = trd?.data(using: String.Encoding.utf8) {
do {
var content = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String:String]
print(content)
}
catch let error as NSError {
print(error)
}
}