JSON dictionary to JSON object in SwiftyJSON - ios

On login, my server returns a user json object if the login was successful. The structure of JSON is as follows:
{
"user" = {
[
user info here
]
}
}
As you can see, it returns the user data inside an array, and unfortunately, this cannot be changed.
I am trying to parse this data in the most efficient way possible with SwiftyJSON, but I've run into a problem. I want to check if there is a "user" key, and if so, parse the JSON object as JSON rather than a dictionary [String: JSON]. However, I can't figure out how to just cast response["user"][0] as a JSON object rather than a dictionary.
if let userInfo = response["user"][0].dictionary {
let user = User.json_decode(userInfo) as! User
User.setUser(user)
success(user: user)
return
}
else {
failure(error: "Username or password was incorrect. Please try again")
}

try this, userinfo is supposed to contain the dictionary
if let user = response["user"].array, userinfo = user[0].dictionary {
println(userinfo)
} else {
failure(error: "Username or password was incorrect. Please try again")
}

Related

use of "po" to get data from server response in console log

i know this is very basic question that i am gonna ask but i need to ask how can i access data which is dictionary that is getting from server.
here is my response
JSON: {
message = "The email must be a valid email address.";}
now i want to do "po" in console log so what to write after in po statement
Thanks
All you need type
po yourResponseAsDictionary["message"]
UPDATED
Sorry I was thinking you already converted it.
If you are not using anything like SwiftyJSON or ObjectMapper to parse your json data then you can do just the following.
But I would recommend to use some lib to convert response directly to your model
let yourResponseFromNetwork = "{ \"country_code\" : \"+9\", \"user_id\" : 123456}"
if let data = yourResponseFromNetwork.data(using: String.Encoding.utf8) {
do {
if let dic = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String:Any] {
let countryCode = dic["country_code"]
let userId = dic["user_id"]
}
} catch {
print("Error occurred")
}
}

Accessing Specific key on Firebase (Swift)

I am trying to update child values within firebase.
User first will create a new order, it creates two nodes, one in the main orders section and second under user to keep clean records. this seem to have worked but I am struggling to update values
then while he is on the form and makes updates, I want firebase to update simultaneously on firebase. How do I access to that specific key as nothing seem to have worked for me when I tried using observe method.
What will be the best way to access that key that the form is on and update values?
This is how you can update values in Firebase:
func updateDatabaseForEdits() {
let updates : [AnyHashable: Any] = ["variableName": value,
"variableName2": value]
ref.child("COrders").child("specificKeyYouWantToEdit").updateChildValues(updates, withCompletionBlock: { (error, success) in
if error != nil {
// upload failed
return
}
else {
// upload worked
// update your locally stored values
}
})
}
There are other issues with you app though. Specifically, how you're storing the data. How do you expect to know which key to access? I recommend you update your data store to be something like this:
desikhanapeena {
COrder {
key123 {
orderInformation
}
}
UserOrders {
uid {
key123
orderInformation
}
}
}
Let me know if you have questions:
If you want to get the key from a snapshot you can do that like this:
for child in snap.children {
let child = child as? DataSnapshot
if let key = child?.key {
// print(key)
}
}
If you want to get the key before you upload you can do that like this:
let key = ref.child("COrders").childByAutoId().key
in case if you are still looking for answer.
Answer for Prob #1.
you need to update order value for user, if it successfull then take parent key (in your case , its AutoID) from there , and using this key, update in "Corders".
here is the code
func updateBothValue(){
let value = ["key":"data","key1": "data2"]
REF.child("Users").child(UID).child("UserCorder").childByAutoId().setValue(value){
error, ref in
guard error == nil else { return }
let key = ref.key
REF.child("Coorders").child(key).setvalue(value)
}
}
for Prob #2, as you written "access that key that the form is on". for each form data , store the key which you get from firebase in previous steps. and use this key for updates.

Swift Unable To Convert NSString To JSON

