View on GitHub

Mobile App Development (MAD)

Mobile App Development class for University of Applied Sciences Vienna

TableView Exercise

In this exercise, you’ll do a few things:

The main goal of these tasks is to learn the following things:

Deadline

See the deadline on the exercises page.

Submission instructions

See the submission instructions on the exercises page.

API Key, Username, Password

In this exercise, we’re going to use the REST API of the Google Firebase service. Specifically, we’re going to use this endpoint to download a list of data. You shouldn’t necessarily have to dig through the docs above to be able to complete this exercise. Everything you need should be in the instructions below, but the above link might still help you understand the inner workings of the API.

When using the API, build upon your code of the previous exercises and use the same credentials as in the REST exercise.

Resources

Instructions, Requirements and Hints

Setting up the project

Fixing the big UI problem from the Login Exercise

Maybe you can remember: I mentioned in the Login Exercise that there’s a critical UI problem in the current login screen. When we select one of the UITextFields, the keyboard might cover the UI elements (especially on smaller devices or when in landscape orientation). When this happens, there’s no obvious way for the user to get out of this state or dismiss the keyboard - the only way to continue is to force quit the application! In that sense, this bug is even worse than a crash, so we definitely want to fix it.

To fix this, we want to embed all the UI elements in a UIScrollView. This way, we can scroll the content when the keyboard is visible and the screen space is too small to fit it all.

Adding the UIScrollView

Adjusting for keyboard changes

Adding navigation

We want our login screen to actually lead somewhere. In this part of the exercise, you’re going to create a new UIViewController and a UINavigationController to navigate between the LoginViewController and the newly created viewController.

Downloading the list of countries

Next, we want to download some data to display in our newly created viewController. In this part of the exercise, we’re going to use the firebase API (specifically, this endpoint) from the last exercise to download a list of countries.

{
	"documents": [{
		"name": "projects/mad-course-3ceb1/databases/(default)/documents/countries/05GmkD91SrjOR2wyTn8u",
		"fields": {
			"name": {
				"stringValue": "Jamaica"
			},
			"languages": {
				"arrayValue": {
					"values": [{
						"stringValue": "en"
					}]
				}
			},
			"currency": {
				"stringValue": "JMD"
			},
			"capital": {
				"stringValue": "Kingston"
			},
			"native": {
				"stringValue": "Jamaica"
			},
			"continent": {
				"stringValue": "NA"
			},
			"phone": {
				"stringValue": "1876"
			}
		},
		"createTime": "2019-10-09T17:50:13.139043Z",
		"updateTime": "2019-10-09T17:50:13.139043Z"
	},
	...
	...
	...
	...
	...
	]
}
struct Country: Decodable {
	var ID: String
	var name: String
	var currency: String
	var capital: String
	var native: String
	var continent: String
	var phone: String
	var createTime: Date
	var updateTime: Date
	var languages: [String]
}
    struct DocumentsContainer: Decodable {
        var documents: [Country]
    }
	private enum RootCodingKeys: String, CodingKey {
		case ID = "name"
		case createTime
		case updateTime
		case fields
	}
        init(from decoder: Decoder) throws {
            let rootContainer = try decoder.container(keyedBy: RootCodingKeys.self)
            ID = (try rootContainer.decode(String.self, forKey: .ID) as NSString).lastPathComponent
            // decode other properties...
        }
private enum NestedCodingKeys: String, CodingKey {
	case name
	case currency
	case capital
	case native
	case continent
	case phone
	case languages
}

private enum StringValueCodingKeys: String, CodingKey {
	case stringValue
}

private enum ArrayValueCodingKeys: String, CodingKey {
	case arrayValue
}

private enum ArrayValueNestedCodingKeys: String, CodingKey {
	case values
}

let nestedContainer = try rootContainer.nestedContainer(keyedBy: NestedCodingKeys.self, forKey:.fields)

Adding the tableView

In this part of the exercise, we’re going to create a UITableView to display our countries.

Adding a detail view

In the last part of this exercise, we’ll create a detailed viewController and view for each country. This viewController should display all the available information for each country.

Help and Support

As always, if you need any help or have any questions, feel free to contact me. I’m happy to help!