Representing JSON Data in the Form of Swift Dictionaries

The project which I’m currently working on involves working with a lot of JSON data in an iOS mobile app which I plan on sending to a database using the Alamofire http networking library/wrapper. When working with JSON in Swift using Alamofire, you need to create your JSON objects in the form of Swift Dictionaries. This has been pretty confusing for me, so I wanted to whip up this quick blog post for my own personal reference demonstrating how to represent JSON data in the form of a Swift Dictionary so that it can later be sent over the internet to a backend server using Alamofire:
exampledata.json

{
    "location": [
        {
            "latitude": 30.00000001,
            "longitude": 30.0000005,
            "timestamp": 2342342342
        },
        {
            "latitude": 30.00000029,
            "longitude": 30.00000023,
            "timestamp": 2342342343
        }
    ],
    "altitude": [
        {
            "pressure": 90.00000001,
            "timestamp": 2342342345
        },
        {
            "pressure": 91.00000029,
            "timestamp": 2342342347
        }
    ]
}

 
exampledictionary.swift

import Foundation
// REFERENCE: https://dzone.com/articles/all-you-need-to-know-about-json-with-swift
var myDictionary = [
    "location": [
        [
            "latitude": 30.00000001,
            "longitude": 30.0000005,
            "timestamp": 2342342342
        ],
        [
            "latitude": 30.00000029,
            "longitude": 30.00000023,
            "timestamp": 2342342343
        ]
    ],
    "altitude": [
        [
            "pressure": 90.00000001,
            "timestamp": 2342342345
        ],
        [
            "pressure": 91.00000029,
            "timestamp": 2342342347
        ]
    ]
] as [String:Any]
print(myDictionary)

 
REFERENCE: All You Need to Know About JSON With Swift

 

Working with JSON in PHP: Accessing Array Items

This afternoon I spent a little time playing around with JSON & PHP using repl.it so that I can figure out how to build the next part of my WingsuitGP app. For this app I’m sending a fairly large amount of JSON data from an iPhone app back to a server running PHP, and need to parse all of the JSON data so that I can stick it in a MySQL database for further analysis. Not sure if this will be of any use to anyone other than myself, but here is what I have so far:

$rawJSON = '
{
    "location": [
        {
            "latitude": 30.00000001,
            "longitude": 30.0000005,
            "timestamp": 2342342342
        },
        {
            "latitude": 30.00000029,
            "longitude": 30.00000023,
            "timestamp": 2342342343
        }
    ],
    "altitude": [
        {
            "pressure": 90.00000001,
            "timestamp": 2342342345
        },
        {
            "pressure": 91.00000029,
            "timestamp": 2342342347
        }
    ]
}
';
$decodedJSON = json_decode($rawJSON);
$latitude[0] = $decodedJSON->{'location'}[0]->{'latitude'};
$longitude[0] = $decodedJSON->{'location'}[0]->{'longitude'};
$locationTimestamp[0] = $decodedJSON->{'location'}[0]->{'timestamp'};
$latitude[1] = $decodedJSON->{'location'}[1]->{'latitude'};
$longitude[1] = $decodedJSON->{'location'}[1]->{'longitude'};
$locationTimestamp[1] = $decodedJSON->{'location'}[1]->{'timestamp'};
$altitude[0] = $decodedJSON->{'altitude'}[0]->{'pressure'};
$altitudeTimestamp[0] = $decodedJSON->{'altitude'}[0]->{'timestamp'};
$altitude[1] = $decodedJSON->{'altitude'}[1]->{'pressure'};
$altitudeTimestamp[1] = $decodedJSON->{'altitude'}[1]->{'timestamp'};
echo "\n";
echo "Latitude Point 0: {$latitude[0]}" . "\n";
echo "Longitude Point 0: {$longitude[0]}" . "\n";
echo "Location Timestamp 0: {$locationTimestamp[0]}" . "\n";
echo "\n";
echo "Latitude Point 1: {$latitude[1]}" . "\n";
echo "Longitude Point 1: {$longitude[1]}" . "\n";
echo "Location Timestamp 1: {$locationTimestamp[1]}" . "\n";
echo "\n";
echo "Altitude Reading 0: {$altitude[0]}" . "\n";
echo "Altitude Timestamp 0: {$altitudeTimestamp[0]}" . "\n";
echo "\n";
echo "Altitude Reading 1: {$altitude[1]}" . "\n";
echo "Altitude Timestamp 1: {$altitudeTimestamp[1]}" . "\n";
echo "\n";

 

