Как стать автором
Обновить

Комментарии 35

«мобильных аппликаций»
Сделайте меня развидеть это!
исправил на «мобильное приложение». так лучше?
Umputun с вами не согласен :)
НЛО прилетело и опубликовало эту надпись здесь
Воот. Три комментария об ошибках автора.
А куча какого-то хабрасброда меня ещё учить хотела :)
Всё правильно делаете, писать надо в комментах, а не в личку.
Приложение — аппликация
Разговор — конверсация
Производство — продакция
Продвижение — промоуция

ну вы поняли как много «правильных» слов новых может появиться =)
спасибо, я сейчас исправлю. Первый раз пишу тематический пост на русском
да это ерунда, на хабре всегда ворчат вслух ))
А сама статья интересная. Интересно если ли что-то подобное на Python?
к сожалению, Apple запрещает использовать динамические языки типа python, только компилируемые.
Это не так, примерно с 2010 года. Правило менялось несколько раз и в данный момент звучит так.

3.3.2 An Application may not download or install executable code. Interpreted code may only be used in an Application if all scripts, code and interpreters are packaged in the Application and not downloaded. The only exception to the foregoing is scripts and code downloaded and run by Apple’s built-in WebKit framework.

Т.е. если питоновские скрипты и интепретатор зашиты в клиент — то сколько угодно.
Тут какое-то противоречие. А как же ограничение динамических языков? Коим руби так же как и питон является.
upd — увидел в коменте выше, что ограничение уже не актуально.
Когда интересно сделают аналог рубмушн для питонистов?
«экране/телефоне/таблете». Таблет — планшет. А то таблет звучит немного странно.
А в целом, спасибо за статью!
спасибо, исправил
А расскажите, каким образом можно на нем вызывать нативные методы? Ну т.е. вот есть ряд платформозависимых плюшек которые нужно нам вызывать — на android java код, на ios objc и т.п. Ну в качестве пример fb sdk, или MAT sdk и т.п.

Каким образом происходит прокидывание вызовов из C# в «нативные» методы для различных платформ?
Приложение под iOS в итоге просто компилируется в нативный код, только добавляется небольшой рантайм .net. Сборка мусора, bcl и все что вы используете. Т.е. почти что трансляция кода из c# (MSIL) в obj-c.
Для доступа к сторонним либам, есть специальный тип проекта obj-c\java binding library который создает обертки над библиотекой и можно вызывать эти методы из c#
Создает автоматом как-то? И что с android? Т.е. есть у меня некоторое SDK — android и ios версия. Хочу чтобы один метод в C# в зависимости от платформы вызывал нужный метод на каждой платформы. Или мне придется сделать две обертки, и потом их еще обернуть в одну свою?

И обратный вопрос — как в платформо зависимом коде вызывать методы моей логики на C#?

Т.е. есть некоторое событие приходящие от встроенного SDK — callback, соотвественно в java коде хочеться вызвать мой C# метод и в objc его же. Для c++ методов это на ура делает, что мне придется в случае Xamarin делать?
Хочу чтобы один метод в C# в зависимости от платформы вызывал нужный метод на каждой платформы — просто передаем ему интерфейс, который отдельно имплементирован на каждой платформе.

