Разработка мобильных приложений для iOS и Android на C#

Содержание

Слайд 2

C#? Доклад проплачен?

Да! (на самом деле нет ☹)
Лямбда-выражения, делегаты, евенты
LINQ
Properties
Generics
Структуры
dynamic
В С# 5

C#? Доклад проплачен? Да! (на самом деле нет ☹) Лямбда-выражения, делегаты, евенты
async/await (ммм как сладко)

Слайд 3

Асинхронный код раньше

MyApi.OnSomeMethod += () => {
InvokeOnMainThread( (result) => {
textView.Text = result;

Асинхронный код раньше MyApi.OnSomeMethod += () => { InvokeOnMainThread( (result) => {
});
}
MyApi.SomeMethodAsync();

Слайд 4

async/await
textView.Text = await MyApi.GetUrlAsync(
“http://touchin.ru”);

async/await textView.Text = await MyApi.GetUrlAsync( “http://touchin.ru”);

Слайд 5

С# vs Objective-C

Objective-C:
// …
[button addTarget:self action:@selector(touchHandler:) forControlEvents:UIControlEventTouchUpInside];
// …
-(void) touchHandler:(id)sender {
textView.text = @"some

С# vs Objective-C Objective-C: // … [button addTarget:self action:@selector(touchHandler:) forControlEvents:UIControlEventTouchUpInside]; // …
text";
}

Слайд 6

С# vs Objective-C
C#:
btn.TouchUpInside += (sender, e) => {
textView.Text = "Clicked!";
} ;

С# vs Objective-C C#: btn.TouchUpInside += (sender, e) => { textView.Text = "Clicked!"; } ;

Слайд 7

C# vs Java

Java:
button.setOnClickListener(
new View.OnClickListener() {
public void onClick(View v) {
textView.setText(“Clicked”);
}
}
);

C# vs Java Java: button.setOnClickListener( new View.OnClickListener() { public void onClick(View v)

Слайд 8

C# vs Java
C#:
button.Click += (sender, e) {
textView.Text = “Clicked!”;
} ;

C# vs Java C#: button.Click += (sender, e) { textView.Text = “Clicked!”; } ;

Слайд 9

C# vs {0}

Проще
Чище
Развивается очень быстро
Меньше скобочек (но еще не Ruby/Python)
Из Java песок

C# vs {0} Проще Чище Развивается очень быстро Меньше скобочек (но еще
сыплется
[[[[После Objective-C] мир: квадратный] как:очень] ивесь: вдвоеточиях];

Слайд 10

Мир, дружба!

Мир, дружба!

Слайд 11

Mono

Свободная реализация стандарта ECMA-334 (C#) и ECMA-335 (CLI)
Развивается с 2004 года
Основатель –

Mono Свободная реализация стандарта ECMA-334 (C#) и ECMA-335 (CLI) Развивается с 2004
Miguel de Icaza (GNOME, Ximian, Midnight Commander, WINE)
Исходники, комьюнити, все как у людей
На данный момент поддерживается C# 4.0 и большая часть BCL

Слайд 12

Xamarin

Ximian -> Novell -> Attachmate -> Xamarin
Продает и саппортит Monotouch + Mono

Xamarin Ximian -> Novell -> Attachmate -> Xamarin Продает и саппортит Monotouch
for Android
Цены от 399$ за лицензию
На сайте отличные туториалы, документация, исходники типичных приложений
Выпущено 4 книги
https://github.com/xamarin/monotouch-samples

Слайд 13

Ах, да, представиться ☺

1.5 года опыта разработки с Monotouch
Своя компания разрабатывающая мобильные

Ах, да, представиться ☺ 1.5 года опыта разработки с Monotouch Своя компания
приложения для iOS, Android, WP7
Активно используем Monotouch, Mono for Android, Mono
Наши приложения попадают в топы AppStore и Google Play
Шарим код, пишем правильные архитектуры
Нам уже год, 17 человек, Kinect, бинбегги, массажистки, блекджек

Слайд 14

Что же такое Monotouch

Mono framework с AOT компиляцией для ARM процессоров и

Что же такое Monotouch Mono framework с AOT компиляцией для ARM процессоров
Bindings к родным API
Код пишется на C#
UI используется родной, через C# обертки
C#-зированный API (евенты, проперти, енумы)
Среда разработки Monodevelop + XCode

Слайд 15

Процесс компиляции

Компилируется ваш код, библиотеки, BCL, обертки над нативными методами в IL
Теоретически

Процесс компиляции Компилируется ваш код, библиотеки, BCL, обертки над нативными методами в
можно юзать любой язык (F#, IronPython, IronRuby, Nemerle, VB для особенных)
IL преобразуется в машинный код с использованием AOT компиляции
К коду приложения добавляется Mono Runtime с Garbage Collector’ом и всем остальным

Слайд 16

AOT vs JIT

Обычно в .Net и Mono машинный код генерируется в момент

AOT vs JIT Обычно в .Net и Mono машинный код генерируется в
запуска – Just In Time компиляция
В iOS нельзя компилировать код на лету, только статическая линковка
Но мы заранее знаем архитектуру (ARM) поэтому можно компилировать код заранее – Ahead Of Time компиляция

Слайд 17

Ограничения AOT

Нету Emit, но Reflection остается
Некоторые специфичные конструкции работать не будут, т.к.

Ограничения AOT Нету Emit, но Reflection остается Некоторые специфичные конструкции работать не
компилируются на лету
Generic Virtual Methods
P/Invokes in Generic Types
Некоторые LINQ expressions

Слайд 18

Linking

В момент компиляции в IL из BCL берется только тот код, который

Linking В момент компиляции в IL из BCL берется только тот код,
реально используется
Таким же образом можно вырезать неиспользуемый код в своих либах
Нужно для уменьшения размеров приложения

Слайд 19

C#-изация API

Подписка на евенты
Установка свойств
Привычные названия
var btn = new UIButton(new RectangleF(0, 0,

C#-изация API Подписка на евенты Установка свойств Привычные названия var btn =
200, 80));
btn.Enabled = true;
btn.SetTitleColor(UIColor.FromRGB(255, 255, 0), UIControlState.Selected);
btn.TouchUpInside += delegate {
// your code
} ;
window.Add(btn);

Слайд 20

Обертки над нативными методами

Monotouch:
Все сводится к P/Invoke метода objc_msgSend c нужными

Обертки над нативными методами Monotouch: Все сводится к P/Invoke метода objc_msgSend c
параметрами
См код Monotouch.ObjcRuntime.Messaging
Mono for Android:
Используется JNI (Java Native Interface)

Слайд 21

Обертки над нативными методами

public virtual bool Enabled
{
[Export("isEnabled")]
get
{
// …
return Messaging.bool_objc_msgSend(base.Handle, UIControl.selIsEnabled);
}
[Export("setEnabled:")]
set
{
// …
Messaging.void_objc_msgSend_bool(base.Handle, UIControl.selSetEnabled_,

Обертки над нативными методами public virtual bool Enabled { [Export("isEnabled")] get {
value);
}
}

Слайд 22

Структура приложения

Практически соответствует такой же у нативного приложения
AppDelegate, UIWindows, ViewControllers
Для описания UI

Структура приложения Практически соответствует такой же у нативного приложения AppDelegate, UIWindows, ViewControllers
также используются nib файлы

Слайд 23

Дебаг

Вместе с дебаг сборкой идет вся отладочная инфа + механизм удаленного дебага
Раньше

Дебаг Вместе с дебаг сборкой идет вся отладочная инфа + механизм удаленного
был по Wi-Fi сейчас по USB (быстрее)
Дебаг полноценный с breakpoint’ами watch’ами итд

Слайд 24

Garbage Collector

Работает ☺
Агрессивен – может часто вызываться
Не забывайте – локальная переменная, значит

Garbage Collector Работает ☺ Агрессивен – может часто вызываться Не забывайте –
обязательно соберется сборщиком
Говорят что в играх, если много объектов может подтормаживать (актуально для Unity скорее)

Слайд 25

Среда разработки - Monodevelop

Среда разработки - Monodevelop

Слайд 26

Для UI - XCode

Для UI - XCode

Слайд 27

Интеграция со сторонними либами

P/Invoke для С кода
btouch для Objective-C Bindings
В первый раз

Интеграция со сторонними либами P/Invoke для С кода btouch для Objective-C Bindings
сложно, а потом халява
Есть готовые обертки для популярных либ: Google Analytics, Flurry и др.

Слайд 28

Минусы

Размер (минимум 2-3Мб)
Рантайм идет с каждым приложением
Производительность (но не критично)
Все равно придется

Минусы Размер (минимум 2-3Мб) Рантайм идет с каждым приложением Производительность (но не
учить UIKit/Android UI

Слайд 29

Плюсики

Код шаринг (но не забываем про ограниченный WP7)
Не надо учить Objective-C (на

Плюсики Код шаринг (но не забываем про ограниченный WP7) Не надо учить
самом деле нет)
Проще разрабатывать (на самом деле быстрее)

Слайд 30

А что на практике

А на практике вполне себе хорошо
CoinKeeper (iOS + Android

А что на практике А на практике вполне себе хорошо CoinKeeper (iOS
+ сервер) - удобная архитектура, сокращение кода, багов, времени разработки
Наш супер [SecretProject] - тоже все пучком
Omlet.ru – 2 недели на аппы под iPad и Android, код шаринг на уровне АПИ, быстро реагировали на изменение АПИ

Слайд 31

Mono for Android

Почти тоже самое, за исключением:
JIT комплиция, можно EMIT (на андройде

Mono for Android Почти тоже самое, за исключением: JIT комплиция, можно EMIT
вообще все можно, порно, смс вирусы, убиение младенцев)
Одновременно живут две машины Mono VM и Dalvik VM
GREFs
Начиная с Android 1.6
Свой редактор UI в Monodevelop (alpha)

Слайд 32

Кроссплатформенность

Шаринг в районе 30-60 процентов кода
В основном работа c АПИ, с локальной

Кроссплатформенность Шаринг в районе 30-60 процентов кода В основном работа c АПИ,
базой, внутренняя бизнес логика
UI все равно переписывается
Xamarin.Mobile объединяющий основной мобильный функционал (фото, геолокация)
Есть различные MVC фреймворки

Слайд 33

Делайте хорошую архитектуру!

Четкое разеделение кода логики и UI
Unit test’ы (на девайсе тоже

Делайте хорошую архитектуру! Четкое разеделение кода логики и UI Unit test’ы (на
– TouchUnit)
Выносим все что можно, делаем общие методя для стандартных операций (Alert, InvokeOnMainThread итд)

Слайд 34

Xobot OS

Android переписанный на С#
Быстрее обычного андройда из-за особенностей C#
Просто концепт

Xobot OS Android переписанный на С# Быстрее обычного андройда из-за особенностей C# Просто концепт

Слайд 35

Риски

Риски

Слайд 36

Конкуренты

Appcelerator
PhoneGap
Unity (тоже на Mono работает)

Конкуренты Appcelerator PhoneGap Unity (тоже на Mono работает)