Panduan Pengembang iOS: Dari Objective-C ke Belajar Swift

Diterbitkan: 2022-03-11

Pada tahun 2008 Apple mengumumkan dan merilis iPhone SDK 2.0. Acara ini memulai revolusi lain dalam pengembangan perangkat lunak, dan generasi baru pengembang lahir. Mereka sekarang diakui sebagai pengembang iOS.

Banyak dari pengembang ini belum pernah menggunakan Objective-C sebelumnya, dan itu adalah tantangan pertama yang diberikan Apple kepada mereka. Meskipun sintaks yang tidak dikenal dan manajemen memori manual, itu sangat sukses, membantu mengisi App Store dengan puluhan ribu aplikasi. Apple terus meningkatkan Objective-C dengan setiap rilis, menambahkan blok dan literal, manajemen memori yang disederhanakan dengan penghitungan referensi otomatis, dan banyak fitur lain yang menunjukkan bahasa pemrograman modern.

Dan setelah 6 tahun meningkatkan dan mengerjakan Objective-C, Apple memutuskan untuk memberikan tantangan lain kepada pengembang. Sekali lagi, pengembang iOS perlu mempelajari bahasa pemrograman baru: Swift . Swift menghapus manajemen penunjuk yang tidak aman dan memperkenalkan fitur-fitur baru yang kuat, sambil mempertahankan interaksi dengan Objective-C dan C.

Swift 1.0 sudah menjadi platform pengembangan yang stabil dan kuat, yang pasti akan berkembang dengan cara yang menarik di tahun-tahun mendatang. Ini adalah saat yang tepat untuk mulai menjelajahi bahasa baru ini karena ini jelas merupakan masa depan pengembangan iOS.

Tujuan dari tutorial ini adalah untuk memberi pengembang Objective-C gambaran umum singkat tentang fitur bahasa Swift baru, membantu Anda mengambil langkah berikutnya dan mulai mengadopsi Swift dalam pekerjaan sehari-hari Anda. Saya tidak akan menghabiskan terlalu banyak waktu untuk menjelaskan Objective-C, dan saya akan menganggap Anda sudah familiar dengan pengembangan iOS.

Swift mengubah permainan untuk pengembang Objective-C iOS.

Mencoba Swift vs. Objective-C

Untuk mulai menjelajahi Swift, yang perlu Anda lakukan hanyalah mengunduh XCode dari App Store dan membuat taman bermain untuk bereksperimen. Semua contoh yang disebutkan dalam artikel ini dilakukan dengan cara ini.

Beranda Swift Apple adalah referensi terbaik untuk mempelajari pemrograman Swift. Anda akan menganggapnya sangat berharga, dan sampai Anda sepenuhnya memahami perkembangan Swift, saya yakin Anda akan sering kembali ke sini.

Variabel dan Konstanta

Mendeklarasikan variabel di Swift dilakukan dengan menggunakan kata kunci var .

 var x = 1 var s = "Hello"

Anda akan melihat bahwa dua variabel x dan s memiliki tipe yang berbeda. x adalah Integer, sedangkan s adalah String. Swift adalah bahasa yang aman untuk tipe, dan itu akan menyimpulkan tipe variabel dari nilai yang ditetapkan. Jika Anda ingin membuat kode Anda lebih mudah dibaca, Anda dapat membubuhi keterangan jenis variabel secara opsional:

 var y: Int y = 2

Konstanta serupa, tetapi Anda mendeklarasikannya menggunakan let alih-alih var . Nilai konstanta tidak perlu diketahui pada waktu kompilasi, tetapi Anda harus menetapkan nilai tepat satu kali.

 let c1 = 1 // Constant known at compile time var v = arc4random() let c2 = v // Constant known only at run time

Seperti namanya, mereka tidak dapat diubah, jadi kode berikut akan menyebabkan kesalahan waktu kompilasi.

 let c = 1 c = 3 // error

Tipe lain juga dapat dideklarasikan sebagai konstanta. Misalnya, kode berikut mendeklarasikan array sebagai konstanta, dan jika Anda mencoba mengubah elemen apa pun, kompiler Swift akan melaporkan kesalahan:

 var arr2 = [4, 5, 6] arr2[0] = 8 print (arr2) // [8, 5, 6] let arr = [1, 2, 3] a[0] = 5 // error

Opsional

Konstanta perlu diinisialisasi saat mendeklarasikannya, dan variabel perlu diinisialisasi sebelum digunakan. Jadi di mana yang setara dengan Objective-C nil ? Swift memperkenalkan nilai opsional . Nilai opsional dapat memiliki nilai atau nil . Jika Anda melihat kode berikut, Anda akan melihat bahwa x diberi nilai Optional 2014 . Ini berarti bahwa kompiler Swift menyadari bahwa x mungkin juga nil .

 var s = "2014" var x = s.toInt() print(x) // Optional(2014)