как в платформо зависимом коде вызывать методы моей логики на C# — лучше всего делать наоборот, вызывать java код из C#. Но если нет, то смотрите мой ответ ниже, можно использовать JNI:
Java Native Interface – The Java Native Interface (JNI) is a framework that allows non-Java code (such as C++ or C#) to call or be called by Java code running inside a JVM.
Можно уточнить плиз. Вот упрощенный пример — вот есть у меня Java класс ClassA с статическим методом A и ObjectC класс classA со статическим методом А. Я хочу иметь в своей бизнес-логике C# класс ClassA со статическим методом A — который в зависимости на какой платформе мы запускаемся вызывал нужный метод.

Мне нужно сделать враппер на C# вокруг явской реализации, враппер на C# вокруг iOS реализации, и далее уже в C# сделать ClassA которые в зависимости от платформы (явным образом указанной? или можно автоматизировать?) вызывает нужный метод нужного врапера?

— По поводу «лучше всего делать наоборот» — не совсем понятно — т.е. вот есть некий callback в java, предлагает там взводить некий флажок, а в бизнес-логике его опрашивать (в паралельном потоке?) и по нему понимать что callback случился?
в принципе, тут у нас будет три проекта: core, iOs, Android. И все три написаны на C#
Теперь добавляем 2 новых проекта, один обвертывает Java class, второй обвертывает ObjectC class в классы C#.

теперь, если у нас бизнесс-логика написана в core, то мы передаем ему интерфейс с методом A, который он будет вызывать когда надо, в независимости от платформы. Сама имплементация этого интерфейса будет реализована в iOs/Android проектах, и они будут вызывать свой wrapper.

на второй отвечу чуть позже
Если честно, то я не нашел примеров запуска C# code из Java/Objective-C. Не совсем уверен, но мне кажется это практически невозможно
forums.xamarin.com/discussion/4904/possible-to-create-a-c-xamarin-library-add-and-call-it-from-java-app
Это возможно и это я сам делал. Мы создавали свою нативную ObjectiveC-библиотеку и из нее вызывали C#-код.
Как это делается на iOS:
1) Создается интерфейс на ObjectiveC (MonoObject.h):
@interface MonoOject : NSObject {
}

@property(nonatomic) BOOL isAuthenticated;

- (int) search: (NSString*)query;
@end

2) Нативная библиотека компилируется и подключается в Binding Library проект.
3) В ApiDefinition.cs файле этого проекта прописывается следующий код:
    [BaseType(typeof(NSObject), Name="MonoObject")]
    [Model]
    interface MonoObject
    {
        [Export("isAuthenticated")]
        [Abstract]
        bool IsAuthenticated { get; }

        [Export("search:")]
        [Abstract]
        int Search(string query);
    }

4) Создается наследник-имлементация от класса MonoObject:
public class MonoObjectImpl : MonoObject
{
    public override bool IsAuthenticated
    {
        get 
        {
            return true;
        }
    }
    ...
}

5) Объект класса MonoObjectImpl передается в нативный код и оттуда уже вызываются методы этого объекта.

Такой подход позволил нам создать нативную библиотеку со всем UI и взаимодействовать с ней. При этом вся бизнес логика осталась кросс-платформенной на C#.
Если в кратце, то мы создаем проект типа Java Bindings Library или Xamarin.iOs Binding Project. В этом проекте добавляем .jar файл, компилируем и автоматически получем C# обвертку (wrapper) на все методы и классы, обьявленные в jar как public.

image

Подробнее можно почитать у них на сайте:
There are three possible ways to reuse Java libraries in a Xamarin.Android application:

