Quick Links

Wondering where to get started?

I’ve set up the following tutorials which will take you from writing a simple backend in Java (Spring Boot) where you’ll develop your first REST API, all the way to consuming these API’s in a simple iOS application using Swift 3.

With that being said, if you have no interest in developing a backend and just wanted some code for HTTP Requests written in Swift 3, feel free to skip through and check out those tutorials as they can be easily adapted to consume any API.  

Latest Video

Each video will correspond to a part of one of the following tutorials (for those who prefer written format).

Java/Spring Boot Tutorials

Swift/iOS Tutorials

Part 1: Setting up your MySQL Database Part 1: Setting up our XCode/Swift 3 Project (To Consume our REST API)
Part 2: Setting Up Spring Boot and Hibernate in Eclipse Part 2: GET Request with Swift 3 (wihout Alamofire)
Part 3: Configuring Your Database to Work With Spring Boot Part 3: Display JSON Data Inside of a UITableView
Part 4: Querying a Database From Your Spring Boot Application Part 4: POST Request in Swift 3 (without Alamorfire)
Part 5: Creating Some Service Layer Functionality
Part 6: Creating Your First REST API
Part 7: Adding Additional Functionality to our Spring Boot Application

 

Library of the Month

I’ll be putting up a new library that I think is worth mentioning every month alongside some code examples to get you up and running.  If you have any suggestions, feel free to send those along.

Chameleon

 

Blog Categories

Here are a few blog categories I’ll try to keep consistent.

 

Tips All related coding tips and personal experiences.
Library Of The Month
Past libraries of the month.

 

This has received a lot more interest than I thought which is encouraging!  If you have any additional suggestions or maybe there is a topic you’d like to learn more about or if there was a section in one of the tutorials I skipped over too quickly please leave a comment below – I’d love to help out!

Querying a MySQL Database with Swift 3 (PerfectMySQL)

In the last tutorial we set up our server side Swift project to connect with the MySQL database we set up here.  In this tutorial, we’re going to learn how to run queries against our database using Swift & the Perfect framework.

 

Writing our First Statement

In the last tutorial we created a new Database.swift file that will handle all of the related database functionality of our project.  What we’re going to do is add in another function to this file that will allow us to insert a new row into the game table of our database.

To do so, I’m going to add in a function called insertGame which looks like this…

import PerfectHTTP
import PerfectHTTPServer
import PerfectMySQL
import Foundation
public class DB {
// You'll need to update these values based on how you've set up MySQL.
let host = "127.0.0.1"
let user = "root"
let password = "admin"
let database = "nintendo"
func databaseConnect(host: String, user: String, password: String, db: String) -> MySQL {
let mysql = MySQL() // Create an instance of MySQL to work with
let connected = mysql.connect(host: host, user: user, password: password, db: db)
guard connected else {
// verify that we have connected successfully
print(mysql.errorMessage())
return mysql
}
return mysql
}
public func insertGame(title: String, description: String, createdDate: String){
// Connect to our database
var db = databaseConnect(host: host, user: user, password: password, db: database)
defer {
db.close() //This defer block makes sure we terminate the connection once finished, regardless of the result
}
// Create the statement we wish to execute
let statement = MySQLStmt(db)
let insert = "INSERT INTO game(id, title, description, release_date) VALUES (\(statement.insertId()), '\(title)', '\(description)', '\(createdDate)');"
_ = statement.prepare(statement: insert)
// Run the query
let querySuccess = statement.execute()
// Check that our query was successfuly, otherwise return out
guard querySuccess else {
print(db.errorMessage())
return
}
print("Insert successful!");
}
}
view raw Database.swift hosted with ❤ by GitHub

Calling our Insert Function

Awesome, so now that we have our first function created that will insert a game into our database, let’s call this from our main.swift file.  Here’s what we’re going to do:

  1. Create an instance of our DB class (inside of our Database.swift file) that will allow us to make calls to the public functions we’ve put inside of this class.
  2. Call our insertGame function!

Here’s what my main.swift file looks like now…

import PerfectLib
import PerfectHTTP
import PerfectHTTPServer
import PerfectMySQL
import Foundation
let mysql = DB()
mysql.insertGame(title: "testing", description: "testing", createdDate: "1991-05-31");
view raw main.swift hosted with ❤ by GitHub

Now when we go ahead and run our application, our insertGame function will execute which will insert a new row into the game table of our database.

I’ve gone ahead and performed a quick query of the database just to show the additional row that has been added.

Screen Shot 2017-12-02 at 11.54.34 AM.png

Great, so we’ve written our first SQL statement that will insert game rows into our database using Swift!  As promised, I’ll be keeping these tutorials as short as possible, so I’ll end this one right here.  If you’re interested in learning writing server side Swift, in the next tutorial I’ll be showing you how to write your first API.

