В начале мая на просторах интернета разработчики языка объявили, что начинают подготовку к релизу 3.0 версию языка. Разработка 3.0 идет в мастер ветке, по релизам, можно понять, что 3-го мая был релиз Swift 2.2.1. Затем туда же начали вливать изменения касательно 3-ей версии языка. 9-го мая уже появился первый developer релиз из того же мастера, который можно накатить на последний xcode через установщик из swift.org/download/#snapshots, который включается через Preferences -> Components -> Toolchains.

Немного общей информации о будущем релизе


Примерно во время первого dev релиза Swift 3.0, разработчики заявили, что, к сожалению, не успевают реализовать ABI совместимость в 3.0 версии. Давайте разбираться, что это вообще значит, ибо я сам первый раз эти три буквы увидел вместе.

ABI это application binary interface, грубо говоря это совместимость бинарников разных версий между собой, можно привести аналогию с привычным нам API совместимостью, когда API 1.0 совместим с 2.0, но изменения, сделанные в 3.0, уже будут несовместимы с первой версией, поэтому при использовани API 3.0 нужно будет править код (в случае с ABI не править код, а пересобирать бинарник).

На самом деле, как оказалось для меня открытием, Swift еще никогда не имел ABI компатибили. Это говорит о том, что либа, собранная на Swift 2.0 уже не будет резолвиться с 2.2 версией языка. Коллеги из стабильных языков:



Вот так оказывается и живем. Но свитерам сфивтерам в этом плане повезло, потому что депенденси менеджеры (cocoapods, carthage) всегда подтягивают исходники проектов, а не бинарники, поэтому проблем с ABI совместимостью как таковых нет. Но, видимо, пока стоит воздержаться от написания проприетарных либ на сфивте и выкладывать их в паблик в виде бинарников. Да, ABI обещают добавить только к Swift 4.0.

Посмотрим на изменения в API




Даже метод didFinishLaunching подсвечивается варнингом, так как у него поменялась сигнатура, сейчас он стал

/// swift 3
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]? = [:]) -> Bool {}

/// swift 2
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {}

Варнинги должны быть легко пофикшены тулзой для миграции на Swift 3.0 в Xcode в будущем.

Посмотрим на изменения в стандартной библиотеке Swift и в Foundation


ErrorType поменяли на ErrorProtocol

/// swift 3
enum MyError: ErrorProtocol {
    case Success
    case Fail(ErrorProtocol)
}

/// swift 2
enum MyError: ErrorType {
    case Success
    case Fail(ErrorType)
}


Изменения для Array

/// swift 3
sort() // сортирует сам себя
sorted() // сортирует и возвращает новый отсортированный массив не изменяя порядок в старом

/// swift 2
sortInPlace() // сортирует сам себя
sort() // сортирует и возвращает новый отсортированный массив не изменяя порядок в старом


то есть метод sort стал мутабельным, убрали sortInPlace и добавили sorted.

/// swift 3
reversed()
append(contentsOf: [T])
insert(T, at: Int)
joined(separator: String)

/// swift 2
reverse()
appendContentsOf([T])
insert(T, atIndex: Int)
joinWithSeparator(String)

Также убрали многие конструкторы и переименовали другие методы.

Изменения для String

/// swift 3
"3.0".components(separatedBy: ".")
"3.0".substring(to: 1)
"3.0".substring(from: 1)
"".data(using: NSUTF8StringEncoding)
"2.0".replacingOccurrences(of: "2", with: "3")
"".uppercased()
"".lowercased()
"3.0".contains(".")
"3.".appending("0")
("dir1" as NSString).appendingPathComponent("dir2")
" 3.0 ".trimmingCharacters(in: .whitespaces())
"".write(toFile: "/..", atomically: true, encoding: NSUTF8StringEncoding)

/// swift 2
"3.0".componentsSeparatedByString(".")
"3.0".substringToIndex(1)
"3.0".substringFromIndex(1)
"3.0".dataUsingEncoding(NSUTF8StringEncoding)
"2.0".stringByReplacingOccurrencesOfString("2", withString: "3")
"".uppercaseString
"".lowercaseString
"3.0".containsString(".")
"3.0".appendContentsOf(".release")
("dir1" as NSString).stringByAppendingPathComponent("dir2")
"3.0".stringByTrimmingCharactersInSet(.whitespaceCharacterSet())
"3.0".writeToFile("/..", atomically: true, encoding: NSUTF8StringEncoding)


