() translation by (you can also view the original English article)
Jika Anda telah membaca artikel sebelumnya dari seri ini, Anda harus memiliki pemahaman yang baik tentang dasar-dasar bahasa pemrograman Swift sekarang. Kami berbicara tentang variabel, konstanta, dan fungsi, dan di artikel sebelumnya kami membahas dasar-dasar pemrograman berorientasi objek di Swift.
Sementara playground adalah alat yang hebat untuk dimainkan bersama Swift dan belajar bahasa, saatnya untuk melanjutkan dan membuat proyek Swift pertama kita di Xcode. Pada artikel ini, kita akan membuat dasar dari aplikasi to-do sederhana menggunakan Xcode dan Swift. Sepanjang jalan, kita akan belajar lebih banyak tentang pemrograman berorientasi objek dan kita juga akan melihat lebih dekat integrasi antara Swift dan Objective-C.
Prasyarat
Jika Anda ingin mengikuti saya, pastikan Anda memasang Xcode 6.3 atau yang versi lebih tinggi di komputer Anda. Pada saat penulisan, Xcode 6.3 ada dalam versi beta dan tersedia dari iOS Dev Center milik Apple untuk mendaftarkan pengembang iOS.
Alasan mewajibkan Xcode 6,3 atau lebih tinggi adalah untuk dapat memanfaatkan Swift 1.2, yang diperkenalkan Apple beberapa hari yang lalu. Swift 1.2 memperkenalkan sejumlah tambahan hebat yang akan kita manfaatkan di sisa seri ini.
1. Menyiapkan Proyek
Langkah 1: Memilih Template
Jalankan Xcode 6.3 atau lebih tinggi dan pilih New > Project... dari menu File. Dari daftar template iOS Application, pilih template Single View Application dan klik Next.



Langkah 2: Mengkonfigurasi Proyek
Namai proyek ToDo dan atur Language ke Swift. Pastikan Devices diset ke iPhone dan kotak centang berlabel Use Core Data tidak dicentang. Klik Next untuk melanjutkan.



Beritahu Xcode tempat Anda ingin menyimpan proyek Anda dan klik Create di kanan bawah untuk membuat proyek Swift pertama Anda.
2. Proyek Anatomi
Sebelum melanjutkan perjalanan kita ke Swift, mari luangkan waktu untuk melihat apa yang telah diciptakan Xcode untuk kita. Jika Anda baru mengenal Xcode dan pengembangan iOS, maka sebagian besar ini akan menjadi hal baru bagi Anda. Dengan bekerja dengan proyek Swift, bagaimanapun, Anda akan mendapatkan perasaan yang lebih baik tentang bagaimana struktur dan struktur terlihat dan berperilaku seperti di Swift.
Template proyek tidak banyak berbeda dari proyek yang dibuat dengan Objective-C sebagai bahasa pemrograman. Perbedaan yang paling penting terkait dengan kelas AppDelegate
dan ViewController
.
Jika Anda pernah bekerja dengan Objective-C di masa lalu, maka Anda akan melihat bahwa template proyek berisi lebih sedikit file. Tidak ada file header (.h) atau implementasi (.m) yang dapat ditemukan di proyek kami. Di Swift, kelas tidak memiliki file header yang terpisah dimana antarmuka dideklarasikan. Sebagai gantinya, sebuah kelas dideklarasikan dan diimplementasikan dalam file .swift tunggal.
Proyek kami saat ini berisi dua file Swift, satu untuk kelas AppDelegate
, AppDelegate.swift, dan satu lagi untuk kelas ViewController
, ViewController.swift. Proyek ini juga mencakup storyboard, Main.storyboard, dan file XIB untuk layar peluncuran, LaunchScreen.xib. Kita akan mengerjakan storyboard sedikit kemudian di artikel ini. Saat ini hanya berisi adegan untuk kelas ViewController
.
Ada sejumlah file dan folder lain yang disertakan dalam proyek ini, tapi kita akan mengabaikannya untuk saat ini. Mereka tidak memainkan peran penting dalam lingkup artikel ini.
3. Inheritance
Hal pertama yang akan kita sentuh dalam artikel ini adalah inheritance, paradigma umum dalam pemrograman berorientasi objek. Di Swift, hanya class yang bisa mewarisi dari class lain. Dengan kata lain, structure dan enumeration tidak mendukung inheritance. Inilah salah satu perbedaan utama antara class dan structure.
Buka ViewController.swift untuk melihat contoh inheritance secara langsung. Antarmuka dan implementasi class ViewController
cukup terlihat jelas, yang akan memudahkan kita untuk fokus pada hal yang penting.
UIKit
Di bagian atas ViewController.swift, Anda harus melihat pernyataan impor untuk framework UIKit. Ingat bahwa framework UIKit menyediakan infrastruktur untuk membuat aplikasi iOS fungsional. Pernyataan import di bagian atas membuat infrastruktur ini tersedia bagi kita di ViewController.swift.
1 |
import UIKit |
Superclass
Di bawah pernyataan import, kita mendefinisikan class baru bernama ViewController. Tanda titik dua setelah nama class tidak terjemahkan adalah tipe seperti yang kita lihat sebelumnya di seri ini. Sebagai gantinya, class setelah titik dua adalah superclass ViewController
. Dengan kata lain, potongan berikut bisa dibaca saat kita mendefinisikan sebuah class bernama ViewController
yang mewarisi dari UIViewController
.
1 |
class ViewController: UIViewController { |
2 |
|
3 |
}
|
Ini juga menjelaskan adanya pernyataan import di bagian atas ViewController.swift karena class UIViewController
didefinisikan dalam framework UIKit.
Override
Class ViewController
saat ini mencakup dua metode, namun perhatikan bahwa setiap metode diawali dengan kata kunci override
. Ini menunjukkan bahwa metode didefinisikan di class superclass-atau lebih tinggi dari inheritance tree-dan diganti oleh class ViewController
.
1 |
class ViewController: UIViewController { |
2 |
|
3 |
override func viewDidLoad() { |
4 |
super.viewDidLoad() |
5 |
}
|
6 |
|
7 |
override func didReceiveMemoryWarning() { |
8 |
super.didReceiveMemoryWarning() |
9 |
}
|
10 |
}
|
Konstruksi override
tidak ada di Objective-C. Dalam Objective-C, Anda menerapkan metode yang diganti dalam subkelas tanpa secara eksplisit menunjukkan bahwa metode tersebut menggantikan metode yang lebih tinggi dari iheritence tree. Objective-C runtime akan menangani sisanya.
Hal yang sama juga berlaku di Swift, namun kata kunci override
menambahkan keamanan pada metode overriding. Karena kita telah mengawali metode viewDidLoad
dengan kata kunci override
, Swift mengharapkan metode ini di class superclass atau lebih tinggi dari inheritance tree. Sederhananya, jika Anda mengganti metode yang tidak ada di inheritance tree, Swift akan menampilkan kesalahan. Anda bisa mengujinya dengan salah menuliskan metode viewDidLoad
seperti gambar di bawah ini.