If you’re having some trouble getting your project to this stage, leave a comment below and I’ll help you out.  Have any other unrelated questions or suggestions?  I’d like to hear those too! 

 

Setting up our Swift web-server to connect to MySQL

This series is going to show you how to write a basic backend using Swift.  This is for those who feel more comfortable using Swift throughout their application rather than switching between languages (ex: Java/Spring Boot backend which can also be started out here).  If this is something you’re interested in, I’ll be breaking this down into small parts so it doesn’t become too frightening!

Last time we focused on setting up our Swift web-service project which can be found here.  This time we’re going to be doing some configuration within this project to set up communication with MySQL.

Connecting to MySQL

The first thing we’re going to do is configure our project to connect with MySQL.  Before we add in the MySQL Perfect dependency, we have to do a little bit of setting up first on our machine.  Open up Terminal and type the following…

brew update

And once that has finished updating type

brew install mysql

Potential Errors (Follow these steps if you receive the following error)

Screen Shot 2017-11-26 at 10.53.21 AM

To fix this, type

xcode-select --install

And then go ahead and attempt to perform the previous step by typing

brew install mysql

Now we can update our Package.swift file to include the Perfect MySQL dependency.  After doing so, your file will look as follows…

import PackageDescription
let package = Package(
name: "swift-server",
dependencies: [
.Package(url: "https://github.com/PerfectlySoft/Perfect-HTTPServer.git", majorVersion: 2),
.Package(url:"https://github.com/PerfectlySoft/Perfect-MySQL.git", majorVersion: 3)
]
)
view raw Package.swift hosted with ❤ by GitHub

Let’s update our project to include this dependency.  Open up Terminal and type…

swift package update

And once that has finished updating, type in the following command

swift package generate-xcodeproj

Awesome.  So we have the MySQL dependency added, now we can write some code to configure our project to communicate with our MySQL database that we set up in a previous tutorial here (you’ll need to do this first, unless you have a MySQL database already setup and running on your machine).

I’m going to create a new Swift file called Database.swift which is where we’ll put all of our database related functionality.  To do this…

  1. Right click on our project directory, swift-server
  2. Select New File… and in the popup window select Swift File
  3. Give your file a name – I’ve called mine Database and then go ahead and click save.

After creating this new Swift file, my project directory looks as follows…

Screen Shot 2017-12-02 at 9.51.00 AM

Now, there are a few other things we’re going to do before we make the call to connect to our database.  Perform the following…

  1. Right click on your new Database.swift file > Show File Inspector

On the right hand side of Xcode, you’ll notice a panel appear.  Make sure in the Target Membership that you have the following selected…

Screen Shot 2017-12-02 at 10.27.46 AM.png

We’re ready to start coding.  I’m going to create a new function in the Database.swift that will connect to our database.  It will look like this…

public class DB {
// You'll need to update these values based on how you've set up MySQL.
let host = "127.0.0.1"
let user = "root"
let password = "admin"
let database = "nintendo"
func databaseConnect(host: String, user: String, password: String, db: String) -> MySQL {
let mysql = MySQL() // Create an instance of MySQL to work with
let connected = mysql.connect(host: host, user: user, password: password, db: db)
guard connected else {
// verify that we have connected successfully
print(mysql.errorMessage())
return mysql
}
return mysql
}
}
view raw main.swift hosted with ❤ by GitHub

Keep in mind that you’ll have to change the values for user, password, and database depending on how you’ve set up MySQL on your computer.


As promised, I will break down these tutorials to keep them short and easy to follow.  I will end this one right here as I know it might take a bit of time to get this setup – please leave me a comment below if you run into any errors while trying to get your project to this point.

If you’re interested in this series, next time I’ll be showing you how to query our MySQL database that we connected in this tutorial from our Swift web-server project!

Creating our Swift Web Server Project

You may have followed the previous Spring Boot tutorials where we developed our first REST API.  We’re going to do something similar here except we’re going to create our web-server using Swift instead.

Once again, I’m going to break these tutorials down into small sections so it isn’t too daunting especially if this is your first time creating a REST service.  With that being said, today we’re just going to be creating our project.

For the web-server, I’m going to be using Perfect which is a toolkit used to build REST services.

Things you’ll need

OS X

  1. Swift 3.0
    • If you have Xcode installed, you should already have this.  But just to confirm, go ahead and open up Terminal and type swift –version if you’re unsure.

That’s it.  Awesome.

Ubuntu Linux (taken from the Perfect documentation)

Perfect runs in Ubuntu Linux 14.04, 15.10 and 16.04 environments. Perfect relies on OpenSSL, libssl-dev, and uuid-dev. To install these, in the terminal, type:

sudo apt-get install openssl libssl-dev uuid-dev

When building on Linux, OpenSSL 1.0.2+ is required for this package. On Ubuntu 14 or some Debian distributions you will need to update your OpenSSL before this package will build.

