habrahabr

Знакомьтесь, Swift!

  • пятница, 6 июня 2014 г. в 03:11:05
http://habrahabr.ru/post/225297/

2 июня на конференции WWDC 2014 Apple представила новый объектно-ориентированный язык программирования — Swift. Я думаю, многие уже успели посмотреть, что из себя представляет этот язык (Swift — нововведения), поэтому я не буду останавливаться на нововведениях. Я предлагаю создать простенький проект на языке Swift, чтобы понять на деле основные отличия от привычного Obj-C.



Подготовка


Для начала необходимо установить Xcode 6 Beta. Скачать его можно отсюда:
https://developer.apple.com/devcenter/ios/index.action
Скачиваем, устанавливаем и открываем (проблем с установкой не должно возникнуть, beta версия ставится как отдельное приложение и на основной Xcode никак не влияет).
Создаем новый проект (Single View Application) -> вводим название проекта и не забываем выбрать язык Swift!



Структура


Обратите внимание на структуру, количество файлов теперь в 2 раза меньше, теперь нет необходимости в заголовочных файлах. Код, написанный в глобальной области используется в качестве точки входа для программы, так что больше не нужна функция main.


Вот как выглядит теперь AppDelegate:

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
                            
    var window: UIWindow?

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
        // Override point for customization after application launch.
        return true
    }

    func applicationWillResignActive(application: UIApplication) {
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
    }

    func applicationDidEnterBackground(application: UIApplication) {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    }

    func applicationWillEnterForeground(application: UIApplication) {
        // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
    }

    func applicationDidBecomeActive(application: UIApplication) {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    }

    func applicationWillTerminate(application: UIApplication) {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    }
}


Hello World


Изучение любого языка начинается с Hello World. Не станем нарушать традицию. Откройте AppDelegate.swift и добавьте в func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool строку:

println("Hello World") //Выводит в консоль

Запустите программу и вы увидите в консоли заветный Hello World. Вот так все просто.

Усложним


Немного усложним проект. Добавим любимый TableView.
Открываем Main.storyboard. Кстати, обратите внимание что для универсального приложения теперь по умолчанию создается не два storyboard, как было раньше, а всего лишь один. Количество симуляторов тоже увеличилось:


Находим в Object Library заветный Table View и переносим его на экран приложения. Растягиваем таблицу, чтобы она была на весь экран (необходимо, чтобы она совпадала с краями).


Дальше все делается как и раньше, нам нужно задать для таблицы dataSource и delegate. Для этого открываем Connection Inspector, от delegate тянем к объекту ViewController и аналогично для dataSource.



Во ViewController.swift нужно указать протоколы, которые нам понадобятся: UITableViewDataSource и UITableViewDelegate
Теперь это можно сделать так:

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate

Компилятор сразу ругнется:
Type 'ViewController' does not conform to protocol 'UITableViewDataSource'
Компилятор сообщает нам, что мы не определили функции протокола 'UITableViewDataSource'. Чтобы посмотреть какие функции нужно определить, зажмите command + кликните по протоколу.

protocol UITableViewDataSource : NSObjectProtocol {
    
    func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int
    func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!

Вот эти две функции и необходимо добавить в наш ViewController.swift
Первая функция должна возвращать количество строк в таблице (Int):

func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int
 {
        return 20
  }

А вторая функция возвращает ячейку таблицы:

func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!
    {
        let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "MyTestSwiftCell")
        
        cell.text = "Habrapost \(indexPath.row)"
        cell.detailTextLabel.text = "Hi, \(indexPath.row)"
        
        return cell
    }

В первой строчке создаем ячейку. Разберем запись подробней:
let означает, что мы создаем константу, а не переменную.
let cell: UITableViewCell сообщаем, что тип этой константы будет UITableViewCell. По идее, необязательно сообщать какой тип будет у константы или переменной. Программа будет прекрасно работать и так:

let cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "MyTestSwiftCell")

Но как мне кажется, лучше все-таки сообщать, Apple дает хороший пример почему:

let implicitInteger = 70
let implicitDouble = 70.0
let explicitDouble: Double = 70

Напомню, как мы создавали ячейку в Obj-C:

UITableCell *cell =[[UITableCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"MyTestSwiftCell"]

Не нужен больше alloc, Swift все делает самостоятельно. Все методы, которые начинались с init были убраны, и теперь инициализация происходит в стиле Swift (т.е MyClass()). Причем инициализаторы с with тоже были преобразованы, то что шло после with — стало первым аргументом в инициализаторе Swift.

Вот эта запись мне особенно сильно понравилась:

cell.text = "Habrapost \(indexPath.row)"

В Obj-C, чтобы сделать простую операцию конкатенацию строк, нужно было изгаляться следующим образом:

cell.text = [NSString stringWithFormat:@"Habrapost %@", indexPath.row];

По мне, так это приятное изменение.
Скажем теперь мы захотели изменить цвет текста на стандартный фиолетовый. Сделать это можно аналогично тому как было в Obj-C, обратимся к методу класса

cell.detailTextLabel.textColor = UIColor.purpleColor()

В итоге, получаем


Немного о playground


Playground — это площадка, где можно поэкспериментировать, и если понравиться перенести в основной проект.
Для того, чтобы создать playgroung выберете File->New->File:



Вот и все, можно экспериментировать. Например, я добавила ячейку таблицы, чтобы увидеть как она будет выглядеть.


Подробней почитать можно здесь https://developer.apple.com/...

Заключение


На первый взгляд, мне язык понравился. Довольно легко будет перейти от Obj-C на Swift, к тому же Swift прекрасно уживается с Obj-C. Количество кода уменьшилось в разы, читаемость при этом увеличилась. С памятью теперь вообще возиться не надо, все это делает Swift.

Подробнее про Swift: The Swift Programming Language