Swift Objects, JSON, & Making HTTP POST Requests with Alamofire

This blog post is brought to you by the developer of BitBudget. BitBudget is an automated budgeting app for Android and iOS which syncs with your bank account and helps you avoid overspending. If you’d like to quit living paycheck-to-paycheck and get a better handle on your finances, download it today! https://bitbudget.io

Another little note to self tonight, this time regarding how to convert swift objects to JSON in order to make HTTP POST requests using the Alamofire networking library/wrapper: When making HTTP POST requests using the JSON data format with Alamofire, you actually need to turn your swift objects into dictionaries, then you can pass the dictionary to Alamofire and it will handle converting your dictionary into JSON. I was under the assumption that you could just pass Alamofire an object since JSON stands for JavaScript Object Notation and not JavaScript Dictionary Notation, but Alamofire apparently wants a dictionary. This didn’t really seem obvious to me so… that’s why I’m making note of this here on my dev-blog. And here is a link to the original StackOverflow where I found the answer to this question: [Send] Object as Parameter using Alamofire
Note, while the code example below does work, there is a small bug involving the forced unwrapping of an optional that I should not have unwrapped. However, for demonstration/reference purposes, I think it’s a pretty good example (Also, you will need to make sure to add a little XML to your Info.plist if you would like to use HTTP instead of HTTPS):

//
//  ViewController.swift
//  NetworkingWithJSON
//
//  Created by Christopher Pedersen on 3/1/19.
//  Copyright © 2019 Christopher Pedersen. All rights reserved.
//
import UIKit
import Alamofire
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }
    @IBAction func onPostJsonButtonClicked(_ sender: Any) {
        let exampleObject = ExampleClass()
        let exampleDictionary: [String:String] = [
            "id_column": "\(exampleObject.firstExampleProperty)",
            "mediumtext_column": "\(exampleObject.secondExampleProperty)"
        ]
        let parameters = exampleDictionary
        Alamofire.request("http://wingsuitgp.com/networkingwithjson.php", method: .post, parameters: parameters, encoding: JSONEncoding.default).response { response in
            print("Request: \(response.request!)")
            print("Request \(response.response!)")
            print("Error: \(response.error!)")
            if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
                print("Data: \(utf8Text)")
            }
        }
    }
}


//
//  ExampleClass.swift
//  NetworkingWithJSON
//
//  Created by Christopher Pedersen on 3/1/19.
//  Copyright © 2019 Christopher Pedersen. All rights reserved.
//
import Foundation
class ExampleClass {
    var firstExampleProperty: String = "ObjectConvertedToDictConvertedToJSON"
    var secondExampleProperty: String = "AlamofireSaysHello"
}

 

POST JSON Data with AJAX to a Server Running PHP

Over the past couple days I’ve been messing around with sending JSON data back and forth between a web/mobile client and a server running PHP. Here are two little scripts demonstrating how to POST JSON data to a server running PHP with AJAX:
1) sendjson.html
2) receivejson.php

 

Receiving JSON Data via HTTP POST with PHP

This blog post is brought to you by the developer of BitBudget. BitBudget is an automated budgeting app for Android and iOS which syncs with your bank account and helps you avoid overspending. If you’d like to quit living paycheck-to-paycheck and get a better handle on your finances, download it today! https://bitbudget.io

If you happen to follow my blog you know that I’ve been working on this new app called WingsuitGP (Air Races Powered by iPhone). Yesterday while working on the app I found myself a little stumped having to do something I’ve never done before… how do I receive JSON data via HTTP POST with PHP?