Building Our Starter Project

Open up Terminal and enter in the following commands…

mkdir swift-server 
cd swift-server

This is the directory that I’ll put my project into.  (I’ve put this on my desktop, but feel free to put yours anywhere).

Now that we’re inside of our new directory, type the following commands

swift package init --type executable
swift package generate-xcodeproj

And with our new Xcode project generated, let’s go ahead and open it.

open ./swift-server.xcodeproj

Maybe you like screenshots, so here is what my Terminal looks like after entering the above commands…

Screen Shot 2017-11-25 at 10.37.20 AM

Alright, let’s make sure that we have this set up.  After opening your project from Terminal, click on the active scheme

Screen Shot 2017-11-25 at 10.51.23 AM.png

It might already look like it has been selected, but make sure to set the active scheme as follows…

Screen Shot 2017-11-25 at 10.55.01 AM.png

Then we’re going to run our application by selecting the run button.

screen-shot-2017-11-25-at-10-51-23-am1.png

After doing so, you should notice the following “Hello World” text in the Xcode console as follows…

Screen Shot 2017-11-25 at 11.00.49 AM.png

If you don’t see this, make sure that you have selected the correct active scheme from the previous step!

Importing Perfect into our Project

Now that our application has run successfully, let’s go ahead and import Perfect.  To do this, open up the Package.swift file that was generated when we created our project from Terminal.

Screen Shot 2017-11-25 at 11.06.20 AM.png

Add in the following dependency to your Package.swift file so that it will now look something like this…

import PackageDescription
let package = Package(
name: "swift-server",
dependencies: [
.Package(url: "https://github.com/PerfectlySoft/Perfect-HTTPServer.git", majorVersion: 2)
]
)
view raw Package.swift hosted with ❤ by GitHub

Now that we’ve added in the Perfect dependency, we’re going to open up Terminal again and type in the following command

swift package update

And once that has finished updating, type in the following command

swift package generate-xcodeproj

Now we can switch back into Xcode and note the Perfect directories have been added to our Sources.

Screen Shot 2017-11-25 at 11.19.14 AM.png

To check that this is setup, go ahead and open the main.swift file located in Sources > swift-server > main.swift (shown in the above image).

We’re going to import the PerfectLib, PerfectHTTP, and PerfectHTTPServer.  Your main.swift file will now look as follows…

import PerfectLib
import PerfectHTTP
import PerfectHTTPServer
print("Hello, world!")
view raw main.swift hosted with ❤ by GitHub

And once again, we’ll run our application by selecting  Screen Shot 2017-11-25 at 10.51.23 AM and if there are no errors we are good to go!


 

Alright, so we’ve set up our project and have successfully added in the Perfect dependency.  If you’d like to continue learning how to create a Swift REST service, next time we’ll be doing some configuration within our project to communicate with our MySQL database.

Have any questions, comments, suggestions?  Having issues getting your project to this stage?  Leave a comment and I’ll be happy to get back to you. 

 

Library of the Month: Chameleon

Having a hard time finding the right colour scheme for your iOS app?  Check out Chameleon – a powerful colour framework that removes the hassle and minimizes the time spent on finding the perfect colour combination.  Chameleon is lightweight and offers many useful functionalities such as global app theming, text and background contrast, and generation of gradient colours… just to name a few.

Installation

Swift

use_frameworks!

pod 'ChameleonFramework/Swift'

Objective-C

use_frameworks!

pod 'ChameleonFramework'

Storyboard Add-On (optional)

If you like, you can also download and install the Chameleon Palette.  After restarting Xcode you’ll find all of the colours from Chameleon in the Palette Colour Picker for those of you that prefer using Storyboard.

Screen Shot 2017-11-19 at 10.27.13 AM.png

Examples

Text and Background Contrast

I suppose it’s important that users are able to read the text in your application. With Chameleon you can do that with one line of code which takes away the impossible decision of picking a contrasting text colour (this is also extremely helpful when your background colour changes dynamically).  Check it out…