Create a Java Bindings Library – With this technique, a Xamarin.Android project is used to create C# wrappers around the Java types. A Xamarin.Android application can then reference the C# wrappers created by this project, and then use the .jar file.
Java Native Interface – The Java Native Interface (JNI) is a framework that allows non-Java code (such as C++ or C#) to call or be called by Java code running inside a JVM.
Port the Code – This method involves taking the Java source code, and then converting it to C#. This can be done manually, or by using an automated tool such as Sharpen.
docs.xamarin.com/guides/android/advanced_topics/java_integration_overview
Ага, это понятно. Спасибо. А как быть в ios? Ну т.е. SDK они такие, они под все платформы — можно же сделать так, чтобы этот враппер в случае ios вызывал нужные ios методы?

Или мне нужно будет ios wrapper, а потом еще свой wrapper которые объединит эти врапперы?

Ну и если про обратные вызовы (вызов C# методов из «платформенного» кода) расскажите тоже спасибо.
Враппер для метода в общем случае это «тупой» DllImport. Если же хочется не метод дергать, а именно выполнять одинаковую операцию на разных платформах, то нужен собственный уровень абстракции. Из коробки такого SDK в Xamarin нет, его надо либо писать, либо под каждую платформу отдельно кодить GUI, либо как-то исхитрятся. К примеру, у библиотек OpenGL ES одинаковый интерфейс на Xamarin of iOS и Xamarin for Android = OpenTK, потому портирование с одной платформы на другую может уложиться в пол-дня.
С удовольствем бы почитал статью о том, как правильно выстроить работу в Xamarin серьезного проекта с нативными интерфейсами под разные платформы.
Сейчас пишу под iOS на monotouch, впереди заточка под iPad и в перспективе андроид. Насущные вопросы — форкать ли код? Как правильно организовать работу, если все делается в одном проекте?

PS Случайно запостил в ветку, считайте это комментарием к статье.
По моему опыту, если писать интерфейс под каждую платформу в без-форковом проекте, то через какое-то время уж очень много появляется #if/#endif конструкций, потому я для себя решил делать всю бизнес-логику в виде отдельной общей библиотеки, а под интерфейс создавать отдельные проекты с нативными особенностями. Библиотека замораживается и больше не правится и не отлаживается при портировании. Подход работал отлично для iOS, Android, MonoMac и честного .Net, пока не в списке целей не добавилась Windows 8 — там отсутствуют или переделаны неймспейсы System.IO, System.Graphics, System.Xml и System.Data, потому пришлось чуть усложнить.
абсолютно согласен. особенно если разделять логику и интерфейс с помощью MVVM.
Еще одно очень замечательное изобретение в C# — partial class
Можете поглядеть как я это делаю на «Маке»: github.com/bolknote/MacGreenerCS (как раз Замарин и Си#).
Разработка под IOS без мака также недоступна? Скачал xamarin плюс тестовый пример tasky, попытался открыть — Android-версия без проблем, а IOS пишет что «this project type is not supported by Xamarin Studio on Windows».
Да, без мака не получится.
Да, я сейчас выбираю между этим вариантом через VPN и hackintosh.com
Еще можно купить mac mini за 20 тысяч.
Добавляем библиотеку MvvmCross через NuGet. Для примера мы выберем Hot Tuna Start Pack, который включает в себя несколько начальных файлов.
Важно убедиться, что установлена последняя версия NuGet Package Manager, как минимум 2.5

Замечательно, имеем NuGet 2.6.40627.9000

Полностью следуем всем шагам, описанным в статье, получаем:

Attempting to resolve dependency 'MvvmCross.HotTuna.MvvmCrossLibraries (≥ 3.0.9)'.
Attempting to resolve dependency 'MvvmCross.HotTuna.CrossCore (≥ 3.0.9)'.
Attempting to resolve dependency 'MvvmCross.PortableSupport (≥ 3.0.9)'.
Installing 'MvvmCross.PortableSupport 3.0.9'.
Successfully installed 'MvvmCross.PortableSupport 3.0.9'.
Installing 'MvvmCross.HotTuna.CrossCore 3.0.9'.
Successfully installed 'MvvmCross.HotTuna.CrossCore 3.0.9'.
Installing 'MvvmCross.HotTuna.MvvmCrossLibraries 3.0.9'.
Successfully installed 'MvvmCross.HotTuna.MvvmCrossLibraries 3.0.9'.
Installing 'MvvmCross.HotTuna.StarterPack 3.0.9'.
Successfully installed 'MvvmCross.HotTuna.StarterPack 3.0.9'.
Adding 'MvvmCross.PortableSupport 3.0.9' to HelloWorlderCross.
Uninstalling 'MvvmCross.PortableSupport 3.0.9'.
Successfully uninstalled 'MvvmCross.PortableSupport 3.0.9'.
Install failed. Rolling back…
Could not install package 'MvvmCross.PortableSupport 3.0.9'. You are trying to install this package into a project that targets 'portable-win+net40+sl40+wp71', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.

ЧЯДНТ?
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории