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
For the past several days I’ve been trying to figure out how to send JSON data from an iOS app to a backend server running PHP (using the Alamofire networking library/wrapper). The problem that I seem to keep running into is that working with JSON in Swift is sort of a pain in the ass. With Alamofire you are suppose to construct a dictionary to represent your JSON data, and then using the Alamofire.request method you can easily send your data accross the networking using HTTP POST.
However, I keep running into problems when attempting to generate my JSON data dynamically. For example, let’s say I want to create a JSON object that contains thousands of pieces of information. Swift doesn’t make that easy! So far I’ve only been able to get everything to work if my JSON data is all hard-coded, and not generated dynamically.
I feel like I’m getting closer to the answer, but still am not quite where I want to be. So far this is what I have:
Single View (Main.storyboard)
ViewController.swift
//
// ViewController.swift
// JSONxAlamofire
//
// Created by Christopher Pedersen on 3/3/19.
// Copyright © 2019 Christopher Pedersen. All rights reserved.
//
import UIKit
import Foundation
import Alamofire
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
@IBAction func onButtonClick(_ sender: Any) {
let parameters: Parameters = [
"firstTypeOfData": [
["foo": Int.random(in: 1...100), "bar": Int.random(in: 1...100), "baz": Int.random(in: 1...100)],
["foo": Int.random(in: 1...100), "bar": Int.random(in: 1...100), "baz": Int.random(in: 1...100)],
["foo": Int.random(in: 1...100), "bar": Int.random(in: 1...100), "baz": Int.random(in: 1...100)],
["foo": Int.random(in: 1...100), "bar": Int.random(in: 1...100), "baz": Int.random(in: 1...100)],
["foo": Int.random(in: 1...100), "bar": Int.random(in: 1...100), "baz": Int.random(in: 1...100)]
],
"secondTypeOfData": [
["foo": Int.random(in: 1...100), "bar": Int.random(in: 1...100)],
["foo": Int.random(in: 1...100), "bar": Int.random(in: 1...100)],
["foo": Int.random(in: 1...100), "bar": Int.random(in: 1...100)],
["foo": Int.random(in: 1...100), "bar": Int.random(in: 1...100)],
["foo": Int.random(in: 1...100), "bar": Int.random(in: 1...100)]
]
]
Alamofire.request("http://wingsuitgp.com/networkingtest.php", method: .post, parameters: parameters, encoding: JSONEncoding.default).response { response in
if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
print("Server Repsonse: \(response)") // print server response to console
} else {
print("ERROR: PC LOAD LETTER") // cryptic error message
}
}
}
networkingtest.php
// Receive JSON Data Via HTTP POST
$data = json_decode(file_get_contents('php://input'));
$numberOfDataPoints = count($data->{'firstTypeOfData'});
if ($numberOfDataPoints <= 1) { die("no data detected..."); } // Connect to MySQL Database $servername = "localhost"; $username = "DATABASE-ADMIN-NAME-GOES-HERE"; $password = "DATABASE-PASSWORD-GOES-HERE"; $dbname = "DATABASE-NAME-GOES-HERE"; $conn = new mysqli($servername, $username, $password, $dbname); if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// Insert First Type of Data into MySQL Database
for ($i = 0; $i < $numberOfDataPoints; $i++){ $datatype = "first_type_of_data"; $foo = $data->{'firstTypeOfData'}[$i]->{'foo'};
$bar = $data->{'firstTypeOfData'}[$i]->{'bar'};
$baz = $data->{'firstTypeOfData'}[$i]->{'baz'};
$stmt = $conn->prepare("INSERT INTO networkingtest_table (datatype_column, foo_column, bar_column, baz_column) VALUES (?, ?, ?, ?)");
$stmt->bind_param("siii", $datatype, $foo, $bar, $baz);
$stmt->execute();
$stmt->close();
}
// Insert Second Type of Data into MySQL Database
for ($i = 0; $i < $numberOfDataPoints; $i++){ $datatype = "second_type_of_data"; $foo = $data->{'secondTypeOfData'}[$i]->{'foo'};
$bar = $data->{'secondTypeOfData'}[$i]->{'bar'};
$baz = 0;
$stmt = $conn->prepare("INSERT INTO networkingtest_table (datatype_column, foo_column, bar_column, baz_column) VALUES (?, ?, ?, ?)");
$stmt->bind_param("siii", $datatype, $foo, $bar, $baz);
$stmt->execute();
$stmt->close();
}
// Close MySQL Database Connection
$conn->close();
echo "data_received"; // echo server response back to client iPhone app