Кейсы для enum сейчас в ловер кейсе

/// swift 3
UIInterfaceOrientation.portrait
Optional.some("")
Optional.none

/// swift 2
UIInterfaceOrientation.Portrait
Optional.Some("")
Optional.None


Изменения в UIKit


/// swift 3
let vc = UIViewController()
vc.present(some, animated: true, completion: nil)
vc.dismiss(animated: true, completion: nil)
vc.prepare(for: segue sender: button)

UIColor.white()
UIColor.blue()

let path = UIBezierPath()
path.move(to: CGPoint(x: 0, y: 0))
path.addLine(to: CGPoint(x: 100, y: 100))

// добавился знак _ в начале первого параметра + сократили имя аргумента функции, из-за чего будут варниги в проекте
func tableView(_ tableView: UITableView, numberOfSections section: Int) -> Int { return 0 }
func tableView(_ tableView: UITableView, cellForRowAt indexPath: NSIndexPath) -> UITableViewCell { return UITableViewCell() }
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: NSIndexPath) { }

/// swift 2
let vc = UIViewController()
vc.presentViewController(some, animated: true, completion: nil)
vc.dismissViewControllerAnimated(true, completion: nil)
vc.prepareForSegue(segue, sender: button)

UIColor.whiteColor()
UIColor.blueColor()

let path = UIBezierPath()
path.moveToPoint(CGPoint(x: 0, y: 0))
path.addLineToPoint(CGPoint(x: 100, y: 100))

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 0 }
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { return UITableViewCell() }
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { }


Еще изменения


/// swift 3
NSData(contentsOf: "")
UIApplication.shared()
NSUserDefaults.standard().set("value", forKey: "key")
NSFileManager.default().fileExists(atPath: "/...")
NSBundle.main()

/// swift 2
NSData(contentsOfURL: "/")
UIApplication.sharedApplication()
NSUserDefaults.standardUserDefaults().setObject("value", forKey: "key")
NSFileManager.defaultManager().fileExistsAtPath("/")
NSBundle.mainBundle()


Вот так провели swiftification, в общем пострадал весь апи, а не только стандартная библиотека. Но стоит признаться, читабельность действительно стала лучше. Релиз Swift 3.0 намечен на осень. ABI compatibility запланирована в 4.0. Чего-то нового в Swift не стоит ожидать на WWDC 2016.

Встает вопрос, так что же всё таки выбрать на новый проект? Я голосую за Swift, с ним разработка идет намного быстрее и безопаснее ввиду очень строгой типизации и рюшечек ввиде Optional и синтаксиса замыканий/лямбд. В общем:



Полезные ссылки:

https://swift.org/blog/
https://www.hackingwithswift.com/swift3
https://github.com/apple/swift-evolution
http://www.bensnider.com/abi-compatibility-whoopdty-do-what-does-it-all-mean.html

update

Стоит добавить, что разработчики Swift перелопатили весь API, чтобы сделать его как и задумывалось с первых дней языка, просто поддержка совместимости с Objective-C сделала своё дело и поломала первоначальный API дизайн. Планируется, что Swift будет работать на многих платформах, включая FreeBSD, Raspberry Pi, Android, Windows. Видимо, именно в версии 3.0 решили сделать полную переработку API, придать ему более свифтовый стиль.
try?

Проголосовало 457 человек. Воздержалось 206 человек.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Поделиться с друзьями
-->

