I am working with SwiftyJSON which is great. I am however having an issue with storing the JSON(data:) result in a property in my viewController. The standard use of SwiftyJSON works fine.
let json = JSON(data: data)
let name = json[1]["name"].string
My problem occurs when I try to create a property to store the result of JSON(data:)
// Property
var jsonData : JSON?
someMethod()
{
let json = JSON(data: data)
self.jsonData = json
if let name = self.jsonData[1]["name"].string
{
print(name)
}
}
When I do this I get an error on the following line.
if let name = self.jsonData[1]["name"].string
Cannot find member 'string'
Does anyone know why this is?
You are using an optional property.
var jsonData : JSON?
just use
if let name = self.jsonData?[1]["name"].string
in place of
if let name = self.jsonData[1]["name"].string
in your case complier trying to find a property which can be a nil.
Related
What I want to do:
I want to get an array from UserDefaults that I saved beforehand and append a custom object to it. Afterwards I want to encode it as a Data-type again and set this as the UserDefaults Key again.
My problem:
The encoding part is what is not working as intended for me.
It says: -[__SwiftValue encodeWithCoder:]: unrecognized selector sent to instance 0x60000011a540
But I do not know how to fix this.
Below is my code for more context:
do {
let decoded = defaults.object(forKey: "ExArray") as! Data
var exo = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(decoded) as! [Exerc]
exo.append(datas[indexPath.row])
let enco = try NSKeyedArchiver.archivedData(withRootObject: exo, requiringSecureCoding: false) <- Here is the error
defaults.set(enco, forKey: "ExArray")
} catch {
print("Error encoding custom object NOSEARCHO")
}
This is how Exerc looks:
struct Exerc: Codable {
var title: String
var exID: String
}
Seems like you are not using the archiver features, so why don't you just use the codable?
do {
let key = "ExArray"
let decoded = defaults.data(forKey: key)!
var exo = try JSONDecoder().decode([Exerc].self, from: decoded)
exo.append(datas[indexPath.row])
let enco = try JSONEncoder().encode(exo)
defaults.set(enco, forKey: key)
} catch {
print("Error encoding/decoding custom object NOSEARCHO", error)
}
It just a simple refactored MVP of the original code, but you can even work a bit on this and make it human readable right in the plist file!
I'm fairly new to this. Anyway, here we go:
I have JSON data that comes from an API. For the sake of this question, I have simplified it greatly. You can run the following code in a Playground.
import UIKit
struct Book: Codable {
let image: String
}
// this comes from my API
let jsonString = "{ \"image\" = \"someURL\" }"
print(jsonString) // { "image" = "someURL" }
// convert String to Data
let jsonData = jsonString.data(using: .utf8)
// decode data (in my project, I catch the error, of course)
let decoder = JSONDecoder()
let decodingResult = try? decoder.decode(Book.self, from: jsonData!)
print(decodingResult) // nil
As you can see, I'm trying to decode my JSON-String into an Object (my Struct), but the Decoder always returns nil.
Can someone point me in the right direction?
Thank you.
Your current jsonString isn't a proper JSON. Change it to "{ \"image\": \"someURL\" }", and it should work. For more information on JSON syntax, check this manual.
I am attempting to decode my JSON response data from type: AnyObject? back into something that can be printed out in the console / interacted with.
reading back the data, before decoding prints projectName.GameData
Here is the breakdown, data comes back from the response as type: Any? Because it sent up as
class GameData : Codable {
var isPlayerOneTurn: Bool!
var wasCreated: Bool!
var playerOne: String!
var playerTwo: String!
var board: [[Int]]!
init() {
}
}
The current error I am getting when attempting to decode is Cannot convert value of type 'GameData' to expected argument type 'Data'
code :
let decoder = JSONDecoder()
let dataTest = try? decoder.decode(GameData.self, from: data)
Am I missing a correct init() method on the GameData class?
UPDATE:
data was changed to type Data here: thank you #rmaddy for the comment pointing this out.
let data = data as? Data
let decoder = JSONDecoder()
let dataTest = try? decoder.decode(GameData.self, from: data!)
print("data: \(String(describing: dataTest))")
the print line still shows data: Optional(projectName.GameData)
What is wrong here still, not allowing me to view the values of the class GameData?
The print line mentioned in the question, was the value of the game object decode.. That was all XCode would print out - the name of the original object before decoding. Using dataTest.myValue worked when accessing data from the object.
I'm using firebase now and I got stuck with this.
I have a contactList like below.
I want to get the keys (like "-L8per5UdCjQyCBxs5Oo" for the one) but I don't know how to do this.
I tried something like this:
guard let contactList = self.user?.contactList else { return }
print(contactList[0])
And the error message is this.
Cannot subscript a value of type '[String : [String : String]]' with an index of type 'Int'
How can I fix this problem?
Thank you.
var ref:DatabaseReference?
var contactListArray:[DataSnapshot] = [] //you could create an array to save your children
func startListening() {
ref = Database.database().reference().child("contactList")
ref?.observe(.childAdded) {(snapshot) in
self.contactListArray.append(snapshot) // doing this, you can access the first child by contactListArray[0]
// This is how to access info in your snapshot if you need it
let key = snapshot.key //HERE: you'll get the keys
let props = snapshot.value as! Dictionary<String, AnyObject>
let userId = props["userId"] //HERE: how to access to data
}
}
You could iterate through fetched objects via:
for (key, value) in contactList {
///
}
If you want to get the first object, you can write:
contactList.first
I am trying to import Json data from a user uploaded txt file into a standard object that I can use via SwiftyJson framework
Here is the contents of the text fie:
{
"String": "answer",
"String2": "answer2"
}
I have successfully read it and turned it into a String file using:
let openPanel = NSOpenPanel()
let arrayOfExtensions = ["txt"]
openPanel.allowedFileTypes = arrayOfExtensions
let result = openPanel.runModal()
if result == NSFileHandlingPanelCancelButton {
return
}
let fileUrl = openPanel.URL
do {
let stringResult = try String(contentsOfURL: fileUrl!, encoding: NSUTF8StringEncoding)
print (stringResult)
completionhandler(retrievedData: stringResult, error: nil)
I am trying to convert this into a JSON object using:
let jsonFile = JSON(contentsOfFile)
The problem is that the resulting JSON object created appears to be blank for all the fields except rawvalue.
Here is the screenshot from the debug console.
How to I sucessfully read in the string from the file and then make it populate via SwiftJson correctly?
The problem above was that I was using the wrong method to parse it into JSON.
SwiftyJSON seems to be badly documented hence others had a similar problem.
The correct way to do this is to use :
let jsonFile = JSON.parse(string:contentsOfFile)