In the past I’ve used PHP many times to spit out JSON data back to a web or mobile app. But with WingsuitGP I’m having to do the opposite. The mobile app is the one spitting out the JSON, and the backend PHP script is on the receiving end of these data. So I just wanted to sort of bookmark this cool blog post I found from thisinterestsme.com on how to go about doing this: Receiving JSON POST data via PHP

UPDATE
I found another excellent post on StackOverflow.com: Receive JSON POST with PHP

Also, here is an example demonstrating how to send JSON data via HTTP POST using client-side JavaScript: What is the way to send a JSON object via a POST request in JavaScript (not jQuery or Nodejs)?

 

How to Dismiss the Keyboard in iOS

This blog post is brought to you by the developer of BitBudget. BitBudget is an automated budgeting app for Android and iOS which syncs with your bank account and helps you avoid overspending. If you’d like to quit living paycheck-to-paycheck and get a better handle on your finances, download it today! https://bitbudget.io

First, drag the ‘Tap Gesture Recognizer’ from Object Library onto Background. Then control-drag from ‘Tap Gesture Recognizer’ to ViewController.swift to add the dismissKeyboard() @IBAction. And last, call the resignFirstResponder() method from within the dismissKeyboard function to then dismiss the keyboard.

@IBAction func dismissKeyboard(_ sender: UITapGestureRecognizer) {
mySuperSweetTextField.resignFirstResponder()
}
 

No such module 'Alamofire'

This blog post is brought to you by the developer of BitBudget. BitBudget is an automated budgeting app for Android and iOS which syncs with your bank account and helps you avoid overspending. If you’d like to quit living paycheck-to-paycheck and get a better handle on your finances, download it today! https://bitbudget.io

Ran into another annoying error message tonight while messing around with the Alamofire networking library for iOS. Actually, it was two annoying error messages:
No such module ‘Alamofire’
and…
Module ‘Alamofire’ has no member ‘request’
It looks like the documentation for Alamofire is out of sync with the latest version of Alamofire. So simply open up your podfile and change the Alamofire version back to 4.8.1 instead of version 5.0.0. Then go ahead and run $ pod update and all will be well!

 

Invalid initializer call with same type 'FileAttributeKey' as parameter

This blog post is brought to you by the developer of BitBudget. BitBudget is an automated budgeting app for Android and iOS which syncs with your bank account and helps you avoid overspending. If you’d like to quit living paycheck-to-paycheck and get a better handle on your finances, download it today! https://bitbudget.io

Ran into a little bug tonight going through the official quick start guide for the Realm Database on iOS. The app which I’m building needs to be able to access the database while running in the background, so according to the Realm documentation developers need to change some security settings for the folder containing the database in order to access that database from the background. Without changing the security settings, the folder containing the database will be encrypted and not accessible when a user’s iPhone is locked. The official documentation suggests adding the following lines of code so that the Realm Database is accessible even when the phone is locked:

let realm = try! Realm()
// Get our Realm file's parent directory
let folderPath = realm.configuration.fileURL!.deletingLastPathComponent().path
// Disable file protection for this directory
try! FileManager.default.setAttributes([FileAttributeKey(rawValue: NSFileProtectionKey): NSFileProtectionNone], ofItemAtPath: folderPath)

However, when I tried using this little snippet of code in my current iOS project (WingsuitGP) I received the following error message: Invalid initializer call with same type ‘FileAttributeKey’ as parameter
Luckily, someone on StackOverflow got me pointed in the right direction: invalid initializer call with same type ‘XXXX’ as parameter
But I still needed a little help from Xcode’s suggested bug fixes to get it to work just right. So here is what I ended up with if anyone else is struggling with this annoying error:

let realm = try! Realm()
// Get our Realm file's parent directory
let folderPath = realm.configuration.fileURL!.deletingLastPathComponent().path
// Disable file protection for this directory
try! FileManager.default.setAttributes([FileAttributeKey.protectionKey: FileProtectionType.none], ofItemAtPath: folderPath)

 

How To Install a Cocoapod

