1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
|
---
language: swift
contributors:
- ["Özgür Şahin", "https://github.com/ozgurshn/"]
filename: learnswift-tr.swift
lang: tr-tr
---
Swift iOS ve OSX platformlarında geliştirme yapmak için Apple tarafından oluşturulan yeni bir programlama dilidir. Objective - C ile beraber kullanılabilecek ve de hatalı kodlara karşı daha esnek bir yapı sunacak bir şekilde tasarlanmıştır. Swift 2014 yılında Apple'ın geliştirici konferansı WWDC de tanıtıldı. Xcode 6+'a dahil edilen LLVM derleyici ile geliştirildi.
Apple'ın resmi [Swift Programlama Dili](https://itunes.apple.com/us/book/swift-programming-language/id881256329) kitabı Apple Books'ta yerini aldı.
Ayrıca Swift ile gelen tüm özellikleri görmek için Apple'ın [başlangıç kılavuzu](https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/RoadMapiOS/index.html)na bakmanızda yarar var.
```swift
// modülü import etme
import UIKit
//
// MARK: Temeller
//
//XCode işaretlemelerle kodunuzu bölümlere ayırmanızı ve sağ üstteki metot
//listesinde gruplama yapmanıza olanak sağlıyor
// MARK: Bölüm işareti
// TODO: Daha sonra yapılacak
// FIXME: Bu kodu düzelt
//Swift 2 de, println ve print metotları print komutunda birleştirildi.
//Print otomatik olarak yeni satır ekliyor.
print("Merhaba dünya") // println print olarak kullanılıyor.
print("Merhaba dünya", appendNewLine: false) // yeni bir satır eklemeden yazar.
// variables (var) değer atandıktan sonra değiştirilebilir.
// constants (let) değer atndıktan sonra değiştirilemez.
var degiskenim = 42
let øπΩ = "deger" // unicode degişken adları
let π = 3.1415926
let convenience = "keyword" // bağlamsal değişken adı
let isim = "ahmet"; let soyad = "un" // farklı ifadeler noktalı virgül
kullanılarak ayrılabilir.
let `class` = "keyword" // rezerve edilmiş keywordler tek tırnak içerisine
alınarak değişken adı olarak kullanılabilir
let doubleOlduguBelli: Double = 70
let intDegisken = 0007 // 7
let largeIntDegisken = 77_000 // 77000
let etiket = "birseyler " + String(degiskenim) // Cast etme
let piYazi = "Pi = \(π), Pi 2 = \(π * 2)" // String içerisine değiken yazdırma
// Builde özel değişkenler
// -D build ayarını kullanır.
#if false
print("yazılmadı")
let buildDegiskeni= 3
#else
let buildDegiskeni = 7
#endif
print("Build degiskeni: \(buildDegiskeni)") // Build degeri: 7
/*
Optionals Swift dilinde bazı değerleri veya yokluğu (None) bir değişkende
tutmanıza olanak sağlar.
Swift'te her bir degişkeninin bir değeri olması gerektiğinden, nil değeri
bile Optional değer olarak saklanır.
Optional<T> bir enum'dır.
*/
var baziOptionalString: String? = "optional" // nil olabilir.
// yukarıdakiyle aynı ama ? bir postfix (sona eklenir) operatördür. (kolay
//okunabilir)
var someOptionalString2: Optional<String> = "optional"
if baziOptionalString != nil {
// ben nil değilim
if baziOptionalString!.hasPrefix("opt") {
print("ön eki var")
}
let bos = baziOptionalString?.isEmpty
}
baziOptionalString = nil
// belirgin olarak acilan(unwrap) opsiyonel (optional) değer
var acilanString: String! = "Değer bekleniliyor"
//yukarıdakiyle aynı ama ! bir postfix operatördür (kolay okunabilir)
var acilanString2: ImplicitlyUnwrappedOptional<String> = "Değer bekleniliyor."
if let baziOpsiyonelSabitString = baziOptionalString {
// eğer bir değeri varsa, nil değilse
if ! baziOpsiyonelSabitString("tamam") {
// ön eke sahip değil
}
}
// Swift değişkenlerde herhangi bir tip saklanabilir.
// AnyObject == id
// Objective-C deki `id` den farklı olarak, AnyObject tüm değişkenlerle
//çalışabilir
(Class, Int, struct, etc)
var herhangiBirObject: AnyObject = 7
herhangiBirObject = "Değer string olarak değişti, iyi bir yöntem değil ama mümkün"
/*
Yorumlar buraya
/*
İç içe yorum yazılması da mümkün
*/
*/
//
// MARK: Koleksiyonlar
//
/*
Array ve Dictionary tipleri aslında structdırlar. Bu yüzden `let` ve `var`
ayrıca bu tipleri tanımlarken değişebilir(var) veya değişemez(let)
olduğunu belirtir.
*/
// Diziler
var liste = ["balik", "su", "limon"]
liste[1] = "şişe su"
let bosDizi = [String]() // let == değiştirilemez
let bosDizi2 = Array<String>() // yukarıdakiyle aynı
var bosDegistirilebilirDizi = [String]() // var == değişebilir
// Dictionary
var meslekler = [
"Kamil": "Kaptan",
"Ayse": "Analist"
]
meslekler["Cansu"] = "Halkla İlişkiler"
let bosDictionary = [String: Float]() // let == değiştirilemez
let bosDictionary2 = Dictionary<String, Float>() // yukarıdakiyle aynı
var bosDegistirilebirDictionary = [String: Float]() // var == değiştirilebilir
//
// MARK: Kontroller
//
// for döngüsü (dizi)
let dizi = [1, 1, 2, 3, 5]
for deger in dizi {
if deger == 1 {
print("Bir!")
} else {
print("Bir degil!")
}
}
// for döngüsü (dictionary)
var dict = ["one": 1, "two": 2]
for (key, value) in dict {
print("\(key): \(value)")
}
// for döngüsü (aralık)
for i in -1...liste.count {
print(i)
}
liste[1...2] = ["et", "yogurt"]
// ..< kullanarak son elemanı çıkartabilirsiniz
// while döngüsü
var i = 1
while i < 1000 {
i *= 2
}
// do-while döngüsü
do {
print("merhaba")
} while 1 == 2
// Switch
// Çok güçlü, `if` ifadesenin daha kolay okunabilir hali olarak düşünün
// String, object örnekleri, ve primitif tipleri (Int, Double, vs) destekler.
let sebze = "kırmızı biber"
switch sebze {
case "sogan":
let sebzeYorumu = "Biraz da domates ekle"
case "domates", "salata":
let sebzeYorumu = "İyi bir sandviç olur"
case let lokalScopeDegeri where lokalScopeDegeri.hasSuffix("biber"):
let sebzeYorumu = "Acı bir \(lokalScopeDegeri)?"
default: // zorunludur (tüm olasılıkları yakalamak icin)
let sebzeYorumu = "Corbadaki herseyin tadı güzel"
}
//
// MARK: Fonksiyonlar
//
// Fonksiyonlar first-class tiplerdir, yani başka fonksiyon içine konabilir
// ve parametre olarak geçirilebilirler.
// Swift dökümanlarıylaa birlikte Fonksiyonlar (format as reStructedText)
/**
selamlama işlemi
:param: isim e isim
:param: gun e A gun
:returns: isim ve gunu iceren bir String
*/
func selam(isim: String, gun: String) -> String {
return "Merhaba \(isim), bugün \(gun)."
}
selam("Can", "Salı")
// fonksiyon parametre davranışı hariç yukarıdakine benzer
func selam2(#gerekliIsim: String, disParametreIsmi lokalParamtreIsmi: String) -> String {
return "Merhaba \(gerekliIsim), bugün \(lokalParamtreIsmi)"
}
selam2(gerekliIsim:"Can", disParametreIsmi: "Salı")
// Bir tuple ile birden fazla deger dönen fonksiyon
func fiyatlariGetir() -> (Double, Double, Double) {
return (3.59, 3.69, 3.79)
}
let fiyatTuple = fiyatlariGetir()
let fiyat = fiyatTuple.2 // 3.79
// _ (alt çizgi) kullanımı Tuple degerlerini veya diğer değerleri görmezden
//gelir
let (_, fiyat1, _) = fiyatTuple // fiyat1 == 3.69
print(fiyat1 == fiyatTuple.1) // true
print("Benzin fiyatı: \(fiyat)")
// Çeşitli Argümanlar
func ayarla(sayilar: Int...) {
// bu bir dizidir
let sayi = sayilar[0]
let argumanSAyisi = sayilar.count
}
// fonksiyonu parametre olarak geçirme veya döndürme
func arttirmaIslemi() -> (Int -> Int) {
func birEkle(sayi: Int) -> Int {
return 1 + sayi
}
return birEkle
}
var arttir = arttirmaIslemi()
arttir(7)
// referans geçirme
func yerDegistir(inout a: Int, inout b: Int) {
let tempA = a
a = b
b = tempA
}
var someIntA = 7
var someIntB = 3
yerDegistir(&someIntA, &someIntB)
print(someIntB) // 7
//
// MARK: Closurelar
//
var sayilar = [1, 2, 6]
// Fonksiyonlar özelleştirilmiş closurelardır. ({})
// Closure örneği.
// `->` parametrelerle dönüş tipini birbirinden ayırır
// `in` closure başlığını closure bodysinden ayırır.
sayilar.map({
(sayi: Int) -> Int in
let sonuc = 3 * sayi
return sonuc
})
// eger tip biliniyorsa, yukarıdaki gibi, şöyle yapabiliriz
sayilar = sayilar.map({ sayi in 3 * sayi })
// Hatta bunu
//sayilar = sayilar.map({ $0 * 3 })
print(sayilar) // [3, 6, 18]
// Trailing closure
sayilar = sorted(sayilar) { $0 > $1 }
print(sayilar) // [18, 6, 3]
// Super kısa hali ise, < operatörü tipleri çıkartabildiği için
sayilar = sorted(sayilar, < )
print(sayilar) // [3, 6, 18]
//
// MARK: Yapılar
//
// Structurelar ve sınıflar birçok aynı özelliğe sahiptir.
struct IsimTablosu {
let isimler = [String]()
// Özelleştirilmiş dizi erişimi
subscript(index: Int) -> String {
return isimler[index]
}
}
// Structurelar otomatik oluşturulmuş kurucu metoda sahiptir.
let isimTablosu = IsimTablosu(isimler: ["Ben", "Onlar"])
let isim = isimTablosu[1]
print("İsim \(name)") // İsim Onlar
//
// MARK: Sınıflar
//
// Sınıflar, structurelar ve üyeleri 3 seviye erişime sahiptir.
// Bunlar: internal (default), public, private
public class Sekil {
public func alaniGetir() -> Int {
return 0;
}
}
// Sınıfın tüm değişkenleri ve metotları publictir.
// Eğer sadece veriyi yapılandırılmış bir objede
// saklamak istiyorsanız, `struct` kullanmalısınız.
internal class Rect: Sekil {
var yanUzunluk: Int = 1
// Özelleştirilmiş getter ve setter propertyleri
private var cevre: Int {
get {
return 4 * yanUzunluk
}
set {
// `newValue ` setterlarda yeni değere erişimi sağlar
yanUzunluk = newValue / 4
}
}
// Bir değişkene geç atama(lazy load) yapmak
// altSekil getter cağrılana dek nil (oluşturulmamış) olarak kalır
lazy var altSekil = Rect(yanUzunluk: 4)
// Eğer özelleştirilmiş getter ve setter a ihtiyacınız yoksa,
// ama bir değişkene get veya set yapıldıktan sonra bir işlem yapmak
// istiyorsanız, `willSet` ve `didSet` metotlarını kullanabilirsiniz
var identifier: String = "defaultID" {
// `willSet` argümanı yeni değer için değişkenin adı olacaktır.
willSet(someIdentifier) {
print(someIdentifier)
}
}
init(yanUzunluk: Int) {
self. yanUzunluk = yanUzunluk
// super.init i her zaman özelleştirilmiş değerleri oluşturduktan sonra
çağırın
super.init()
}
func kisalt() {
if yanUzunluk > 0 {
--yanUzunluk
}
}
override func alaniGetir() -> Int {
return yanUzunluk * yanUzunluk
}
}
// Basit `Kare` sınıfI `Rect` sınıfını extend ediyor.
class Kare: Rect {
convenience init() {
self.init(yanUzunluk: 5)
}
}
var benimKarem = Kare()
print(m benimKarem.alaniGetir()) // 25
benimKarem.kisalt()
print(benimKarem.yanUzunluk) // 4
// sınıf örneğini cast etme
let birSekil = benimKarem as Sekil
// örnekleri karşılaştır, objeleri karşılaştıran == (equal to) ile aynı değil
if benimKarem === benimKarem {
print("Evet, bu benimKarem")
}
// Opsiyonel init
class Daire: Sekil {
var yaricap: Int
override func alaniGetir() -> Int {
return 3 * yaricap * yaricap
}
// Eğer init opsiyonelse (nil dönebilir) `init` den sonra soru işareti
// son eki ekle.
init?(yaricap: Int) {
self.yaricap = yaricap
super.init()
if yaricap <= 0 {
return nil
}
}
}
var benimDairem = Daire(radius: 1)
print(benimDairem?.alaniGetir()) // Optional(3)
print(benimDairem!. alaniGetir()) // 3
var benimBosDairem = Daire(yaricap: -1)
print(benimBosDairem?. alaniGetir()) // "nil"
if let daire = benimBosDairem {
// benimBosDairem nil olduğu için çalışmayacak
print("circle is not nil")
}
//
// MARK: Enumlar
//
// Enumlar opsiyonel olarak özel bir tip veya kendi tiplerinde olabilirler.
// Sınıflar gibi metotlar içerebilirler.
enum Kart {
case kupa, maca, sinek, karo
func getIcon() -> String {
switch self {
case .maca: return "♤"
case .kupa: return "♡"
case .karo: return "♢"
case .sinek: return "♧"
}
}
}
// Enum değerleri kısayol syntaxa izin verir. Eğer değişken tipi açık olarak belirtildiyse enum tipini yazmaya gerek kalmaz.
var kartTipi: Kart = .kupa
// Integer olmayan enumlar direk değer (rawValue) atama gerektirir.
enum KitapAdi: String {
case john = "John"
case luke = "Luke"
}
print("Name: \(KitapAdi.john.rawValue)")
// Değerlerle ilişkilendirilmiş Enum
enum Mobilya {
// Int ile ilişkilendirilmiş
case masa(yukseklik: Int)
// String ve Int ile ilişkilendirilmiş
case sandalye(String, Int)
func aciklama() -> String {
switch self {
case .masa(let yukseklik):
return "Masa boyu \(yukseklik) cm"
case .sandalye(let marka, let yukseklik):
return "\(brand) marka sandalyenin boyu \(yukseklik) cm"
}
}
}
var masa: Mobilya = .masa(yukseklik: 80)
print(masa.aciklama()) // "Masa boyu 80 cm"
var sandalye = Mobilya.sandalye("Foo", 40)
print(sandalye.aciklama()) // "Foo marka sandalyenin boyu 40 cm"
//
// MARK: Protokoller
//
// `protocol` onu kullanan tiplerin bazı özel değişkenleri, metotları,
// tip metotlarını,opertörleri ve alt indisleri (subscripts) içermesini
// zorunlu hale getirebilir.
protocol SekilUretici {
var aktif: Bool { get set }
func sekilOlustur() -> Sekil
}
// @objc ile tanımlanan protokoller, uygunluğu kontrol edebilmenizi sağlayacak
// şekilde opsiyonel fonksiyonlara izin verir
@objc protocol SekliDondur {
optional func sekillendirilmis()
optional func sekillendirilebilir() -> Bool
}
class BenimSeklim: Rect {
var delegate: SekliDondur?
func buyut() {
yanUzlunluk += 2
// Bir çalışma zamanı hatası("optional chaining") fırlatmak yerine nil
//değeri görmezden gelerek nil dönmek için opsiyonel değişken, metot veya
// altindisten sonra soru işareti koyabilirsiniz.
if let izinVeriyormu = self.delegate?.sekillendirilebilir?() {
// önce delegate i sonra metodu test edin
self.delegate?.sekillendirilmis?()
}
}
}
//
// MARK: Diğerleri
//
// `extension`lar: Var olan tiplere ekstra özellikler ekleyin
// Kare artık `Printable` protokolüne uyuyor.
extension Kare: Printable {
var description: String {
return "Alan: \(alaniGetir()) - ID: \(self.identifier)"
}
}
print("Kare: \(benimKarem)")
// Dahili tipleri de yeni özellikler ekleyebilirsiniz
extension Int {
var customProperty: String {
return "Bu sayı \(self)"
}
func carp(num: Int) -> Int {
return num * self
}
}
print(7.customProperty) // "Bu sayı 7"
print(14.carp(3)) // 42
// Genericler: Java ve C#'a benzer şekilde. `where` anahtar kelimesini
// kullanarak genericlerin özelliklerini belirleyin
func indexiBul<T: Equatable>(dizi: [T], bulunacakDeger: T) -> Int? {
for (index, deger) in enumerate(dizi) {
if deger == bulunacakDeger {
return index
}
}
return nil
}
let bulunanIndex = indexiBul([1, 2, 3, 4], 3)
print(bulunanIndex == 2) // true
// Operatorler:
// Özel operatorler şu karakterlerle başlayabilir:
// / = - + * % < > ! & | ^ . ~
// veya
// Unicode math, symbol, arrow, dingbat, ve line/box karakterleri.
prefix operator !!! {}
// Yan uzunluğu 3 katına çıkartan prefix operatörü
prefix func !!! (inout sekil: Kare) -> Kare {
sekil.YanUzunluk *= 3
return sekil
}
// güncel deger
print(benimKarem.YanUzunluk) // 4
// yan uzunluğu !!! operatorü kullanarak 3 katına çıkar
!!!benimKarem
print(benimKarem.YanUzunluk) // 12
```
|