import UIKit
import ChameleonFramework
class RootViewController: UIViewController {
@IBOutlet var myTitle: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
myTitle.textColor = ContrastColorOf(backgroundColor: view.backgroundColor!, returnFlat: false)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
view raw ViewController.swift hosted with ❤ by GitHub

Screen Shot 2017-11-19 at 10.44.08 AM.png

Gradient Colours

import UIKit
import ChameleonFramework
class RootViewController: UIViewController {
@IBOutlet var myTitle: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
myTitle.textColor = ContrastColorOf(backgroundColor: view.backgroundColor!, returnFlat: false)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
view raw ViewController.swift hosted with ❤ by GitHub

Screen Shot 2017-11-19 at 10.55.40 AM.png

Colours From Images

Chameleon supports extraction of colour from images which allows for easy generation of flat or non-flat colour schemes.

import UIKit
import ChameleonFramework
class RootViewController: UIViewController {
@IBOutlet var myTitle: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
myTitle.textColor = ContrastColorOf(backgroundColor: view.backgroundColor!, returnFlat: false)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
view raw ViewController.swift hosted with ❤ by GitHub

Screen Shot 2017-11-19 at 11.18.23 AM.png

This just provides a few examples of the things you can do with the Chameleon framework, if you’re looking for some more tricks check out the documentation here.  I hope some of you might find this useful as it’s definitely something I’ll continue to use in my future projects.

If there are any other frameworks that you think are worth mentioning, leave me a comment below and I’d love to check them out. 

Using JDBC in a Spring Boot Application

Sometimes you might want to execute some more complicated SQL statements to run against your database from your Spring Boot application.  In this section, I’ll show you how to setup a JDBC Template to get started.

I’m going to be using a simple, existing project that you would have been following along with if you had done any of the previous Spring Boot tutorials.  The source code for this can be found right here.

I’m also going to be running this in Eclipse, but feel free to use any other IDE of choice.  If you’re having some trouble following along, don’t worry, I’ll add in the completed source code at the end of this post as well.

Creating our BaseJDBCRepository

There will be many times where you’ll want to create a new JDBCRepository class per each entity in your application.  With that in mind, to keep things tidy I’m going to create a parent class that each of these JDBCRepositories will extend just to reuse some existing code.  So, I’m going to create a new class called BaseJDBCRepository inside of the repository package and add in the following code…

import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
@Repository
@Transactional
public class BaseJDBCRepository {
@Autowired
private Environment environment;
protected NamedParameterJdbcTemplate jdbcTemplate;
@Autowired
public void setDataSource(DataSource dataSource){
this.jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
}
public String readQueryFromProperties(String query){
return environment.getProperty(query);
}
}

Creating the GameJDBCRepository class

Remember before how I mentioned that we’re going to want to create a new JDBCRepository class per each entity in our application?  Now we’re going to create a GameJDBCRepository.java file inside of the repository package which will handle all functionality related to our Game.java object.  This new file will extend the BaseJDBCRepository class we created in the previous step so that we can access the jdbcTemplate.  This will allow us to perform our queries.  A basic skeleton of this class will look as follows…

import org.springframework.stereotype.Repository;
@Repository
public class GameJDBCRepository extends BaseJDBCRepository {
}

Now, for fun let’s add in a query that will find all games that have a particular word that we are looking for in their description.  Maybe we want to find all games that have the word “platform” in their description as we really like those kind of games.

There are a couple of things that we will need to set this up such as:

