What is the best way to parse in dictionary? ios7 - parsing

I got 2 types of response:
1.
{ Data = {
color = red;
email = "may#mail.ru";
number = 97;
name = "john";
dadname = "tim";
};
Message = "dada";
Result = OK;
2.
{
Data = "<null>";
Message = "Message";
Result = fail;
}
I need that left part(Data, Message, Result) be a key and right a value. And I also need that Data be a dictionary too. What is the best way to get this?
For request I use AFNetworking 2.0

Related

sending parsed JSON data to views

I'm stuck because I can't send JSON data from URLSession func to views. I read the 90% of previous commends and watch lots of videos but I didn't migrate to my project. Here is my code blocks that I need help ;
This ones my json struct
struct APIResponse: Decodable{
let stocks: [Stocks]
}
struct Stocks: Decodable{
let id: Int
let difference: Float
let bid:Float
let isDown: Bool
let isUp: Bool
let offer: Float
let price: Float
let symbol: String
let volume: Double
}
this one is mine JsonDecode code block;
if let data2 = data2 {
do {
// let json = try JSONSerialization.jsonObject(with: data2, options: [])
let apiResponse = try JSONDecoder().decode(APIResponse.self, from: data2)
print(apiResponse.stocks[2].volume)
DispatchQueue.main.async {
completed()
}
}catch{
print(error)
}
}
}.resume()
when I watch videos about it they were [APIResponse].self but when I try that way my code is failed, in my way json parse is working (I can call like 'apiResponse.stocks[2].id') but I can't send this apiResponse data to views.
example of my JSON file
{
status = {
error = {
code = 0;
message = "";
};
isSuccess = 1;
};
stocks = (
{
bid = "31.5";
difference = "-0.2";
id = 1190;
isDown = 1;
isUp = 0;
offer = "31.6";
price = "31.81";
symbol = "P4jfFAYOTiLEih2Ic+NAkg==";
volume = "801457.5";
},
{
bid = "4.25";
difference = "-0.04";
id = 471;
isDown = 1;
isUp = 0;
offer = "4.26";
price = "4.31";
symbol = "zomIgqEl79jIE+TJ7xV4yQ==";
volume = "349264.21";
},
{
bid = "2.86";
difference = "-0.01";
id = 472;
isDown = 1;
isUp = 0;
offer = "2.87";
price = "2.87";
symbol = "2DlR317+autGo3fiKwNhFA==";
volume = "19279.4";
},
{
bid = 55;
difference = 1;
id = 473;
isDown = 0;
isUp = 1;
offer = "55.25";
price = "56.74";
symbol = "fvo0GQ+pqUmHXwm062Gatw==";
volume = "2647954.25";
}, {
bid = "1.22";
difference = "-0.04";
id = 465;
isDown = 1;
isUp = 0;
offer = "1.23";
price = "1.26";
symbol = "wR/24WChHVRFWZSUW1UdwQ==";
volume = "2206441.67";
}
);
}
First if you want to send your response back to the point from where initiated the API call you need to write completion handler and send your response model with the handler; you can take reference from Closures for Swift.
Also apart from that I noticed few errors in your decodable structure, for example you are expecting 'difference' as float type but the example JSON you have posted contains 'difference' as String and it applies for all your float and double values.
Also it will be a good practice If we will declare all the variable optional in decodable structure as if anytime any parameter won't come in response there won't be any problem in parsing it.

PayUBiz hash integration failed-iOS?