4. Antarmuka Pengguna
Mendeklarasikan Outlet
Mari kita tambahkan tampilan tabel ke view controller untuk menampilkan daftar item to-do. Sebelum kita melakukannya, kita perlu membuat outlet untuk tampilan tabel. Outlet tidak lebih dari properti yang dapat dilihat dan dapat diatur dalam Interface Builder. Untuk menyatakan outlet di class ViewController
, kita awali properti, variabel, dengan atribut @IBOutlet
.
1 |
class ViewController: UIViewController { |
2 |
@IBOutlet var tableView: UITableView! |
3 |
|
4 |
override func viewDidLoad() { |
5 |
super.viewDidLoad() |
6 |
}
|
7 |
|
8 |
override func didReceiveMemoryWarning() { |
9 |
super.didReceiveMemoryWarning() |
10 |
}
|
11 |
}
|
Perhatikan bahwa outlet adalah pilihan yang secara implisit tidak terbungkus. Terus Apa? Mari saya mulai dengan mengatakan bahwa outlet selalu perlu menjadi tipe optional. Alasannya sederhana saja. Setiap properti kelas ViewController
perlu memiliki nilai setelah inisialisasi. Namun, outlet hanya terhubung ke antarmuka pengguna saat runtime setelah instance ViewController
diinisialisasi sehingga menjadi tipe optional.
Tunggu sebentar. Outlet tableView
dideklarasikan sebagai pilihan yang secara implisit tidak terbaca, bukan optional. Tidak masalah. Kita dapat mendeklarasikan outlet tableView
sebagai optional dengan mengganti tanda seru pada cuplikan di atas dengan tanda tanya. Itu akan mengkompilasi dengan baik. Namun, ini juga berarti bahwa kita perlu secara eksplisit membuka properti setiap kali kita ingin mengakses nilai yang tersimpan dalam pilihan. Ini akan cepat menjadi tidak praktis dan verbose.
Sebagai gantinya, kita mendeklarasikan outlet tableView
sebagai pilihan yang secara implisit tidak terbaca, yang berarti bahwa kita tidak perlu secara eksplisit membuka pilihan jika kita perlu mengakses nilainya. Singkatnya, pilihan yang secara implisit tidak terbungkus opsional, tapi kita bisa mengakses nilai yang tersimpan dalam pilihan seperti variabel biasa. Yang penting untuk diingat adalah aplikasi Anda akan macet jika Anda mencoba mengakses nilainya jika tidak ada nilai yang telah ditetapkan. Jadi seperti itu. Jika outlet tersambung dengan benar, bagaimanapun, kita dapat memastikan bahwa outlet diatur saat pertama kali kita mencoba mengaksesnya.
Menghubungkan Outlet
Dengan outlet yang dideklarasikan, saatnya untuk menghubungkannya di Interface Builder. Buka Main.storyboard, dan pilih view controller. Pilih Embed In > Navigation Controller dari menu Editor. Ini akan mengatur kontroler tampilan sebagai pengendali tampilan akar dari pengontrol navigasi. Jangan khawatir tentang ini untuk saat ini.
Tarik contoh UITableView
dari Object Library ke tampilan pengontrol tampilan, dan tambahkan batasan tata letak yang diperlukan. Dengan tampilan tabel yang dipilih, buka the Connections Inspector dan atur table view dataSource
dan delegate
outlet ke view controller.