I am using a WKUserScript for communications between a UIWebView and a server. This particular code will allow user's to search for geographical places. I receive a message back just fine in the function
func userContentController(userContentController: WKUserContentController,
didReceiveScriptMessage message: WKScriptMessage)
The variable message has an AnyObject body. That value I want to convert to a JSONObject so I can access it's contents. Here is the message.body:
{
"status":"OK",
"predictions":[
{
"description":"Dallas, TX, United States",
"id":"fa589a36153613fc17b0ebaebbea7c1e31ca62f0",
"matched_substrings":[{"length":6,"offset":0}],
"place_id":"ChIJS5dFe_cZTIYRj2dH9qSb7Lk",
"reference":"CkQxAAAAJNbPZRkdsyxuKT4FzFmgpBx9HWnZLNhxprRQB0zy62sHCXo3tkHfV_M5dK4Cabp2KL43nIKAAyrv_RI4qbvNfRIQ1dzEGuqywMIAlNg_1AKvoRoUQN32C2uNo4KzZ9j58lB-wjPpjJw",
"terms":[
{"offset":0,"value":"Dallas"},
{"offset":8,"value":"TX"},
{"offset":12,"value":"United States"}
],
"types":["locality","political","geocode"]},
{
"description":"Dallas Athletic Club Drive, Dallas, TX, United States",
"id":"37c4f8d416b9d3975ad57662eb022a0d410e8f76",
"matched_substrings":[{"length":6,"offset":0}],
"place_id":"EjVEYWxsYXMgQXRobGV0aWMgQ2x1YiBEcml2ZSwgRGFsbGFzLCBUWCwgVW5pdGVkIFN0YXRlcw",
"reference":"CkQ5AAAArHSWkIVO6uTH4qE6LxRHshWAfgSnMfxXiBxqf_ZO3O-xQ8RIKKHA9QT7LKwf6Ic788Bzy_I2FpemvcQhE6o5ZRIQ5td4XsjIiyX6D6_dgI3YIxoURu_oROPuOguuorK3Tw11veN7XJI",
"terms":[
{"offset":0,"value":"Dallas Athletic Club Drive"},
{"offset":28,"value":"Dallas"},
{"offset":36,"value":"TX"},
{"offset":40,"value":"United States"}
],
"types":["route","geocode"]
}
]
}
The JSONObject has a status, which lets me know if the results are valid or if an error occurred. I am using SwiftyJSON to create and access my JSONs. I create the JSONObject:
let json = JSON(message.body as! NSString)
and I attempt to access the status key like:
if let status = json["status"].string {
print("status: \(status)")
}
But I am no able to reach the print statement. I have noticed that NSDictionary and JSON have new line characters when you print them out to the console, but I didn't think that would make a difference. Does anyone know why I am unable to retrieve the status variable from the JSON?
You can't initalize a SwiftyJSON object directly with a string, you have to convert this string to data (or use the data you got in the first place if that's the case).
Assuming message.body is a string:
if let dataFromString = message.body.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) {
let json = JSON(data: dataFromString)
if let status = json["status"].string {
print("status: \(status)")
}
}

How can I use swiftyJSON dictionaryValue as a usable string for a UILabel?