Комментарии (40)


  1. MeGaPk
    22.05.2016 21:12
    +2

    Пожалуй останусь на OBJ-C. Хоть и синтаксис упорот. Но по крайней мере:
    — Стабильно
    — Без «плюшек» ввиде багов с ооочень долгим компиляцией массива, в котором ты запилил еще OPTIONAL переменную…
    Ну и разумеется AppCode отвратительно работает, что очень удурчяет.

    Вообщем поживём, увидим :).


    1. i_user
      22.05.2016 22:27
      +5

      ввиде багов с ооочень долгим компиляцией массива

      Это далеко не самый страшный баг свифта) но вернуться на обж-си я уже не могу, глаза вытекают…


      1. Speakus
        23.05.2016 04:30
        +2

        Расскажите плиз про страшные баги свифта.


        1. i_user
          23.05.2016 08:45
          +2

          https://bugs.swift.org/browse/SR-1502 вот, например. Страшный.


        1. i_user
          23.05.2016 10:31
          +1

          О, вот прям с утра от знакомых еще один прилетел:

          http://openradar.appspot.com/radar?id=4971716266688512


    1. creker
      23.05.2016 14:45
      -1

      Я бы сказал, что у свифта синтаксис не менее упорот


  1. iroln
    23.05.2016 00:22
    +4

    По моему это хорошо, что они так легко рефакторят API стандартной библиотеки без оглядки на обратную совместимость. Пока язык молодой, они могут себе это позволить без особой боли. Потом будет сложнее.


    1. hell0w0rd
      23.05.2016 01:52
      +2

      Не факт, что будет сложнее. Я так понимаю к каждой версии выходит codemode-tool, который приводит весь старый код к новому виду. Если такое делать постоянно, но обратная совместимость имхо не так важна. Подобного не хватает в других технологиях.


      1. Krypt
        23.05.2016 20:44

        Это плохо для понимания кода программистами. После такой тулзы наверняка будут проблемы с «узнаванием» своего собственного кода, особенно в старых модулях.


        1. Makaveli
          24.05.2016 11:57
          +1

          Но тут должно приходить на помощь умение разбираться в чужом коде, который на самом деле изменённый ваш. Всё равно, если синтаксис языка меняется, а вы на нём постоянно пишете, так или иначе надо будет разбираться и привыкать к новому синтаксису.


    1. KindDragon
      23.05.2016 12:39
      +10

      Не понятно зачем они это называют 3.0, а не 0.3.


      1. iroln
        23.05.2016 12:48

        В последнее время вообще наблюдается тенденция использовать мажорные номера версий. Возможно, какой-то психологический трюк. Наверное, людям приятнее смотреть на версию 3.0 или 3.1, чем на 0.3.11 или что-нибудь в таком роде. С быстрым ростом версии кажется, что проект быстрее развивается, а его вес в глазах сообщества растёт. :)
        При этом правило «стабилизируем API на версии 1.0» в этом случае уже не работает.


        1. grossws
          23.05.2016 12:58
          +6

          Мне более импонирует использование semver + плюс оговорки для major == 0, чем такой популизм.


          Тот же rust пошёл по пути постепенного развития, но базовые вещи зафиксированы с версии 1.0.0. А то, что ещё не зафиксировано и развивается — недоступно в stable. Т. е. новые api в libstd и libcore появляются только после их обкатки и в финальном виде. Что, несмотря на довольно высокий темп релизов (раз в 6 недель) позволяет выдавать продуманное стабильное API


      1. sulnedinfind
        23.05.2016 13:03

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

        Но разделяю вашу фрустрацию.


      1. okla
        23.05.2016 13:21
        +1

        Видимо, потому что ломается обратная совместимость с 2.0. semver.org


        1. defuz
          23.05.2016 14:12
          +1

          Собственно, если перейти по вашей ссылке, то там написано следующее:

          Major version zero (0.y.z) is for initial development. Anything may change at any time. The public API should not be considered stable.

          Это примерно соответствует тому, на какой стадии сейчас находиться разработка Swift, учитывая то, с какой легкостью они позволяют себе переименовывать базовые методы в стандартной библиотеке языка. Я не хочу сказать что это само по себе плохо, просто в таком случае было бы честно говорить, что текущая версия языка – 0.3.


          1. okla
            23.05.2016 18:11

            Не сказал бы, что язык всё ещё в initial стадии, уже очень многие используют его в продакшене. Изменения довольно косметические, бoльшая их часть скорее всего будет внесена в проекты автоматически с помощью swift migration tool. Кстати, эти изменения были предложены сообществом и прошли через обсуждения и, затем, ревью разработчиками языка. Очень грамотный, на мой взгляд, подход (https://github.com/apple/swift-evolution)


  1. entze
    23.05.2016 09:08
    +1

    Изменения пролоббированы авторами учебников начального уровня: Lynda, Udemy и т.д.?


  1. monah_tuk
    23.05.2016 09:30

    Это говорит о том, что либа, собраная на Swift 2.0 уже не будет резолвиться с 2.2 версией языка. Коллеги из стабильных языков:

    В C++, насколько я знаю, стандартизации ABI нет до сих пор (я знаю только про пропозал Саттера: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4028.pdf, но за его судьбой не следил). Ну и интересно узнать про языки вне платформ JVM и .NET, у которых есть стандартизованные ABI интерфейсы.


    1. andy128k
      23.05.2016 12:17
      +1

      В C++ общего стандарта на ABI нет, но у каждого производителя есть свой. Можно не менять поставщика компилятора и стабилизировать ABI.
      В Swift-е же поставщик один, а стабильности всё нет :) Молодой ещё.


  1. Barafu
    23.05.2016 11:16

    Разница серьёзнее, чем между Python2 и Python3. При этом на Python3 народ уже много лет переходить из-за этого не хочет. В основном, программы не переходят потому, что библиотеки остались на втором, а библиотеки не переходят потому, что использующие их программы остались на втором.
    Посмотрим что тут получится. Так сказать, сравнение развития ситуации при инъекции бабла.


    1. Googolplex
      23.05.2016 12:01
      +1

      Мне кажется, что на Swift сейчас написано гораздо меньше кода, чем на Python 2 в то время, когда появился Python 3. Скорее всего, переход на новую версию Swift будет гораздо менее болезненным, даже без "инъекции бабла".


  1. fiveze
    23.05.2016 12:43
    +1

    С кейсами для enum как-то неоднозначно.


  1. alexbers
    23.05.2016 12:45
    +1

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

    Swift 2:
    func square(a:Int) -> Int { return a * a }
    print(square(10))


    Swift 3:
    func square(a:Int) -> Int { return a * a }
    print(square(a:10))

    или
    func square(_ a:Int) -> Int { return a * a }
    print(square(10))


    Переименование функций, например, из «3.0».componentsSeparatedByString(".") в «3.0».components(separatedBy: ".") могли быть следствием этого.


    1. Viacheslav01
      23.05.2016 13:06
      +1

      Вот честно просто не могу себе представить, ЗАЧЕМ?


      1. Makaveli
        23.05.2016 13:19

        Видимо, для более явного именования аргументов функции, у которых есть внутреннее и внешнее имя. Единообразие, видимо, в объявлении аргументов. Если не хочешь извне указывать имя аргумента явно — в объявлении функции используешь _ и пишешь square(10)


        1. Viacheslav01
          23.05.2016 15:28

          Мы тут уже пообсуждали, видимо это попытка решения проблемы выбора перегруженой функции.


      1. sojik
        23.05.2016 17:14

        Благо, что думать в Swift не надо :) а по каждому решению есть точное описание. По этому изменению вот:
        https://github.com/apple/swift-evolution/blob/master/proposals/0046-first-label.md
        В данном случае речь идет о единообразии и чистоте языка. Теперь функции единообразны с инициализаторами, где требовалось указывать первый параметр обязательно, а если ты не хочешь, то надо было ставить "_". А в других функциях требовалось наоборот дважды указывать название первой переменной, чтобы мочь ее указывать в вызове. Это могло быть confusing для людей, изучающих язык. Теперь все сделано единообразно.

        ЗЫ как человек, который «волею судеб» год писал приложение в продакшене только на Swift каждый день, скажу, что язык мне нравится. Очень дисциплинирует. Иногда, когда возвращался на 5 минут в Obj-С, глаза действительно кровоточили от синтаксиса. Также, привыкнув к Optionals, порой было страшно в Obj-C, что передам nil в какой-то метод, которые его не принимает. Но на днях прям плотненько вернулся в старый проект на Obj-C и оказалось, что это как ездить на велосипеде, руки то помнят :))) и можно писать точно также хорошо.


        1. Krypt
          23.05.2016 21:08

          Точно не скажу с какой версии, но сейчас в языке есть дерективы nullable и nonnull для аргументов и возвращаемых значений функций. На Swift я ещё не писал, но по описанию — похоже.

          Вообще, сейчас в язык добавили много операторов-подсказок для компилятора, вроде NS_REQUIRES_NIL_TERMINATION.


          1. sojik
            24.05.2016 06:30

            ну, они nullable и nonnull сделали как раз по больше связи для взаимодействия со Swift. Поэтому, как только это появилось в API, то не прошло мимо меня ) спасибо!


  1. Makaveli
    23.05.2016 13:22
    +1

    Планируется, что Swift будет работать на многих платформах, включая FreeBSD, Raspberry Pi, Android, Windows.

    Захотел тут попробовать что-то для Linux сделать на Swift — упёрся в то, что ничего для работы с сетью пока не реализовано. Когда хотят реализовать — планов не нашёл, только «not implemented yet», то есть сделать на сервере какой-то запрос к какому-то другому REST API надо какими-нибудь обёртками на, например, сишным CURL (так делают IBM). Но хочется как-то из коробки


    1. alexbers
      23.05.2016 13:46

      Можно посмотреть на это с другой стороны. В Swift очень удобно подключаются библиотеки на C. Недавно безо всяких проблем удалось подключить OpenGL.

      Ещё потихоньку портируют Foundation Framework из Obj C. Здесь сказано, что NSURLRequest доступен и для Swift тоже.

      В кроссплатформенный Swift ещё перенесли не все возможности Foundation Framework, но это одна из главных целей, поставленная для Swift 3.0:
      Our primary goal is to achieve implementation parity with Foundation on Apple platforms. This will help to enable the overall Swift 3 goal of portability.

      Источник

      Сейчас Foundation собирается довольно сложно, но к релизу должны поправить.


      1. Makaveli
        23.05.2016 15:03

        Здесь сказано, что NSURLRequest доступен и для Swift тоже

        Так это документация для макоси, никаких проблем для iOS / tvOS / OX X нет, там бриджинг на все фреймворки из Objective-C из коробки.

        В Linux то нужно опенсорсный Swift тащить и опенсорсный Foundation (тот что swift-corelibs-foundation), а там, к сожалению, написано:
        NSURLSession and related classes are not yet implemented.


        1. alexbers
          23.05.2016 15:22

          В любом случае, к выходу Swift 3, обещают реализовать всё.

          Возможно какая-то часть уже сделана. Файл по ссылке не обновлялся уже пять месяцев, что для проекта у которого первый коммит сделан шесть месяцев назад — значительный срок.


          1. Makaveli
            23.05.2016 15:22

            Будем надеяться и ждать :)


  1. i-mist
    23.05.2016 15:24

    А если сравнивать Swift с C#, что выглядит перспективней для мобильной разработки?

    Насколько я понимаю, по уровню и наличию синтаксических плюшек вроде лямбда-выражений/nullable-переменных языки сопоставимы. Об IDE судить не берусь. Но на C# уже можно писать и для Android, и для iOS, а Swift только на пути к этому (да и с этой самой ABI-совместимостью у .NET получше)?..


    1. Zanael
      23.05.2016 16:31
      +5

      Ну окей, постараемся отбросить все предрассудки и посмотрим на вещи как они есть на самом деле.
      Если есть желание писать под все мобильные платформы (iOS, Android, и, возможно, Windows Phone) на C#, то вероятно речь идет о silver bullet в лице Xamarin. Говорить о нем можно бесконечно, при этом как хваля его, так и презирая. Объективно, чтобы создать приложение, нужно:

      1. Какая-то IDE для проектирования интерфейса;
      2. Знание жизненного цикла приложения на мобильной ос;
      3. Знание нативных библиотек;

      «Мираж» Xamarin в том, что для того чтобы написать что-то на C#, вам, хотите вы или нет, придется разобраться в пунктах 1, 2 и 3. При этом на май 2016 года ни Xamarin Studio, ни Visual Studio нет нормального дизайнера.
      — Для iOS вам придется использовать XCode Interface Builder, так как Storyboard формируются криво, а работа с Constraints начинает утомлять неточностью;
      — Для Android вам придется использовать Android Studio и линковать xml-файлы обратно в Xamarin Studio, так как «IntelliSense» работает не очень хорошо, а для ресурсных xml не работает вовсе. Если конечно вы не ниндзя и пишете без подсказок в коде.

      Далее вам будет необходимо использовать стандартные функции фреймворка или даже наследоваться:
      — Из мира iOS вас теплыми объятиями встретит именование Objective-C функций, binding'а, интересные конструкторы с указателями;
      — Из мира Android вас повстречает обязательное наследование от Java.Lang.Object и увлекательное жонглирование интерфейсами;

      Ну и вишенка конечно — вопросы многопоточности, работы с сетью и хранения данных. Тут вы быстро попытаетесь спрятаться в уютном .NET домике. Он будет настолько теплым, что вы начнете выстраивать в нем свою параллельную вселенную, которая действительно будет работать.

      Потратив значительное время на изучение нативных инструментов разработки, зазубривание нативного API и библиотек, а также переиначивая их на C#-лад, вы сделаете свое первое мобильное приложение, которое будет работать как надо. И будет выглядеть как нативное.
      Но в этот момент *гифка где Гендальф-Белый плачет на фоне Хельмовой Пади, дождавшись помощи Эомера с войском рохирримов* — вы оглянетесь и скажете «я сделал это!», но встретившись глазами со своим боевым конем Xamarin'ом проскользнет секундная неловкость, и вы скажете: «Спасибо друг, дальше я сам», и нативная разработка станет для вас не такой страшной и более привлекательной.

      Вытерев скупую мужскую слезу с мужественной щеки и, оценив перспективы C#, понимаешь, что он имеет крайне нишевое применение в мобильной разработке. Учитывая планы Google по использованию Swift в качестве ключевого языка для Android вывод становится очевидным — доминирование Swift в мобильной разработке лишь вопрос времени. Вероятно это случится к 5 или 6 версии Swift года через два-три. И новые программисты вряд ли будут выбирать C# для этой связки.

      Мое субъективное мнение — Swift на текущий момент слишком дорого обходится в промышленном использовании. Перепиливание проекта после каждой новой версии требует вливание человека-часов, конвертируемых в $. Тот же Xamarin стабильнее.

      Objective-C не такой страшный как кажется на первый взгляд, и не такой «динозавр» как можно подумать. Если понимать как он работает внутри, то у него много общего с тем же C#.

      C# отличный язык, мой любимый. И я фанат Miguel de Icaza. Но я понимаю, что доля C# в мобильной разработке даже в среднесрочной перспективе имеет форму дули. Но, тем не менее, Xamarin — это фантастическая штука, через которую я бы советовал пройти каждому C#/.NET программисту, который хочет приоткрыть для себя дивный мир мобильной разработки.


      1. i-mist
        23.05.2016 17:02

        Спасибо за содержательный ответ. Давно хотел понять, в чём подводные камни сочетания C# + Xamarin. Которое, вроде бы, призвано стать панацеей для мобильной разработки, но пока явно не становится. )

        А насчёт
        «Учитывая планы Google по использованию Swift в качестве ключевого языка для Android вывод становится очевидным — доминирование Swift в мобильной разработке лишь вопрос времени. » Вероятно это случится к 5 или 6 версии Swift года через два-три."

        мне кажется, за 2 — 3 года и Xamarin может обзавестись стоящей обёрткой для нативных библиотек + инструментами разработки интерфейса. Впрочем, не знаю, насколько это вероятно — просто тоже нравится C#. )


        1. Zanael
          23.05.2016 17:21

          за 2 — 3 года и Xamarin может обзавестись стоящей обёрткой для нативных библиотек + инструментами разработки интерфейса.

          К тому моменту для большинства может встать один единственный, и страшный вопрос: «а зачем, если есть Swift?»
          C# никуда не денется, как и Xamarin, но может стать своеобразным «шахматным клубом».

          А на данный момент можно расслабиться, Google от слов к делу пока не перешел. Так что сейчас Xamarin, это «Уникальное предложение… Только сейчас… Вы сможете без труда… и т.д.» :-)


  1. mezastel
    23.05.2016 19:20

    Оставлю этот комментарий про поддержку Windows.