Storing JSON Dictionary Values into Variables - php

Using a PHP file, I echoed data from a MySQL database in the following format: [{"longitude":"-122.031","latitude":"37.3323”}]
In my Swift file, I use NSJSONSerialization.JSONObjectWithData() to create a JSON dictionary that looks like the following
(
{
latitude = "37.3323";
longitude = "-122.031";
}
)
If I wanted to store the individual dictionary values inside variables, I believe the following snippet of Swift code would work
class Location: NSObject {
var latitude: String?
var longitude: String?
}
var locations = [Location]()
if let locationDictionary = jsonDictionary["coordinates"] as? [String: AnyObject] {
let location = Location()
location.setValuesForKeysWithDictionary(locationDictionary)
print(location.latitude, location.longitude)
}
The only problem I’m having is that I need my JSON dictionary to look like
(
coordinates = {
latitude = "37.3323";
longitude = "-122.031";
}
)
but I don’t know what steps to take to achieve this.

You would have to make your JSON like this:
[{"coordinates":{"longitude":"-122.031","latitude":"37.3323"}}]
which is an array of dictionaries, where each dictionary contains another one.
And here is your code adapted for the new format:
if let json = try? NSJSONSerialization.JSONObjectWithData(data, options: []), // your source may differ, I'm just using this line for my example
content = json as? [[String:AnyObject]] { // the array of dictionaries
for item in content {
if let locationDictionary = item["coordinates"] as? [String: AnyObject] { // the dictionary inside the dictionary
let location = Location()
location.setValuesForKeysWithDictionary(locationDictionary)
print(location.latitude, location.longitude)
}
}
}

Related

Run the same line of code but incrementing the number. Swift, Php

I want to run the same line of code but incrementing the number "prodottiNome_prodotto0" and forKey: ("nome_prodotto0") always.
let prodotti = jsonData.value(forKey: "prodotti") as! NSDictionary
let prodottiNome_prodotto0 = prodotti.value(forKey: "nome_prodotto0") as! String
self.defaultValues.set(prodottiNome_prodotto0, forKey: "nome_prodotto0")
nome_prodotto0 refers to the result of a return in php ------------>
"prodotti":{"nome_prodotto0":"farina","nome_prodotto1":"dfd"}
If I understand what you're asking, your code might look like this:
let max = 50 //Or whatever limit you want to use
for i in 0...max {
let key = "nome_prodotto" + String(i)
//Use `if let` so you don't crash if a value is not a string
//Don't use `value(forKey:)` on a dictionary. That's a KVO method
if let value = prodotti[key] as? String {
self.defaultValues.set(value, forKey: key)
{
}

swift 3 json not working

I'm working on a database connection between Swift 3 and a php file.
Sending information to the php will be correctly transfered into the database.
But I'm having an issue when I want to print information from the database into my xcode.
I'm sending this json to my app:
[{"latitude":"51.430536341034","longitude":"5.45947450542819"},
{"latitude":"51.4305299243587","longitude":"5.45964865535365"},
{"latitude":"51.4305299243587","longitude":"5.45964865535365"},
{"latitude":"51.4305299243587","longitude":"5.45964865535365"},
{"latitude":"51.4305299243587","longitude":"5.45964865535365"}]
I printed this JSON in xcode with:
print(NSString(data: data!, encoding: String.Encoding.utf8.rawValue)!)
I tried 2 options that were described in other topics at this site, which both were about swift 3 and json problems.
Option 1:
let parsedData = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! [String:AnyObject]
When I ran the app, there come's an error:
Signal SGBRT Could not cast value of type '__NSArrayI' (0x1b2a89cc8) to 'NSDictionary' (0x1b2a8a128).
Option 2:
let parsedData = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! Dictionary<String, AnyObject>
What happens is the same Signal SGBRT with error:
Could not cast value of type '__NSArrayI' (0x1b2a89cc8) to 'NSDictionary' (0x1b2a8a128).
I need to say that I'm not a professional, but I'm a hard learning student with no connections that also program swift. Therefore I hope to get some help here, to finish this function of the app.
If you answer the topic, I would be glad to here some other codes I should try.
Thank you.
From your JSON response that you have added in question, if that was the only response that you need to use [[String: String]] instead of [[String: AnyObject]] because using AnyObject you need to first convert it to String then double, so it is batter if you use [[String: String]]. Now you have array of dictionary so get all coordinates like this way.
let parsedData = try? JSONSerialization.jsonObject(with: data!, options: []) as! [[String:String]]
for dic in parsedData {
if let lat = Double(dic["latitude"]), let long = Double(dic["longitude"]) {
print(lat)
print(long)
}
}
Your JSON clearly says that it is an array of dictionaries, so you should cast it to an array of dictionaries [[String: AnyObject]]. Already mentioned in comments. Try below, it might help you:
//First you should check for data whether it has value
if let data = data {
//This gives you an array of dictionaries as per your JSON data. So safer side try to 'guard let' it so that it should not crash if your JSON data is nil
guard let parsedDataArray = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [[String: AnyObject]] else { return }
//Here you can enumerate through your array to get each dictionary
for parsedDict in parsedDataArray {
//This gives the value of latitude
if let latitude = parsedDict["latitude"] {
print(latitude)
}
//And this is for "longitude"
if let longitude = parsedDict["longitude"] {
print(longitude)
}
}
}

How to crypt string to sha1 in base64 with Swift?

I want to crypt privateKey & publicKey to sha1 in base64 with Swift, but the output is not the one I see in PHP urlencode base64_encode which I tried in Codecademy:"https://www.codecademy.com/courses/web-beginner-en-StaFQ/0/3?curriculum_id=5124ef4c78d510dd89003eb8".
Pls see the following codes in Swift and Codecademy:
Swift:
//pls see func dataFromHexadecimalString() details here "http://stackoverflow.com/questions/26501276/convert-string-to-hex-string-in-swift/26502285#26502285"
extension String {
func dataFromHexadecimalString() -> NSData? {
let trimmedString = self.stringByTrimmingCharactersInSet(NSCharacterSet(charactersInString: "<> ")).stringByReplacingOccurrencesOfString(" ", withString: "")
var error: NSError?
let regex = NSRegularExpression(pattern: "^[0-9a-f]*$", options: .CaseInsensitive, error: &error)
let found = regex?.firstMatchInString(trimmedString, options: nil, range: NSMakeRange(0, count(trimmedString)))
if found == nil || found?.range.location == NSNotFound || count(trimmedString) % 2 != 0 {
return nil
}
let data = NSMutableData(capacity: count(trimmedString) / 2)
for var index = trimmedString.startIndex; index < trimmedString.endIndex; index = index.successor().successor() {
let byteString = trimmedString.substringWithRange(Range<String.Index>(start: index, end: index.successor().successor()))
let num = UInt8(byteString.withCString { strtoul($0, nil, 16) })
data?.appendBytes([num] as [UInt8], length: 1)
}
return data
}
}
func URLEcodekey() -> String {
let appid="a1b2c34d5e"
let privateKey="ef7d6s0d"
let areaid="101020900"
let time="201507191254"
let publicKey="http://open.weather.com.cn/data/?areaid=\(areaid)&type=forecast_v&date=\(time)&appid=\(appid)"
let cPrivateKey=privateKey.dataUsingEncoding(NSUTF8StringEncoding)!
let cPublicKey=publicKey.dataUsingEncoding(NSUTF8StringEncoding)!
var cHMAC = [CUnsignedChar](count: Int(CC_SHA1_DIGEST_LENGTH), repeatedValue: 0)
CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA1), cPublicKey.bytes, Int(cPublicKey.length), cPrivateKey.bytes, Int(cPrivateKey.length), &cHMAC)
let hexKeyString=NSMutableString(capacity: Int(CC_SHA1_DIGEST_LENGTH))
for byte in cHMAC{
hexKeyString.appendFormat("%02hhx", byte)
}
println("hexKeyString:\(encryptedKey)")
let binaryData = hexKeyString.dataFromHexadecimalString()
let base64String = binaryData?.base64EncodedStringWithOptions(nil)
println("base64String:\(base64String)")
var urlEncodeKey=base64String!.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())!
println("urlEncodeKey:\(urlEncodeKey)")
return urlEncodeMessage
}
the outputs are:
hexKeyString:d4433d42b1505c00a4aa80205171d0d04754d254
base64String:1EM9QrFQXACkqoAgUXHQ0EdU0lQ=
urlEncodeKey:1EM9QrFQXACkqoAgUXHQ0EdU0lQ=
PHP in Codecademy:
echo urlencode(base64_encode(hash_hmac('sha1', " http://open.weather.com.cn/data/?areaid=101020900&type=forecast_v&date=201507191254&appid=a1b2c34d5e", "ef7d6s0d", TRUE)));
the output is:
A5O59Y%2BFbGjhVwaI9JNB7DkcX%2F4%3D // the output is much like the
example in API, which I think maybe the right one.
So, how can I receive the right urlEncodeKey for my privateKey & publicKey like in PHP?
Thank you very much in advance!
You should read more about cryptography and hashing. In your case, there's no public key, private key, ... SHA stands for Secure hash algorithm and what you're trying to get is Hash based authentication code. Check Wikipedia articles about HMAC, SHA-1, Public key, ... I strongly recommend to read more about it otherwise you can create more damage if you misunderstand it.
Back to your problem. It's in one character:
Swift code - let publicKey="http://open.weather.com.cn...
PHP code - hash_hmac('sha1', " http://open.weather.com.cn...
Do you see where the problem is? In your PHP code, there's one space character just before http. This character is not in your Swift code.
Honestly, I didn't check your whole code, because I don't know why you're trying to convert it from hexadecimal string, etc. Used some parts only and rewrote it from scratch for you. Here's working example:
func URLEncodedKey() -> String? {
let appid = "a1b2c34d5e"
let time = "201507191254"
let areaid = "101020900"
let key = "ef7d6s0d"
let string = " http://open.weather.com.cn/data/?areaid=\(areaid)&type=forecast_v&date=\(time)&appid=\(appid)"
// ^ <- in your PHP example, there's space
guard let keyData = key.dataUsingEncoding(NSUTF8StringEncoding),
stringData = string.dataUsingEncoding(NSUTF8StringEncoding),
outputData = NSMutableData(length: Int(CC_SHA1_DIGEST_LENGTH)) else {
return nil
}
outputData.length = Int(CC_SHA1_DIGEST_LENGTH)
CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA1),
keyData.bytes, keyData.length,
stringData.bytes, stringData.length,
outputData.mutableBytes)
return outputData
.base64EncodedStringWithOptions([])
.stringByAddingPercentEncodingWithAllowedCharacters(.URLQueryAllowedCharacterSet())
}
Return value is:
`Optional("A5O59Y+FbGjhVwaI9JNB7DkcX/4=")`
Which is what you get when you decode your PHP output.
Just replace URLQueryAllowedCharacterSet with any of the following character sets:
class func URLUserAllowedCharacterSet() -> NSCharacterSet
class func URLPasswordAllowedCharacterSet() -> NSCharacterSet
class func URLHostAllowedCharacterSet() -> NSCharacterSet
class func URLPathAllowedCharacterSet() -> NSCharacterSet
class func URLQueryAllowedCharacterSet() -> NSCharacterSet
class func URLFragmentAllowedCharacterSet() -> NSCharacterSet
Depends on your use case. IOW in which part of the URL your would like to use it.

