iOS App with Kotlin/Native: Getting Started
In this tutorial, you’ll build an iOS app using Kotlin/Native. You’ll also take a look at the AppCode IDE from JetBrains! By Eric Crawford.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
iOS App with Kotlin/Native: Getting Started
30 mins
- Getting Started
- Using Kotlin/Native
- Build Phase Script
- Gradle Build Script
- Necessary iOS Classes
- Adding a MKMapView to the Storyboard
- Creating the ViewController
- Using AppCode for Kotlin/Native
- Fleshing out the ViewController
- Wiring up the Storyboard
- Adding an Objective-C Third-Party Library
- Making Network Requests
- Where to Go From Here?
Adding a MKMapView to the Storyboard
First you’ll add a MKMapview component to the storyboard. This will show the locations of the Meteorites. Open Main.storyboard and delete the label hello.
Note: You may or may not have heard of a storyboard when it comes to iOS development. If you haven’t, just think of it as a file used to visually create your app’s layout.
Note: You may or may not have heard of a storyboard when it comes to iOS development. If you haven’t, just think of it as a file used to visually create your app’s layout.
In the Xcode toolbar, click on the Library button. When a pop-up appears, search for Map Kit View (which corresponds to MKMapView) like below:
Next, drag the Map Kit View to the phone scene where you just deleted the label. Then, drag the edges of the Map Kit View to take up the full screen.
In order to show the map correctly on different device screen sizes, you’ll need to adjust the constraints. Since you only have one view to worry about, Xcode will set the constraints for you.
Select the MKMapview component you added. Then, click on the Resolve Auto Layout Issues button on the Xcode bottom toolbar. After that, select Add Missing Constraints.
Now that the Map Kit View scene has been set in the storyboard with some constraints, you’ll next add a ViewController.
Creating the ViewController
ViewControllers are the heart of most iOS apps. They are similar to Activities on Android.
You are going to create a ViewController in Kotlin. Since Xcode does not understand Kotlin source code, you will have to create an empty file for your ViewController.
Right-click on the kotlin folder and select New File…. In the template window, scroll down to Other section and select Empty and click Next. Name the file MeteoriteMapViewController.kt, then click Create.
Add the following code to the new file:
// 1
import kotlinx.cinterop.ExportObjCClass
import kotlinx.cinterop.ObjCObjectBase.OverrideInit
import kotlinx.cinterop.ObjCOutlet
import platform.Foundation.*
import platform.UIKit.*
import platform.MapKit.*
// 2
@ExportObjCClass
class MeteoriteMapViewController : UIViewController, MKMapViewDelegateProtocol {
// 3
@OverrideInit
constructor(coder: NSCoder) : super(coder)
// 4
override fun viewDidLoad() {
super.viewDidLoad()
}
}
Here is what you added:
- Imports for Kotlin to interop with Objective-C and some of the Cocoa Touch frameworks.
- The class inherits from
UIVIewController
and conforms toMKMapViewDelegateProtocol
. The@ExportObjCClass
annotation helps Kotlin create a class that is visible for lookup at runtime. - Overrides the
UIViewController
initializer with a Kotlin constructor. - Overrides the
viewDidLoad()
method.
Hold on a second! Something is missing, here. Where is the syntax highlighting and code completions?
Luckily, the creators of Kotlin can help you out here via the AppCode IDE.
Using AppCode for Kotlin/Native
AppCode is JetBrains dedicated iOS development IDE. It supports Objective-C, Swift and our friend Kotlin (with a plugin). Head over to the AppCode download site to download and install the latest stable version.
Note: Unfortunately AppCode is not free. There is a 30-day trial of the production version.
Note: Unfortunately AppCode is not free. There is a 30-day trial of the production version.
With AppCode installed, you need to install the Kotlin/Native IDE plugin. Open AppCode, then click Configure ▸ Plugins to show the plugins window.
Now, click on Install JetBrains plugin and then search for kotlin native. The results should include the Kotlin/Native for AppCode plugin:
Go ahead and click Install to install the plugin, and when it’s done installing, restart AppCode. Once restarted, select Open Project and navigate to the root folder of your MeteoriteFinder project (the one that contains the MeteoriteFinder.xcodeproj file) and click Open. Once the project is open, you can expand the folder structure and explore the layout. If you already use Android Studio or IntelliJ IDEA, AppCode will look very familiar.
Fleshing out the ViewController
With AppCode open and ready, it’s time to get back to the project. Double-click on MeteoriteMapViewController.kt
and bask in the syntax highlighting provided by the Kotlin/Native plugin and all its glory.
Note: At this point, you may see red underlining under super(coder)
. This is a false positive, and you may see more through out this tutorial. The Kotlin/Native plugin is in active development and is still in beta. Valid errors will be caught by the compiler when you build/run the project. Also, full syntax highlighting may not show up immediately, but instead only after a short time, once AppCode has fully integrated the Kotlin/Native plugin. The syntax highlighting may also intermittantly not show up fully, due to the beta nature of the plugin.
Note: At this point, you may see red underlining under super(coder)
. This is a false positive, and you may see more through out this tutorial. The Kotlin/Native plugin is in active development and is still in beta. Valid errors will be caught by the compiler when you build/run the project. Also, full syntax highlighting may not show up immediately, but instead only after a short time, once AppCode has fully integrated the Kotlin/Native plugin. The syntax highlighting may also intermittantly not show up fully, due to the beta nature of the plugin.
Under the constructor, add the following:
@ObjCOutlet
lateinit var mapView: MKMapView
The @ObjCOutlet
annotation sets the mapView
property as an outlet. This allows you to link the MKMapview from the storyboard to this property. The mapView
property will be initialized at a later time than the ViewController is created, so you use the lateinit
keyword.
In the viewDidLoad()
method, add the following under super.viewDidLoad()
:
// 1
val center = CLLocationCoordinate2DMake(38.8935754, -77.0847873)
val span = MKCoordinateSpanMake(0.7, 0.7)
val region = MKCoordinateRegionMake(center, span)
// 2
with(mapView){
delegate = this@MeteoriteMapViewController
setRegion(region, true)
}
Going through this, step by step:
- Create
center
,span
andregion
properties that will be used to position the viewable area ofmapView
. - Use the Kotlin standard library
with
function, to scope and setup a couple of themapView
properties. Inside the scope, you set themapView
delegate equal to thisMeteoriteMapViewController
and set the region of themapView
.
CLLocationCoordinate2DMake
is from a different module, and you will need to import from the CoreLocation module to make the compiler happy. You can write the import at the top of the file:
import platform.CoreLocation.CLLocationCoordinate2DMake
Or instead you can let the IDE add the import for you by setting your cursor on CLLocationCoordinate2DMake
and hitting option+return at the same time on your keyboard.
Since MeteoriteMapViewController
conforms to MKMapViewDelegateProtocol
, setting the mapView
delegate to this class allows MeteoriteMapViewController
to receive callback events from mapView
.
To conform to the protocol, first implement the method mapViewDidFailLoadingMap()
, just in case the map fails to load. Add the following under the viewDidLoad()
method:
override fun mapViewDidFailLoadingMap(mapView: MKMapView, withError: NSError) {
NSLog("Error loading map: $withError")
}
Next, you’ll create a method that will insert mock data to be displayed on the map. Add the following method call to the end of viewDidLoad()
:
createAnnotation()
The method call should display red because it isn’t declared yet. Time to do so! Select the method, then press option+return at the same time. In the context menu, select Create function ‘createAnnotation’.
Inside the new createAnnotation()
method, delete the TODO
template code and add the following:
// 1
val annotation = MKPointAnnotation().apply {
setCoordinate(CLLocationCoordinate2DMake(38.8935754, -77.0847873))
setTitle("My mock meteorite")
setSubtitle("I'm falling........")
}
// 2
mapView.addAnnotation(annotation)
In the above, you:
- Create an
MKPointAnnotation
that will represent a pin on the map. For now, you set up some mock data. - Add the
annotation
variable to themapView
. This will add a mock data pin on the map.
At this point, you’ve created a ViewController that will display a single pin on a map.
Build the project to make sure no errors are showing, by selecting Run from the toolbar and then Build.
The first build in AppCode may take a little time to complete.