  1. Our SQL statement that we wish to execute.
  2. A custom RowMapper that will map the results returned from our query into a list of Game.java objects.

With that in mind, I will add these into our GameJDBCRepository class and it should now look as follows…

import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import tutorial.springsetup.entity.Game;
@Repository
public class GameJDBCRepository extends BaseJDBCRepository {
private final String SQL_SEARCH_BY_DESCRIPTION = "SELECT description, id, title FROM game g WHERE lower(g.description) LIKE lower(:desc);";
private class GameRowMapper implements RowMapper<Game> {
public Game mapRow(ResultSet rs, int rowNum) throws SQLException {
Game game = new Game();
game.setDescription(rs.getString("description"));
game.setId(rs.getLong("id"));
game.setTitle(rs.getString("title"));
return game;
}
}
}

Great, so now that we have our RowMapper and our SQL statement, let’s create our searchForGamesByDescription method.  It will look something like this…

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import tutorial.springsetup.entity.Game;
@Repository
public class GameJDBCRepository extends BaseJDBCRepository {
private final String SQL_SEARCH_BY_DESCRIPTION = "SELECT description, id, title FROM game g WHERE lower(g.description) LIKE lower(:desc);";
public List<Game> searchForGamesByDescription(String searchTerm){
Map<String, Object> params = new HashMap<String, Object>();
params.put("desc", "%" + searchTerm + "%"); // wrap with "%" to find descriptions that include provided search term.
return jdbcTemplate.query(SQL_SEARCH_BY_DESCRIPTION, params, new GameRowMapper()); // use jdbcTemplate extended from BaseJDBCRepository
}
private class GameRowMapper implements RowMapper<Game> {
public Game mapRow(ResultSet rs, int rowNum) throws SQLException {
Game game = new Game();
game.setDescription(rs.getString("description"));
game.setId(rs.getLong("id"));
game.setTitle(rs.getString("title"));
return game;
}
}
}

Awesome, and that is our first implementation using JDBC.

If you had some trouble following along, or if you wanted to just check out the source code I’ve uploaded it to github which can be found here.

Have any questions, comments, suggestions?  Want more JDBC examples?  Leave a comment and I’ll be happy to get back to you. 

 

 

POST Request in Swift 3 (without Alamofire)

Howdy folks!  In the last tutorial we spent some time going through how we can take the JSON data we retrieved from our GET request in Swift and display it inside of a UITableView.  We also learned how we can map the JSON representation of our Game object (from the database) into a Swift object so that we could easily access particular fields.

If you’re new to these tutorials, the API’s we will be calling to test our HTTP requests were developed in previous lessons using Spring Boot.  If you’re interested in Java development and wanted to create your own backend application, the beginning of these tutorials can be found here.  However, if you have no interest in learning how to create your own API’s, you can still follow along with this tutorial.

In this tutorial we’re going to code our POST request so that a user will be able to create comments on a Game.  We’ll add this code to our Request.swift file which is responsible for all of our HTTP functionalities.

Creating our Comment.swift Object

Because we’re going to be using a JSON content type when posting to our API, that means we need to pass through a JSON representation of a Comment object.  With that being said, the first thing we’re going to do is create a new Comment.swift file that mocks the fields of our comment table in the database.  It will look something like this…

import Foundation
class Comment {
var id: Int?
var game: Game?
var author: String?
var text: String?
var createdDate: String?
init(){}
init(data: [String: AnyObject]){
id = data["id"] as? Int
author = data["author"] as? String
text = data["text"] as? String
createdDate = data["createdDate"] as? String
if let gameData = data["game"] as? [String: AnyObject] {
game = Game(data: gameData)
}
}
// Use to map Comment object into dictionary - this will be used to POST to the server.
// We do not have to worry about setting our Game object nor our createdDate as we handle this on the server side.
func convertToDictionary() -> [String: AnyObject] {
var dict = [String: AnyObject]();
dict["id"] = self.id as AnyObject
dict["author"] = self.author as AnyObject
dict["text"] = self.text as AnyObject
return dict
}
}
view raw Comment.swift hosted with ❤ by GitHub

Creating our POST request in Swift 3

Great, so we have our Comment.swift object created, now we’re ready to start coding our POST request.  If you’ve been following along, we’re going to put this function in our Request.swift file which is responsible for all of our HTTP functionality.  In order to make a POST request, we need to keep in mind that we’re going to be posting JSON content type to the server, which is where we can make use of our mapToDictionary function created in our Comment.swift file.

With that being said, our POST request will look as follows…

typealias PostCompletionHandler = (NSDictionary) -> ()
static func post(postUrl: String, body: [String: AnyObject], completionHandler: @escaping (PostCompletionHandler)){
let url = URL(string:postUrl)!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type") // Set as JSON content-type
request.addValue("application/json", forHTTPHeaderField: "Accept")
if(body.count > 0){
do {
request.httpBody = try JSONSerialization.data(withJSONObject: body, options: .prettyPrinted)
} catch let error {
print(error.localizedDescription)
}
}
let task = URLSession.shared.dataTask(with: request as URLRequest) { data,response,error in
if error != nil{
print(error?.localizedDescription ?? "Error")
return
}
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if json != nil {
completionHandler(json!)
}
} catch let error as NSError {
print(error)
}
}
task.resume()
}
view raw Request.swift hosted with ❤ by GitHub

We’ll take in a POST url which contains the API that we will POST to.  We’ll also take in a body: [String: AnyObject] parameter which represents a JSON representation of, in this case, our Comment.swift object.

Testing our POST request

Sweet, so we’ve created our Comment.swift class and now we have our POST request set up using Swift 3.  Now, let’s see how we can actually use this function.

First, let’s set up a new constant in our Constants.swift file to store our create game comment API.  It should now look something like…

import Foundation
struct Constants {
struct URL {
static let baseUrl = "http://localhost:8080/api"
static let searchGamesByTitle = baseUrl + "/games?title="
static let createGameComment = baseUrl + "/games/{gameId}/comments"
}
}
view raw Constants.swift hosted with ❤ by GitHub

For now, I’m going to create a new view controller in which I’ll name CommentViewController.swift which will be responsible for showing all of the comments of a particular game.

Now, my project directory will look something like this…

Screen Shot 2017-10-27 at 6.41.47 PM.png

For testing purposes, I’m just going to create a dummy call with this function so that we can see how to call it and that it is working as we expect it to.  With that being said, in our viewDidLoad method of our new CommentViewController.swift file, I’m going to add in the following code…

import UIKit
class CommentViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Create a test comment
let comment = Comment()
comment.author = "Dayna"
comment.text = "This game is cool."
let postUrl = Constants.URL.createGameComment.replacingOccurrences(of: "{gameId}", with: "1") // Create a comment on game with id = 1
Request.post(postUrl: postUrl, body: comment.convertToDictionary()) { (data) in
OperationQueue.main.addOperation {
print(data)
}
}
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
  1. We’ll create a random Comment.swift object.
  2. Set up our POST url to create a comment on game with id = 1
  3. We’ll call our Request.post method.

For now, I’ll set this CommentViewController.swift class as my initial view controller, just for testing purposes.  When I run my application,  I print out the data to the console which looks as follows…

Screen Shot 2017-10-27 at 7.11.11 PM.png

Awesome, this tells us that our POST request is working as expected and that comments are being created on the game corresponding to the game.id we pass through in our API call.

So, we’ve created our Comment.swift object, wrote our POST request in Swift, and finally we have done a quick test to see that it is working as expected.

This tutorial was primarily created to develop our actual POST request, however, in the next tutorial we’ll set up a basic UI that will allow a user to comment on a particular game, and from this input we will POST it to the server.

Have any questions, comments, suggestions?  Having issues getting your project to this stage?  Leave a comment and I’ll be happy to get back to you. 

Library of the Month: DZNEmptyDataSet

This month we’re checking out the DZNEmptyDataSet library which can be included in your XCode project via CocoaPods.

If your UICollectionView or UITableView views are populated dynamically, this library will make it extremely easy to handle the case where these views might be empty if there is a situation where there isn’t any available data to display.  Adding these little touches to your application really gives it that complete feel.

The best part is that setting this up only requires minimal additional coding on your part to get a pretty sleek looking empty set.  Plus, you can simply add it to an existing UITableView or UICollectionView that you’ve already been using in your project without any hassle.

Here’s a little example I’ve put together with a UITableView just to show you how easy it truly is.

I’ve added mine using CocoaPods as follows…

pod 'DZNEmptyDataSet'

I’ve just set up a basic UITableView in storyboard and connected it to my ViewController.swift class.  To start using this library, we’ll import DZNEmptyDataSet and adopt it.  This will look like…

import DZNEmptyDataSet

class ViewController: UIViewController, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate { ... }

Here’s what my class looks like after adding in the following datasource and delegate methods…

import UIKit
import DZNEmptyDataSet
class ViewController: UIViewController, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate {
@IBOutlet var tableView: UITableView!
let tungsten: UIColor = UIColor(red:0.20, green:0.20, blue:0.20, alpha:1.0)
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.emptyDataSetSource = self
self.tableView.emptyDataSetDelegate = self
self.tableView.tableFooterView = UIView() // remove empty cells from tableView
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// Add an image to your empty data set
func image(forEmptyDataSet scrollView: UIScrollView!) -> UIImage! {
let image = UIImage(named: "Coffee")?.withRenderingMode(.alwaysTemplate)
scrollView.tintColor = self.tungsten
return image
}
// Add a title to your empty data set
func title(forEmptyDataSet scrollView: UIScrollView!) -> NSAttributedString! {
let text = "Sorry, nothing found here."
let attribs = [
NSFontAttributeName: UIFont(name: "Helvetica", size: 18.0)!,
NSForegroundColorAttributeName: self.tungsten
]
return NSAttributedString(string: text, attributes: attribs)
}
// Add a description to your empty data set
func description(forEmptyDataSet scrollView: UIScrollView!) -> NSAttributedString! {
let text = "Please check back at another time and we might have something more."
let para = NSMutableParagraphStyle()
para.lineBreakMode = NSLineBreakMode.byWordWrapping
para.alignment = NSTextAlignment.center
let attribs = [
NSFontAttributeName: UIFont(name: "Helvetica", size: 14.0)!,
NSForegroundColorAttributeName: UIColor.lightGray,
NSParagraphStyleAttributeName: para
]
return NSAttributedString(string: text, attributes: attribs)
}
// Set the background color of your empty data set
func backgroundColor(forEmptyDataSet scrollView: UIScrollView!) -> UIColor! {
return UIColor(red:0.96, green:0.96, blue:0.96, alpha:1.0)
}
}
view raw ViewController.swift hosted with ❤ by GitHub

And if we run our application, we’ll see our cool empty data set result!

Screen Shot 2017-10-22 at 10.30.29 AM.png

If you enjoyed this segment or if you have any library suggestions you would like for me to check out, I’d love to hear about them – leave a comment below!

Also, shoutout to Outlane on www.dribbble.com for the illustration used in this post.  If you’re looking for some great free resources to add to your application, make sure to check out http://freebbble.com/.

Display JSON Data Inside of a UITableView

Last tutorial we looked at coding our GET request to retrieve data from one of the APIs we had written in our Spring Boot application.  We didn’t do much with the data that was returned other than printing it out into the XCode console to check that it was working as we had expected it to.  This tutorial we’re actually going to go through how we can store this data into an object and display it inside of a UITableView. 

Creating our Game.swift Object

So before we go ahead and do anything else, the first thing we want to do is create a new swift file called Game which will represent the JSON data of a single game object returned from our backend application.  Once you’ve done this, your XCode project directory might look something like…

Screen Shot 2017-10-21 at 9.04.13 AM

So before we start adding anything to this new Game.swift file, I should probably go into a little more detail of why we’re creating this to begin with.  Why can’t we just keep our data stored inside of a [[String: AnyObject]] like we’re doing currently?  The thing is, you CAN keep it in this format if you’d like (for simple projects such as this)… but I wouldn’t recommend it.  The main reason being is that it is A LOT more difficult to maintain and it is a huge pain to retrieve particular fields.  By creating our Game model in Swift, we can define one init that will map JSON to it’s appropriate fields in Game.swift which will grant us a hell of a lot easier access to particular data fields.

With that being said, I’m going to mock the JSON fields in our new Game.swift file so that it looks as follows…

import Foundation

class Game {