I am calculating hash from server and passed it to payUbiz hash object. When hash value passed to hash object of payUbiz it binds as optional value i.e. Optional(*hashValue*). I have tried to convert optional string to string, but it won't worked. It gives Invalid Parameter error.
Below is my hash value response from server:
{
errorMessage = "Success.";
lastSyncDateTime = "<null>";
result = {
furl = "http://192.168.3.2:93/PayU/AppointmentResponse";
hash = 4875a6096814ee1fbe19110582ea0a1564f81880ae66539b94384d3d332106855a00132332919724f085d02d64cffb6d47ff98f3ac4eb7d5e2bb31b4022e3f06;
merchantKey = gtKFFx;
mobileSDKHASH = 110f85b862578214e5c38637762a6fce9c34bd5e2d78bc34a486f0ee2e3e5d0fada221795de4b67952ec2cff6b4d0fe8877506e7a5480bbdbfdf9045521d8523;
payURequestArea = 1;
profileID = 7;
surl = "http://192.168.3.2:93/PayU/AppointmentResponse";
txnID = 62604613a06163c02ddd;
userID = 18;
vasMobileSDKHASH = 7da0f4fef5bab0e5034f37f9503bdcbede00cc2cd0cf6cbb4e43baa9d57f05680305885199e2b0d38e8cf12895fd06f4d3dd3fb422535feeb555adc58e2cf3cc;
};
statusCode = 200;
}
This is hashvalue printed from payUbiz
paymentHash: Optional("4875a6096814ee1fbe19110582ea0a1564f81880ae66539b94384d3d332106855a00132332919724f085d02d64cffb6d47ff98f3ac4eb7d5e2bb31b4022e3f06")
vasForMobileSDKHash: Optional("7da0f4fef5bab0e5034f37f9503bdcbede00cc2cd0cf6cbb4e43baa9d57f05680305885199e2b0d38e8cf12895fd06f4d3dd3fb422535feeb555adc58e2cf3cc")
paymentRelatedDetailsHash: Optional("110f85b862578214e5c38637762a6fce9c34bd5e2d78bc34a486f0ee2e3e5d0fada221795de4b67952ec2cff6b4d0fe8877506e7a5480bbdbfdf9045521d8523")
Please give solution on this
I have faced same issue a month ago. I think Optional value is not cause of issue. The response itself say's that "Invalid Parameters" means there are some invalid parameters passed to Payment gateway.
Please check following parameters are provided or not:
paymentParam.key = *Your key*;
paymentParam.transactionID = *Transaction ID*
paymentParam.amount = *Amount*
paymentParam.productInfo = *Product Info*;
paymentParam.surl = *Success URL*;
paymentParam.furl = *Failure URL*;
paymentParam.firstName = "";
paymentParam.email = "";
paymentParam.udf1 = "";
paymentParam.udf2 = "";
paymentParam.udf3 = "";
paymentParam.udf4 = "";
paymentParam.udf5 = "";
paymentParam.hashes = hashes; //**Important**
paymentParam.userCredentials = "default"; **//This was the issue in my case, i have accidentally deleted this parameter**
// ENVIRONMENT_TEST for test environment:
paymentParam.environment = ENVIRONMENT_TEST;
// Set this property if you want to give offer:
paymentParam.offerKey = "";
Please check for paymentParam.userCredentials = "default" parameter,
because after adding this parameter i have solved my issue.
Hope this will help you.

Indexing into NSArray with JSON object