Dengan Connections Inspector masih terbuka, pilih view controller dan hubungkan outlet tableView
ke tampilan tabel yang baru saja kita tambahkan. Ini akan menghubungkan outlet tableView
dari class ViewController
ke tampilan tabel.
5. Protocol
Sebelum kita dapat membangun dan menjalankan aplikasi, kita perlu menerapkan protokol UITableViewDataSource
dan UITableViewDelegate
di kelas ViewController
. Ini melibatkan beberapa hal.
Langkah 1: Sesuai dengan Protocol
Kita perlu memberitahu compiler bahwa class ViewController
sesuai dengan protocol UITableViewDataSource
dan UITableViewDelegate
. Sintaksnya mirip dengan Objective-C.
1 |
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { |
2 |
...
|
3 |
}
|
Protokol yang sesuai dengan kelas terdaftar setelah superclass, UIViewController
pada contoh di atas. Jika class tidak memiliki superclass, yang tidak biasa di Swift, maka protocolnya terdaftar segera setelah nama class dan titik dua.
Langkah 2: Implementasi Protocol UITableViewDataSource
Karena protocol UITableViewDelegate
tidak mendefinisikan metode yang diperlukan, kita hanya akan menerapkan protocol UITableViewDataSource
untuk saat ini. Sebelum melakukannya, mari buat properti variabel untuk menyimpan item tugas yang akan kita cantumkan dalam tampilan tabel.
1 |
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { |
2 |
@IBOutlet var tableView: UITableView! |
3 |
|
4 |
var items: [String] = [] |
5 |
|
6 |
...
|
7 |
}
|
Kita mendeklarasikan properti variabel items
dari tipe [String]
dan menetapkan sebuah array kosong, []
, sebagai nilai awal. Ini seharusnya terlihat familier sekarang. Selanjutnya, mari kita terapkan dua metode yang dibutuhkan dari protokol UITableViewDataSource
.
Metode pertama yang dibutuhkan, numberOfRowsInSection(_:)
, mudah dilakukan. Kita hanya mengembalikan jumlah item yang tersimpan dalam properti items
.
1 |
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { |
2 |
return self.items.count |
3 |
}
|
Metode kedua yang dibutuhkan, cellForRowAtIndexPath(_:)
, perlu sedikit lebih jelas. Dengan menggunakan sintaks subscript, kami meminta item yang benar dari item to-do.
1 |
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { |
2 |
// Fetch Item
|
3 |
let item = self.items[indexPath.row] |
4 |
|
5 |
// Dequeue Table View Cell
|
6 |
let tableViewCell = tableView.dequeueReusableCellWithIdentifier("TableViewCell", forIndexPath: indexPath) as! UITableViewCell |
7 |
|
8 |
// Configure Table View Cell
|
9 |
tableViewCell.textLabel?.text = item |
10 |
|
11 |
return tableViewCell |
12 |
}
|
Kita kemudian meminta tampilan tabel untuk cell dengan identifier "TableViewCell"
, meneruskan indeks path untuk baris saat ini. Perhatikan bahwa kita menyimpan cell secara konstan bernama tableViewCell
. Tidak perlu mendeklarasikan tableViewCell
sebagai variabel.
Detail penting lainnya adalah bahwa kita menurunkan nilai pengembalian dequeueReusableCellWithIdentifier(_:forIndexPath:)
ke UITableViewCell
karena mengembalikan sebuah objek tipe AnyObject
, yang setara dengan id
di Objective-C. Untuk men-downcast AnyObject
ke UITableViewCell
, kita menggunakan kata kunci as
.
Kita bisa menggunakan as?
varian untuk downcast ke tipe optional, tapi karena kita dapat yakin bahwa dequeueReusableCellWithIdentifier(_:forIndexPath :)
selalu mengembalikan instance yang diinisialisasi dengan benar, kita bisa menggunakannya kata kunci as!
, secara implisit membuka bungkus hasil pemanggilan metode.
Pada baris kode berikutnya, kita mengkonfigurasi sel tampilan tabel, mengatur teks label teks dengan nilai item
. Perhatikan bahwa di Swift properti textLabel
dari UITableViewCell
dideklarasikan sebagai tipe optional dengan tanda tanya. Baris kode ini bisa dibaca seperti mengatur properti teks label text
menjadi item
jika textLabel
tidak sama dengan nil
. Dengan kata lain, properti teks label text
hanya disetel jika textLabel
tidak nil
. Ini adalah konstruksi keamanan yang sangat nyaman di Swift yang dikenal sebagai optional chaining.
Langkah 3: Cell Reuse
Ada dua hal yang perlu kita urutkan sebelum membangun aplikasi. Pertama, kita perlu memberi tahu tampilan tabel bahwa perlu menggunakan class UITableViewCell
untuk membuat sel tampilan tabel baru. Kita melakukan ini dengan meminta registerClass(_:forCellReuseIdentifier:)
, lulus di class UITableViewCell
dan pengenal ulang yang kita gunakan sebelumnya, "TableViewCell"
. Perbarui metode viewDidLoad
seperti gambar di bawah ini.
1 |
override func viewDidLoad() { |
2 |
super.viewDidLoad() |
3 |
|
4 |
// Register Class for Cell Reuse
|
5 |
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "TableViewCell") |
6 |
}
|
Langkah 4: Menambahkan Item
Saat ini kami tidak memiliki item untuk ditampilkan dalam table view. Hal ini mudah dipecahkan dengan mengisi properti items
dengan beberapa to-do item. Ada beberapa cara untuk melakukannya. Saya telah memilih untuk mengisi properti items
dalam metode viewDidLoad
seperti yang ditunjukkan di bawah ini.
1 |
override func viewDidLoad() { |
2 |
super.viewDidLoad() |
3 |
|
4 |
// Populate Items
|
5 |
self.items = ["Buy Milk", "Finish Tutorial", "Play Minecraft"] |
6 |
|
7 |
// Register Class for Cell Reuse
|
8 |
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "TableViewCell") |
9 |
}
|
6. Build dan Run
Sudah waktunya untuk mengambil aplikasi kita untuk dijalankan. Pilih Run dari menu Product di Xcode atau tekan Command-R. Jika Anda mengikuti dan Anda menggunakan Swift 1.2, Anda harus akan melihat hasil seperti hasil berikut.