    var id: Int?
    var desc: String?
    var title: String?
    var releaseDate: String?

    init(data: [String: AnyObject]){
        id = data["id"] as? Int
        desc = data["description"] as? String
        title = data["title"] as? String
        releaseDate = data["releaseDate"] as? String
    }
}

Cool, so that is our Game class setup.  Now we can easily convert our JSON data retrieved from the server into this model.

Storing JSON into an Array of Game.swift Objects

Let’s go ahead and take the data we retrieved from our API and store it into an array of objects.  I’m going to create a new function inside of our ViewController.swift file that will do the following…

  1. Take a String parameter which will be represent the title of a game we would like to search for
  2. Call our Request.get method to retrieve data from the server (based on the title provided)
  3. Take the data we retrieved from this method call and populate an array of Game objects

So it’s going to look something like this…

var gameResults = [Game]()

func searchForGamesByTitle(title: String){
    Request.get(requestUrl: Constants.URL.searchGamesByTitle + title) { (results) in
        OperationQueue.main.addOperation {  // Get back onto the main thread after our Asynchronous call
            for jsonGame: [String: AnyObject] in results {
                self.gameResults.append( Game(data: jsonGame) ) // initialize + add game object into our array
            }
        }
    }
}

If you’d like to see what my entire ViewController.swift file looks like, check out the gist here.

Great, so we have a function to populate an array with Game objects.  Now we can use this array to display data inside of a UITableView.  Let’s go ahead and do that.

Creating The UITableView

Before we do this, I’ll just mention that I’ll be adding a gist to the end of this section that will have the complete source code for our ViewController.swift file so don’t worry if you’re having a hard time following along.

We’re going to be using Storyboard to create our UITableView within our UIViewController.

Once you’ve added in your UITableView and connected it to your ViewController.swift file, we need to add UITableViewDelegate and UITableViewDataSource into our class which will look something like this…

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource

You might notice that your project will now have errors.  That’s okay, to fix this we need to override a few functions from UITableViewDelegate and UITableViewDataSource, but before doing so I’m going to create another function within our ViewController.swift file to setup the UITableView we have just connected which will look like this…

func setupTableView(){
    self.tableView.delegate = self
    self.tableView.dataSource = self
    self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
    self.tableView.tableFooterView = UIView()   // remove empty cells from tableView
}

We’ll call this in our viewDidLoad() function.

The first datasource method we will need to override will look as follows…

func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

We’re only going to need one section for our UITableView, so we can return a constant value of 1.

We now need to define the amount of rows we will need in our UITableView.  Since we’re going to be storing one game per row based on the results of our search function, this value will change dynamically based on the number of items found in our gameResults array we created earlier.  To do this, we’ll override the following delegate method as follows…

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return gameResults.count
}

Lastly, we need to add some content to each row’s cell.  In this case, we will display the title of the game.  To do so, we need to override another delegate method which will look something like…

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let game = gameResults[indexPath.item]
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
    cell.textLabel?.text = game.title    // set the game title as the cell's text label
    return cell
}