I receive an object that is sent as a pointer to a collection.
I can access the fields directly as an NSDictionary.
The emails field is sent as an array, and I receive it in parentheses. Currently I get the emailaddress by what I feel is a roundabout method.
How can I most efficiently get to the email address?
let allDoc = users.allDocuments[0]
print("allDoc: \(allDoc)")
let emailsArray = users.allDocuments[0].valueForKey("emails") as! NSArray
print("emailsArray: \(emailsArray)")
let emailAddress = emailsArray[0]["address"] as! String
print("emailAddress: \(emailAddress)")
Console output:
allDoc: <METDocument key: <collection: users, ID: kzzw3vcqukD62xEyz>, fields: {
emails = (
{
address = "xxxx#gmail.com";
verified = 1;
}
);
profile = {
address = {
city = "";
country = nor;
lineOne = "";
lineTwo = "";
zip = "";
};
card = {
last4 = 4242;
verified = 1;
};
filledOut = 1;
name = {
first = XXXX;
last = XXXX;
};
phone = 9999999999;
validated = 1;
};
}>
emailsArray: (
{
address = "xxxx#gmail.com";
verified = 1;
}
)
emailAddress: xxxx#gmail.com
If you just want the email address you could simply do:
let emailsAddress = users.allDocuments[0]["emails"][0][#"address"] as! String
print("emailAddress: \(emailAddress)")
But it really is better to use multiple lines. It makes the code much easier to read and debug. Also, putting all that onto one line doesn't allow any error checking. What if the #"emails" key has an empty array, for example? The code will crash.

Parse Json using SwiftyJson

I am able to get the entire JSon array parsed. It outputs to console with no issue. I can't seem to get the individual params from the array... my json looks like:
[{
City = NYC;
Device = "<null>";
DisplayAs = "Steve Hutson";
FirstName = Steve;
LastName = Hutson;
MobilePhone = "000-000-0000";
Org = "<null>";
Region = "";
Role = INSPECTOR;
SupervisorID = "73990";
email = "email#email.com";
fLast = shutson;
"gz_modtimestamp" = "2015-07-28 14:42:41";
id = 96;
isActive = YES;
lastupdated = "<null>";
sendemail = 1;
token = "<null>";
userpassword = "xxx";
},{
City = DET;
Device = "<null>";
DisplayAs = "Filipe Washington";
FirstName = Filipe;
LastName = Washington;
MobilePhone = "000-000-0000";
Org = "<null>";
Region = "";
Role = INSPECTOR;
SupervisorID = "6567";
email = "email#email.com";
fLast = shutson;
"gz_modtimestamp" = "2015-07-28 13:02:09";
id = 93;
isActive = YES;
lastupdated = "<null>";
sendemail = 1;
token = "<null>";
userpassword = "xxx";
}]
In my main ViewController.swift file my json request looks like:
var myData:NSData = getJSON("http://xxxx/getusersData.php")
var myDict:NSArray = parseJSON(myData)
println(myDict)
This prints my entire json object which is perfect. However my issue is, how do I get only the FirstName's in an array? By index this works:
println(myDict[0]["FirstName"]) how ever, it only brings back one item.
I am trying to insert specific json items into sqlite which i am using SQLite.swift but i need to know how to retrieve specific item parameters as I would if i was using AJAX.
I am trying to retrieve FirstName, Email and UserPassword info.
Any help would be appreciated.
You can iterate over the JSON object and retrieve that info:
for (index: String, subJson: JSON) in json {
//Do something you want
var firstName = subJson["FirstName"].stringValue
var email = subJson["email"].stringValue
var userPassword = subJson["userpassword"].stringValue
// Build the sqlite query with the variables here
}
As a clarification, you don't access the values directly as in json["FirstName"], you must also use the type functions from SwiftyJSON. In your case they're both strings, so stringValue is used. If you needed and int, it'd be intValue.
There's also the option of just json["FirstName"].string in case the field is optional. Take a look at the readme

NSDictionary annidate in swift

I have this json result.
I would take the field "alert".
I try this:
var alert: NSString = jsonResult["features"]["properties"]["alert"]
but this is the error: does not have a member named 'subscript'.
I can not how to access a field in a nested dictionary
{
features = (
{
geometry = {
coordinates = (
"-97.95359999999999",
"37.2382",
5
);
type = Point;
};
id = usb000si7g;
properties = {
alert = green;
cdi = "5.8";
code = b000si7g;
detail = "http://earthquake.usgs.gov/earthquakes/feed/v1.0/detail/usb000si7g.geojson";
dmin = "0.017";
felt = 1258;
gap = 38;
ids = ",usb000si7g,";
mag = "4.3";
magType = mwr;
mmi = "4.94";
net = us;
nst = "<null>";
place = "8km SE of Harper, Kansas";
rms = "0.51";
sig = 864;
sources = ",us,";
status = reviewed;
time = 1412272884590;
title = "M 4.3 - 8km SE of Harper, Kansas";
tsunami = "<null>";
type = earthquake;
types = ",cap,dyfi,general-link,geoserve,losspager,moment-tensor,nearby-cities,origin,phase-data,shakemap,tectonic-summary,";
tz = "-300";
updated = 1412614943519;
url = "http://earthquake.usgs.gov/earthquakes/eventpage/usb000si7g";
};
type = Feature;
}
);
metadata = {
api = "1.0.13";
count = 1;
generated = 1412617232000;
status = 200;
title = "USGS Significant Earthquakes, Past Week";
url = "http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/significant_week.geojson";
};
type = FeatureCollection;
}
I don't know what to do. swift is changed every beta.
As #Kirsteins said is his answer, you have to do a lot of unwrapping, and it's recommended to use a JSON library.
If you still want to stick with hand made extraction, then I suggest you to made it programmatically, such as adding an extension to NSDictionary as follows:
extension NSDictionary {
func objectForTreeKeys<T>(keys:[String]) -> T? {
var dict: NSDictionary? = self
var retValue: T?
for key in keys {
var value: AnyObject? = dict?.objectForKey(key)
if let unwrapped = value as? NSDictionary {
dict = unwrapped
} else if let unwrapped = value as? T {
retValue = unwrapped
break
} else {
retValue = nil
break
}
}
return retValue
}
}
You pass an array of keys to the function, and it traverses all nested dictionaries until:
a value of type T is encountered
a value having type different than NSDictionary and T is found
a nil value is found
In the first case, it returns the value of T type - in the other cases it returns nil.
You can use it as follows:
let ret: String? = jsonResult.objectForTreeKeys(["features", "properties", "alert"])
As you can see, it's a generic method, and the return type is inferred from the type of the variable the result is assigned to - so it's necessary to explicitly define its type, which must be optional (String? in this specific case).

Resources