Pass string with ampersand (&) from iOS to PHP/MySQL with NSURLSession

I'm passing a large set of strings to my server from iOS (Swift) to a PHP file via POST. Unfortunately, if a user places an ampersand (&) in a field, the rest of the field is lost. I understand why (& signifies the next field in the message) but I'm not sure how to fix.
func UploadToSql(plan: LessonPlan, isNew: Bool, callBack: ((data: NSData!, response: NSURLResponse!, error: NSError!) -> Void)?) {
let url = NSURL(string: "https://myserver.com/receive.php")!
var request:NSMutableURLRequest = NSMutableURLRequest(URL:url)
var bodyData = "Author=\(plan.author)&title=\(plan.title)&grade=\(plan.grade)&date=\"\(plan.date)\"&element1=\(plan.element1)&objective1=\(convertedFields[0])&element2=\(plan.element2)&objective2=\(convertedFields[1])&element3=\(plan.element3)&objective3=\(convertedFields[2])&coreProcess1=\(plan.coreProcess1)&coreStrand1=\(plan.coreStrand1)&coreStandard1=\(plan.coreStandard1)&coreProcess2=\(plan.coreProcess2)&coreStrand2=\(plan.coreStrand2)&coreStandard2=\(plan.coreStandard2)&coreProcess3=\(plan.coreProcess3)&coreStrand3=\(plan.coreStrand3)&coreStandard3=\(plan.coreStandard3)&media1=\(plan.media1)&media2=\(plan.media2)&media3=\(plan.media3)&media4=\(plan.media4)&media5=\(plan.media5)&media6=\(plan.media6)&repertoire1=\(convertedFields[3])&repertoire2=\(convertedFields[4])&repertoire3=\(convertedFields[5])&process=\(convertedFields[6])&assessment=\(convertedFields[7])&stateCat1=\(plan.stateCat1)&stateCat2=\(plan.stateCat2)&stateCat3=\(plan.stateCat3)&stateStand1=\(plan.stateStand1)&stateStand2=\(plan.stateStand2)&stateStand3=\(plan.stateStand3)&comment=\(plan.comment)&shared=\(sharedInt!)&authorName=\(plan.authorName)" + planID
request.HTTPMethod = "POST"
request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if error != nil {
println("error=\(error)")
return
}
println("response = \(response)")
callBack?(data: data, response: response, error: error)
return
}
task.resume()
}
Typically for a webrequest like that it uses % followed by the ascii hex value. The hex value for & is 26, so it would be %26
google.com/#q=red%26white is example of a google search for red&white, which uses that replacement
Its called URL encoding or percent encoding and here is another question with an answer on how to do more broad URL encoding: stackoverflow.com/questions/24551816/swift-encode-url
Note that you would have to URL encode each element you were interpolating into the string, not the whole result string, as you want to keep your &'s that separate parameters.
This one is working for me. I am also using PHP/MySQL with NSURLSession.
func stringByAddingPercentEncodingForFormData(plusForSpace: Bool=false) -> String? {
let unreserved = "*-._"
let allowed = NSMutableCharacterSet.alphanumericCharacterSet()
allowed.addCharactersInString(unreserved)
if plusForSpace {
allowed.addCharactersInString(" ")
}
var encoded = stringByAddingPercentEncodingWithAllowedCharacters(allowed)
if plusForSpace {
encoded = encoded?.stringByReplacingOccurrencesOfString(" ",
withString: "+")
}
return encoded
}
Found above function from this link: http://useyourloaf.com/blog/how-to-percent-encode-a-url-string/.