This is a very simple example.  If we wanted, we could create a custom cell to show other values within our game object such as the description, release date, etc.

If you want to double check that you have all of the code setup properly in your ViewController.swift file, check out this gist here.  You’ll notice that I added searchForGamesByTitle(title: mariointo the viewDidLoad() function.  This is just so that we can populate our array for the sake of testing.  Otherwise, in the future we could add in some sort of search bar that would take user input and from that input perform a search based on the provided value.  Anyways, let’s run our application to check that our UITableView is working as we expect.

After running mine in a simulator, I’m able to see that the results returned from our search function are in fact being displayed appropriately inside of the UITableView.  Yours should hopefully look something like this (depending on the data you have in your database)…

screen-shot-2017-10-21-at-7-11-12-pm-e1508638329669.png

Cool!  So we’ve managed to map the JSON representation of our game objects retrieved from our Spring Boot application into Swift objects and we’ve learned how we can display these results within a UITableView.  This was a bit of a longer one, so I’ll wrap it up here.

Next tutorial we’ll learn how we can write a POST request in Swift so that we will be able to create comments on a particular game.

Have any questions, comments, suggestions?  Having issues getting your project to this stage?  Leave a comment and I’ll be happy to get back to you. 

 

GET Request with Swift 3 (without Alamofire)

Alright folks, in the past tutorials we spent some time writing our simple backend with Spring Boot (this will contain the API’s we will be calling in our iOS application) and the source code can be found here if you haven’t been following along.  More recently, we set up a very basic XCode project where we enabled App Transport Security Settings so that we can make HTTP requests within our iOS application – the steps for this can be found here if you have yet to give it a shot.

In this tutorial we will be (finally) writing some code that will allow us to make GET requests to the API’s we wrote in our Spring Boot backend.

If you have no interest in learning how to write a backend and will not be running the Spring Boot application we have been developing throughout, don’t worry, you will be able to follow this tutorial for a basic understanding of how to make HTTP requests with Swift.

Coding our GET Request

If you haven’t already, open up your XCode project.  We’re going to create a new Swift file, I’m going to name mine Request and this is where I’ll be holding all of my HTTP request related functionality.  After doing so, my project directory looks as follows…

Screen Shot 2017-10-20 at 7.15.13 PM.png

Open up the new Request.swift file you have just created.  We’re going to add in the following code which will allow us to make a GET Request.

import Foundation

struct Request {

    typealias CompletionHandler = ([[String: AnyObject]]) -> ()

    static func get(requestUrl: String, completionHandler: @escaping (CompletionHandler))  {
        let url = URL(string: requestUrl)!
        let request = URLRequest(url: url)

        // Asynchronous
        let task = URLSession.shared.dataTask(with: request as URLRequest) { data, response, error in
            guard error == nil else {
                print(error ?? "Error sending get request.")
                return
            }

            guard let data = data else {
                print("Data is empty")
                return
            }

            let json = try? JSONSerialization.jsonObject(with: data, options: [])
            if let jsonData = json as? [[String: AnyObject]] {
                completionHandler(jsonData) // once the call has completed, we can escape with our CompletionHandler
                                            // and return the data.
            }
        }

        task.resume()
    }
}

This might look a little bit confusing at first, but if we work through it a little bit more you’ll get a better idea of what is going on.

  1. The requestUrl method parameter will be the URL we will call to retrieve data.  If we look at our Spring Boot application and the APIs we have created, we would pass through a URL such as http://localhost:8080/api/games/1/comments to GET all comments posted for a particular game.
  2. The completionHandler method parameter is used to return the results from our GET request.  Since this HTTP request is executed asynchronously (to avoid blocking up the main thread), we want to be sure that we wait for this call to finish before returning the data, shown as completionHandler(jsonData) in the code.

If you’re still a bit confused about any part of this (I know the asynchronous call can be a little hard to grasp) add in a comment below and I’ll be happy to help.

Calling our GET Request Method

Fantastic, we have finally set up and written some code so that we can make calls to our API.  Before we begin making use of this function, I’d like to set up another Swift file that will be used to store some constants (ex: our URLs) so that we can keep things a little more readable.

I’ve created a new Swift file called Constants which I’m going to use throughout to store any constant value that is going to be used in our application.  This can range from a variety of things such as colours, String values, etc.  My directory now looks as follows…

Screen Shot 2017-10-20 at 8.07.00 PM

And the contents of my Constants.swift file looks something like this…

import Foundation

struct Constants {
    
    struct URL {
        static let baseUrl = "http://localhost:8080/api"
        static let searchGamesByTitle = baseUrl + "/games?title="
    }
}

The more APIs we develop, the more constants we can add into this file.  This is a really nice way of keeping everything a little more neat and if we make any changes to a particular constant we only have to worry about updating it in this file.

Alright, now we’re ready to test out our GET request function.  Since I’ve only added in the searchGamesByTitle URL into our Constants.swift (for now), we might as well give that one a try.

Open up the default ViewController that was made upon creating your XCode project and add in the following code…

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Call our get request function.  We're going to search for games with a title like "mario"
        Request.get(requestUrl: Constants.URL.searchGamesByTitle + "mario") { (results) in
            print(results)
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

We’re not going to do anything too exciting with our result data, for now we just want to test to see that we’re getting the output that we expect.  If we build and run our project (press the play button on the top menu bar), our Request.get function will be called.  Since we’re just printing out our results, you’ll notice in the console of XCode that you should have a JSON representation of the data we expect.  It might look something like…

Screen Shot 2017-10-20 at 8.25.49 PM.png

Awesome.  Our function is working as we had hoped and this is where I’ll wrap up this tutorial.  If you’re feeling a bit lost or if you are unable to get something similar running on your machine, comment below and I can help you out.

Next tutorial we’re going to be doing something a little more exciting.  I’ll show you how to store this data we retrieve into an object and how we can display this data onto a UITableViewController.