Perhatikan bahwa saya telah menambahkan judul, To Do, di bagian atas tampilan di bilah navigasi. Anda bisa melakukan hal yang sama dengan menyetel properti title
dari instance ViewController
dalam metode viewDidLoad
.
1 |
override func viewDidLoad() { |
2 |
super.viewDidLoad() |
3 |
|
4 |
// Set Title
|
5 |
self.title = "To Do" |
6 |
|
7 |
// Populate Items
|
8 |
self.items = ["Buy Milk", "Finish Tutorial", "Play Minecraft"] |
9 |
|
10 |
// Register Class for Cell Reuse
|
11 |
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "TableViewCell") |
12 |
}
|
Pelajari Lebih Lanjut di Kursus Pemrograman Swift Kami
Jika Anda tertarik untuk mengikuti kursus Swift Anda ke tingkat berikutnya, Anda dapat melihat kursus lengkap kami tentang pengembangan Swift.
Kesimpulan
Meskipun kita telah membuat aplikasi sederhana, Anda telah mempelajari beberapa hal baru. Kita telah mengeksplorasi metode inheritance dan overriding. Kita juga membahas protokol dan cara mengadopsi protocol UITableViewDataSource
di class ViewController
. Hal terpenting yang telah Anda pelajari adalah bagaimana berinteraksi dengan API Objective-C.
Penting untuk dipahami bahwa API SDK iOS ditulis dalam Objective-C. Swift dirancang agar kompatibel dengan API ini. Berdasarkan kegagalan masa lalu, Apple mengerti bahwa Swift harus bisa menghubungkan ke iOS SDK tanpa harus menulis ulang setiap API di Swift.
Menggabungkan Objective-C dan Swift adalah hal yang memungkinkan, namun ada beberapa keberatan yang akan kita jelajahi secara lebih rinci saat kita melangkah maju. Karena fokus Swift yang tanpa henti terhadap keselamatan, kita perlu beberapa rintangan dari waktu ke waktu. Namun, tidak satu pun dari rintangan ini terlalu besar untuk diambil seperti yang akan kita temukan di artikel berikutnya di mana kita terus mengerjakan aplikasi to-do kita.