Communication between Javascript and MYSQL

I am working on some code using Google Maps API. To sum up shortly, I have MySQL database with a table of information used to generate markers on the map. I connected to the database and am using PHP to draw out the necessary attributes and communicate with my Javascript code using XML.
What I'm currently attempting to do is go in the other direction, I'm trying to send a string of information (for example "1,2,3,45,18") from my Javascript code to MySQL to be set as a session parameter (call it #sparam). What is the process behind passing this value to MySQL?
Would I be able to access a MySQL variable through PHP in the same way I can access tables (for the purpose of getting a value back into Javascript)?
I'd appreciate any insight.
Thanks.
EDIT
Maybe I was unclear in my original post. What I'm asking is how would I be able to pass a string to a MySQL session variable, specifically a set of IDs directly related to the IDs in the table of the MySQL database, and then be able to work with these IDs by calling the necessary procedures in MySQL. In turn, the procedures called in MySQL would generate some output, which would then have to be passed back to the Javascript code.
I created a special JSON (JavaScript Object Notation) php pages that I would call from javascript. Then I would parse those JSON responses.
Simple example:
JAVASCRIPT:
function getCheckedUnits() {
jQuery(function($) {
$.ajax( {
url : "page_json.php?action=getsession",
type : "GET",
success : function(data) {
//Get Json and loop over it's data
if (data.length>10){
var jsonData = JSON.parse(data);
$.each(jsonData, function(Idx, Value) {
if (Idx>0){
//get values for each vehicle and then remove it's marker from the map and then add new marker on the map (thereofore update the marker)
c_latitude = Value["lat"];
c_longitude = Value["lon"];
c_name = Value["name"];
c_notes= Value["notes"];
removeMarker(c_name); //remove old marker function
addMarker(c_latitude, c_longitude, c_name); //add current marker function
}
});
}
}
});
});
}
PHP: Here I loop over my arrayList and then create a simple array with values. Then I just output it as a json string
foreach ($listOfCars->arrayList as $key => $value) {
$unit = new fleetUnit();
$unit = $value;
//create array for json output
$data[] = array('lat' => $unit->lat,
'lon' => $unit->lon, 'name' => $unit->name, 'notes' => $unit->notes);
}
echo json_encode($data);

Categories