Jika Anda membuat perubahan dalam kode ini dan menetapkan nilai "abc" ke s , yang tidak dapat dikonversi menjadi Integer, Anda akan melihat bahwa x sekarang adalah nil .

 var s = "abc" var x = s.toInt() print(x) // nil

Jenis kembalinya fungsi toInt() adalah Int? , yang merupakan Int opsional . Mari kita coba memanggil fungsi standar pada x :

 var x = "2014".toInt() print(x.successor()) // error

Kompiler memberi sinyal kesalahan, karena x adalah opsional dan berpotensi nil . Kita harus menguji x terlebih dahulu, dan memastikan bahwa fungsi successor dipanggil pada bilangan real, dan bukan nilai nil :

 var x = "2014".toInt() if x != nil { print(x!.successor()) // 2015 }

Perhatikan bahwa kita harus membuka x dengan menambahkan tanda seru (!) . Ketika kami yakin bahwa x berisi nilai, kami dapat mengaksesnya. Jika tidak, kita akan mendapatkan kesalahan runtime. Kami juga dapat melakukan apa yang disebut Swift sebagai pengikatan opsional , mengubah opsional menjadi variabel non-opsional

 let x = "123".toInt() if let y = x { print(y) }

Kode dalam pernyataan if hanya akan dieksekusi jika x memiliki nilai, dan menetapkannya ke y . Perhatikan bahwa kita tidak perlu membuka y , tipenya tidak opsional karena kita tahu x bukan nil .

Lihat tutorial Swift Apple untuk membaca detail lebih lanjut tentang opsional dan fitur bagus seperti rangkaian opsional

Interpolasi String

Dalam String pemformatan Objective-C biasanya dilakukan dengan metode stringWithFormat: ::

 NSString *user = @"Gabriel"; int days = 3; NSString *s = [NSString stringWithFormat:@"posted by %@ (%d days ago)", user, days];

Swift memiliki fitur yang disebut interpolasi string untuk melakukan hal yang sama, tetapi lebih ringkas dan lebih mudah dibaca:

 let user = "Gabriel" let days = 3 let s = "posted by \(user) \(days) ago"

Anda juga dapat menggunakan ekspresi:

 let width = 2 let height = 3 let s = "Area for square with sides \(width) and \(height) is \(width*height)"

Untuk mempelajari lebih lanjut tentang interpolasi string Swift dan fitur baru lainnya, buka di sini.

Fungsi

Definisi fungsi di Swift berbeda dengan C. Contoh definisi fungsi di bawah ini:

 func someFunction(s:String, i: Int) -> Bool { ... // code }

Fungsi Swift adalah tipe kelas satu . Ini berarti Anda dapat menetapkan fungsi ke variabel, meneruskannya sebagai parameter ke fungsi lain, atau membuatnya mengembalikan tipe:

 func stringLength(s:String) -> Int { return countElements(s) } func stringValue(s:String) -> Int { if let x = s.toInt() { return x } return 0 } func doSomething(f:String -> Int, s:String) -> Int { return f(s).successor() } let f1 = stringLength let f2 = stringValue doSomething(f1, "123") // 4 doSomething(f2, "123") // 124

Sekali lagi, Swift menyimpulkan jenis f1 dan f2 ( String -> Int ), meskipun kita dapat mendefinisikannya secara eksplisit:

 let f1:String -> Int = stringLength

Fungsi juga dapat mengembalikan fungsi lain:

 func compareGreaterThan(a: Int, b: Int) -> Bool { return a > b } func compareLessThan(a: Int, b: Int) -> Bool { return a < b } func comparator(greaterThan:Bool) -> (Int, Int) -> Bool { if greaterThan { return compareGreaterThan } else { return compareLessThan } } let f = comparator(true) println(f(5, 9))

Panduan untuk fungsi di Swift dapat ditemukan di sini.

Enumerasi

Enumerasi di Swift jauh lebih kuat daripada di Objective-C. Sebagai struct Swift, mereka dapat memiliki metode, dan diteruskan dengan nilai:

 enum MobileDevice : String { case iPhone = "iPhone", Andro, WP8 = "Windows Phone8", BB = "BlackBerry" func name() -> String { return self.toRaw() } } let m = MobileDevice.Android print(m.name()) // "Android"

Tidak seperti Objective-C, enumerasi Swift dapat menetapkan String, karakter, atau float sebagai nilai untuk setiap anggota, selain bilangan bulat. Metode toRaw() yang nyaman mengembalikan nilai yang ditetapkan untuk setiap anggota.

Enumerasi juga dapat diparameterisasi:

 enum Location { case Address(street:String, city:String) case LatLon(lat:Float, lon:Float) func description() -> String { switch self { case let .Address(street, city): return street + ", " + city case let .LatLon(lat, lon): return "(\(lat), \(lon))" } } } let loc1 = Location.Address(street: "2070 Fell St", city: "San Francisco") let loc2 = Location.LatLon(lat: 23.117, lon: 45.899) print(loc1.description()) // "2070 Fell St, San Francisco" print(loc2.description()) // "(23.117, 45.988)"

Informasi lebih lanjut tentang enumerasi tersedia di sini.

Tuple

Tuple mengelompokkan beberapa nilai menjadi satu nilai gabungan. Nilai-nilai dalam sebuah tuple dapat bertipe apa saja dan tidak harus bertipe sama satu sama lain.

 let person = ("Gabriel", "Kirkpatrick") print(person.0) // Gabriel

Anda juga dapat memberi nama masing-masing elemen Tuple:

 let person = (first: "Gabriel", last: "Kirkpatrick") print(person.first)

Tuple sangat nyaman sebagai tipe pengembalian untuk fungsi yang perlu mengembalikan lebih dari satu nilai:

 func intDivision(a: Int, b: Int) -> (quotient: Int, remainder: Int) { return (a/b, a%b) } print(intDivision(11, 3)) // (3, 2) let result = intDivision(15, 4) print(result.remainder) // 3

Tidak seperti di Objective-C, Swift mendukung pencocokan pola dalam pernyataan switch:

 let complex = (2.0, 1.1) // real and imaginary parts switch complex { case (0, 0): println("Number is zero") case (_, 0): println("Number is real") default: println("Number is imaginary") }

Dalam kasus kedua, kami tidak peduli dengan bagian bilangan asli, jadi kami menggunakan _ untuk mencocokkan apa pun. Anda juga dapat memeriksa kondisi tambahan dalam setiap kasus. Untuk itu kita perlu mengikat nilai pola ke konstanta:

 let complex = (2.0, 1.1) switch complex { case (0, 0): println("Number is zero") case (let a, 0) where a > 0: println("Number is real and positive") case (let a, 0) where a < 0: println("Number is real and negative") case (0, let b) where b != 0: println("Number has only imaginary part") case let (a, b): println("Number is imaginary with distance \(a*a + b*b)") }

Perhatikan bagaimana kita perlu mengikat hanya nilai yang akan kita gunakan dalam perbandingan atau dalam pernyataan kasus.

Untuk membaca lebih lanjut tentang tupel, buka di sini.

Kelas dan Struktur

Tidak seperti Objective-C, Swift tidak mengharuskan Anda membuat antarmuka dan file implementasi terpisah untuk kelas dan struktur khusus. Saat Anda mempelajari Swift, Anda akan belajar mendefinisikan kelas atau struktur dalam satu file, dan antarmuka eksternal ke kelas atau struktur tersebut secara otomatis tersedia untuk digunakan kode lain.

Mendefinisikan Kelas

Definisi kelas sangat sederhana:

 class Bottle { var volume: Int = 1000 func description() -> String { return "This bottle has \(volume) ml" } } let b = Bottle() print(b.description())

Seperti yang Anda lihat, deklarasi dan implementasi berada dalam file yang sama . Swift tidak lagi menggunakan file header dan implementasi. Mari tambahkan label ke contoh kita:

 class Bottle { var volume: Int = 1000 var label:String func description() -> String { return "This bottle of \(label) has \(volume) ml" } }

Kompiler akan mengeluh karena label adalah variabel non-opsional dan tidak akan memiliki nilai saat Botol dipakai. Kita perlu menambahkan penginisialisasi:

 class Bottle { var volume: Int = 1000 var label:String init(label:String) { self.label = label } func description() -> String { return "This bottle of \(label) has \(volume) ml" } }

Atau, kita bisa menggunakan tipe Optional untuk properti, yang tidak diinisialisasi. Dalam contoh berikut kami membuat volume menjadi Optional Integer :

 class Bottle { var volume: Int? var label:String init(label:String) { self.label = label } func description() -> String { if self.volume != nil { return "This bottle of \(label) has \(volume!) ml" } else { return "A bootle of \(label)" } } }

Struktur

Bahasa Swift juga memiliki structs , tetapi mereka jauh lebih fleksibel daripada di Objective-C. Tutorial kode berikut mendefinisikan sebuah struct :

 struct Seat { var row: Int var letter:String init (row: Int, letter:String) { self.row = row self.letter = letter } func description() -> String { return "\(row)-\(letter)" } }

Seperti kelas di Swift, struktur dapat memiliki metode, properti, inisialisasi, dan sesuai dengan protokol. Perbedaan utama antara kelas dan struktur adalah bahwa kelas dilewatkan dengan referensi, sedangkan struct dilewatkan dengan nilai .

Contoh ini menunjukkan kelas yang lewat dengan referensi:

 let b = Bottle() print(b.description()) // "b" bottle has 1000 ml var b2 = b b.volume = 750 print(b2.description()) // "b" and "b2" bottles have 750 ml

Jika kami mencoba kasus serupa dengan struct , Anda akan melihat bahwa variabel dilewatkan oleh nilai:

 var s1 = Seat(row: 14, letter:"A") var s2 = s1 s1.letter = "B" print(s1.description()) // 14-B print(s2.description()) // 14-A

Kapan kita harus menggunakan struct dan kapan kita harus menggunakan class ? Seperti pada Objective-C dan C, gunakan struct saat Anda perlu mengelompokkan beberapa nilai, dan berharap nilai tersebut disalin daripada direferensikan. Misalnya, bilangan kompleks, titik 2D atau 3D, atau warna RGB.

Sebuah instance dari kelas secara tradisional dikenal sebagai objek. Namun, kelas dan struktur Swift memiliki fungsionalitas yang lebih dekat daripada bahasa lain, dan banyak fungsi dapat diterapkan pada instance kelas atau tipe struktur. Karena itu, istilah yang lebih umum yang digunakan dalam referensi Swift adalah instance , yang berlaku untuk salah satu dari keduanya.

Pelajari dasar-dasar kelas dan struktur Swift di sini.

Properti

Seperti yang kita lihat sebelumnya, properti di Swift dideklarasikan dengan kata kunci var di dalam definisi kelas atau struct. Kita juga dapat mendeklarasikan konstanta dengan pernyataan let .

 struct FixedPointNumber { var digits: Int let decimals: Int } var n = FixedPointNumber(digits: 12345, decimals: 2) n.digits = 4567 // ok n.decimals = 3 // error, decimals is a constant

Juga perlu diingat bahwa properti kelas sangat direferensikan, kecuali jika Anda mengawalinya dengan kata kunci yang weak . Namun ada beberapa kehalusan dengan properti non-opsional yang lemah, jadi baca bab penghitungan referensi otomatis di panduan Swift Apple.

Properti yang Dihitung

Properti yang dihitung sebenarnya tidak menyimpan nilai. Sebagai gantinya, mereka menyediakan pengambil dan penyetel opsional untuk mengambil dan menyetel properti dan nilai lain secara tidak langsung.

Kode berikut memberikan contoh sign nilai yang dihitung:

 enum Sign { case Positive case Negative } struct SomeNumber { var number:Int var sign:Sign { get { if number < 0 { return Sign.Negative } else { return Sign.Positive } } set (newSign) { if (newSign == Sign.Negative) { self.number = -abs(self.number) } else { self.number = abs(self.number) } } } }

Kami juga dapat mendefinisikan properti read-only hanya dengan mengimplementasikan getter:

 struct SomeNumber { var number:Int var isEven:Bool { get { return number % 2 == 0 } } }

Di Objective-C, properti biasanya didukung oleh variabel instan, dideklarasikan secara eksplisit atau otomatis dibuat oleh kompiler. Di Swift, di sisi lain, properti tidak memiliki variabel instan yang sesuai . Artinya, backing store dari sebuah properti tidak dapat diakses secara langsung. Misalkan kita memiliki ini di Objective-C

 // .h @interface OnlyInitialString : NSObject @property(strong) NSString *string; @end // .m @implementation OnlyInitialString - (void)setString:(NSString *newString) { if (newString.length > 0) { _string = [newString substringToIndex:1]; } else { _string = @""; } } @end

Karena, di Swift, properti yang dihitung tidak memiliki penyimpanan cadangan, kita perlu melakukan sesuatu seperti ini:

 class OnlyInitialString { var initial:String = "" var string:String { set (newString) { if countElements(newString) > 0 { self.initial = newString.substringToIndex(advance(newString.startIndex, 1)) } else { self.initial = "" } } get { return self.initial } } }

Properti dijelaskan lebih detail di sini

Bersambung

Ada banyak hal baru yang lebih penting untuk dipelajari di Swift, seperti Generik, interaksi dengan pustaka Objective-C, penutupan, rangkaian opsional, dan kelebihan beban operator. Satu tutorial tidak dapat menjelaskan secara menyeluruh bahasa baru, tetapi saya yakin akan lebih banyak lagi yang akan ditulis tentang mempelajari pemrograman Swift. Namun, saya percaya bahwa membaca cepat ini akan membantu banyak pengembang Objective-C, yang belum berhasil menemukan waktu dan mempelajari detail bahasa Swift, mengikuti jalurnya dan membiarkan burung Swift membawa mereka ke tingkat yang lebih tinggi.