Quick little blog post here on how to install a Cocoapod into an Xcode project. This is sort of for my own personal reference because I haven’t memorized how to do this yet, but if you need a more in depth tutorial check out How to Install a CocoaPod by Sean Allen.
First, enter a few terminal commands:

$ cd Desktop/SwiftPlayground/MySuperSweetXcodeProject
$ pod init
$ open -a Xcode Podfile


Next, edit (and save) your Podfile:

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
target 'MySuperSweetXcodeProject' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!
  # *** ADD YOUR POD ON THE LINE BELOW ***
  pod 'MySuperSweetCocoaPod'
end


Last, run one final terminal command:

$ pod install

 

Hello, World with the Realm Database for iOS in Swift

This blog post is brought to you by the developer of BitBudget. BitBudget is an automated budgeting app for Android and iOS which syncs with your bank account and helps you avoid overspending. If you’d like to quit living paycheck-to-paycheck and get a better handle on your finances, download it today! https://bitbudget.io

As I mentioned in my previous post, I’ve been doing a little hacking today using the Realm Database for iOS (using Swift). The official tutorial from Realm is pretty good, but it leaves out where exactly to put certain snippets of code within the Xcode framework as many official tutorials for various programming frameworks and libraries often do. So I just wanted to jot down this quick blog post for my own personal reference, or maybe to help another developer out there in cyber-space to get up and running with the Realm Database for iOS:

  1. Install Realm using the Cocoapods Dependency Manager (See this tutorial for help getting started with Cocoapods if necessary)
  2. Create a New Xcode Project

Okay, so now you have you have Realm installed and have created your new Xcode project. Now we are going to make our “hello, world” app inspired by one of the stupidest games of all time: Cookie Clicker
Cookie Clicker is a pretty ridiculous game. The gist of the whole thing is you click a button and then you get cookies. That’s it! Pretty much all there is to it. The only thing is, with Cookie Clicker, you want to be able to save the number of cookies baked in between running the game, so I thought it would make an excellent example for learning the basics of Realm. The app will simply consist of a single screen with a label which displays the number of cookies baked, and a button the user can press to bake more cookies. And using the magic of the Realm Database, we will be able to save the number of cookies baked by our users. In addition to the single screen, we will have one ViewController (ViewController.swift) and another swift file called Cookie.swift which we will use to declare our Cookie class. Just remember to connect the label to the view controller (control-drag) to create your IBOutlet for the cookieCountLabel, and also make an IBAction connection by control-dragging from your bakeCookiesButton to the ViewController.
NOTE: See my previous blog post regarding the error message “Could Not Build the Objective-C Module ‘RealmSwift‘” if necessary.
CookieClickerScreenshot

//
//  ViewController.swift
//  HelloRealm
//
//  Created by Christopher Pedersen on 2/25/19.
//  Copyright © 2019 Christopher Pedersen. All rights reserved.
//
import UIKit
import RealmSwift
class ViewController: UIViewController {
    @IBOutlet weak var cookieCountLabel: UILabel!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        let realm = try! Realm()
        let cookies = realm.objects(Cookie.self)
        let cookieCount: Int = cookies.count
        if cookieCount > 0 {
            cookieCountLabel.text = "Cookies: \(cookieCount)"
        } else {
            cookieCountLabel.text = "Cookies: 0"
        }
    }
    @IBAction func onBakeCookiesButtonClicked(_ sender: Any) {
        let realm = try! Realm()
        let newCookie = Cookie()
        newCookie.type = "Chocolate Chip"
        newCookie.size = "Large"
        let cookies = realm.objects(Cookie.self)
        try! realm.write {
            realm.add(newCookie)
        }
        let cookieCount: Int = cookies.count
        cookieCountLabel.text = "Cookies: \(cookieCount)"
    }
}

//
//  Cookie.swift
//  HelloRealm
//
//  Created by Christopher Pedersen on 2/25/19.
//  Copyright © 2019 Christopher Pedersen. All rights reserved.
//
import Foundation
import RealmSwift
class Cookie: Object {
    @objc dynamic var type = ""
    @objc dynamic var size = ""
}