I have a makeRequest() method inside a UITableViewController with the following code:
func makeRequest() {
Alamofire.request(.GET, self.foursquareEndpointURL, parameters: [
//"VENUE_ID" : self.foursquareVenueID,
"client_id" : self.foursquareClientID,
"client_secret" : self.foursquareClientSecret,
"v" : "20140806"
])
.responseJSON(options: nil) { (_, _, data, error) -> Void in
if error != nil {
println(error?.localizedDescription)
} else if let data: AnyObject = data {
let jObj = JSON(data)
if let venue = jObj["response"]["venue"].dictionaryValue as [String: JSON]? {
self.responseitems = jObj
println("venue is: \(venue)")
}
dispatch_async(dispatch_get_main_queue()) {
self.tableView.reloadData() // Update UI
}
}
}
}
also keep in mind that I have a property var responseitems:JSON = []
println("venue is: \(venue)") prints a nice looking response to console, so I know that is working correctly...
I also have a custom UITableViewCell class with a bindData() method with the following code:
func bindData() {
println("VenueDetailHeaderCell data did set")
self.venueDetailTitleLabel.text = self.headerInfo?["name"].stringValue
let labelData = self.headerInfo?["name"].stringValue
println("labelData is: \(labelData)")
}
As you can see, I am attempting to set a UILabel's text to the ["name"].stringValue in the JSON response. However, when I println("labelData is: \(labelData)") I get console output of labelData is: Optional("") which is obviously empty.
Here's a screenshot of what I'm trying to grab
What am I doing wrong here and how can I grab the name of the venue and assign my UILabel to it?
UPDATE:
I tried the following code
let labelData = self.headerInfo?["name"].error
println("labelData is: \(labelData)")
And get a console output of: "Error Domain=SwiftyJSONErrorDomain Code=901 "Array[0] failure, It is not an array" UserInfo=0x7fd6d9f7dc10 {NSLocalizedDescription=Array[0] failure, It is not an array}" If that is of use to anyone. I am really confused here... Any ideas?
The problem is that the headerInfo value is an error JSON object, because you're trying to access a dictionary with an integer index.
Note that var responseitems:JSON = [] does not create an array object. SwiftyJSON has auto-assignment-constructors (I'm new to swift, so not sure what the correct swift terminology is)... see this initialiser in the SwiftyJSON.swift source code:
extension JSON: ArrayLiteralConvertible {
public init(arrayLiteral elements: AnyObject...) {
self.init(elements)
}
}
What this means is that when you do var responseitems:JSON = [] you are not creating an array, you are creating a JSON object that is constructed with an empty array using the above init method. Then when you do self.responseitems = jObj you are re-assigning that responseitems variable to a JSON object with a dictionary in it. Therefore self.responseitems[0] is invalid.
Also note that with SwiftyJSON, there is no such thing as an optional JSON object. I notice in your comment you say that you do var headerInfo:JSON? ... - it's not possible to have an optional JSON.
var headerInfo: JSON = nil
The above is possible - this uses another auto-initialiser that initialises a valid JSON object that represents the JSON null value.
So, how to fix it?
When you assign headerInfo do it like this:
let headerInfo = self.responseitems["response"]["venue"]
And now in bindData you can do:
self.venueDetailTitleLabel.text = self.headerInfo["name"].stringValue
Note that all of the above assumes Swift 1.2 and SwiftyJSON >= 2.2 - also after you've understood the above and corrected the issue, you will probably want to refactor the code a bit to reflect the corrected understanding of the data-model.
The way to parse is the next
element: JSONValue //Something with JSONValue
if let title = element["name"]?.string {
cell.title.text = title
}

How can i extract data from an anyObject in Swift

I'm using the TwitterKit SDK and listing a group of Tweets. The function has an error handler that stores any tweets that have been removed by the user and thus not shown. I am attempting to retrieve these particular ID's from the NSError user info dictionary. I can find them but end up with an anyObject.
This code is getting the tweet objects and filtering out the bad ones...
// load tweets with guest login
Twitter.sharedInstance().logInGuestWithCompletion {
(session: TWTRGuestSession!, error: NSError!) in
// Find the tweets with the tweetIDs
Twitter.sharedInstance().APIClient.loadTweetsWithIDs(tweetIDs) {
(twttrs, error) - > Void in
// If there are tweets do something magical
if ((twttrs) != nil) {
// Loop through tweets and do something
for i in twttrs {
// Append the Tweet to the Tweets to display in the table view.
self.tweetsArray.append(i as TWTRTweet)
}
} else {
println(error)
}
println(error)
if let fails: AnyObject = error.userInfo?["TweetsNotLoaded"] {
println(fails)
}
}
}
The println(error) dump is...
Error Domain=TWTRErrorDomain Code=4 "Failed to fetch one or more of the following tweet IDs: 480705559465713666, 489783592151965697." UserInfo=0x8051ab80 {TweetsNotLoaded=(
480705559465713666,
489783592151965697
), NSLocalizedDescription=Failed to fetch one or more of the following tweet IDs: 480705559465713666, 489783592151965697.}
and refining the results from the error "error.userInfo?["TweetsNotLoaded"]" I can end up with...
(
480705559465713666,
489783592151965697
)
My question is, is there a better way to get this data?
If not, how am I able to convert the (data, data) anyObject into an array of [data, data] ?
Best guess is that TweetsNotLoaded is an NSArray of NSNumber (or maybe NSString, not sure how they're coding/storing message ids), so you can cast the result and go from there:
if let tweetsNotLoaded = error.userInfo?["TweetsNotLoaded"] as? [String] {
// here tweets not loaded will be [String], deal with them however
...
}
If that doesn't work, assume they're longs and use:
if let tweetsNotLoaded = error.userInfo?["TweetsNotLoaded"] as? [Int64] {
// here tweets not loaded will be [Int64], deal with them however
...
}

Resources