Upgrade to Pro — share decks privately, control downloads, hide ads and more …

iOSDC2020: J2ObjCを使ってJava資産 をiOS開発で使ってみた

iOSDC2020: J2ObjCを使ってJava資産 をiOS開発で使ってみた

iOSDC2020: J2ObjCを使ってJava資産 をiOS開発で使ってみた

https://fortee.jp/iosdc-japan-2020/proposal/a94bc318-9ba2-4c22-8e32-6be8fdcb8716

Akihiro Urushihara

September 19, 2020
Tweet

More Decks by Akihiro Urushihara

Other Decks in Programming

Transcript

  1. SocialHub • iOS/Android 向けのマルチ SNS クライアントアプリ ◦ SNS 周りのロジックは共通のものを使用したい ▪

    できる限り既存 OSS ライブラリを用いて楽したい ◦ 普段使いするアプリを目指すので UI/UX 妥協しない
  2. SocialHub • iOS/Android 向けのマルチ SNS クライアントアプリ ◦ SNS 周りのロジックは共通のものを使用したい ▪

    できる限り既存 OSS ライブラリを用いて楽したい ◦ 普段使いするアプリを目指すので UI/UX 妥協しない ライブラリは共有し、UI は OS 毎にネイティブで書きたい!
  3. Embeddinator-4000 • .NET ライブラリを他言語で使用可能にするプロジェクト ◦ Xamarin のサブプロジェクト ◦ iOS 向けに

    Objective-C に変換する機能がある ▪ ジェネリクスが使えない (#232) 制限がありこれが致命的
  4. J2ObjC • Java → Objective-C トランスレータ ◦ Java の既存 OSS

    ライブラリが使用可能! ◦ Kotlin/Native にも鞍替えがギリギリ可能! ◦ 知見は国内にはほぼ無い!
  5. Hello World • Java コードを準備 • Objective-C へ変換 public class

    Main { public static void main(String[] args) { System.out.println("Hello World"); } } $ j2objc Main.java Java
  6. #include "IOSObjectArray.h" #include "J2ObjC_source.h" #include "Main.h" #include "java/io/PrintStream.h" #include "java/lang/System.h"

    @implementation Main - (instancetype)init { Main_init(self); return self; } + (void)mainWithNSStringArray:(IOSObjectArray *)args { Main_mainWithNSStringArray_(args); } // リフレクション等ためのメタデータ情報 + (const J2ObjcClassInfo *)__metadata { /* ... */ } @end void Main_init(Main *self) { /* ... */ } Main *new_Main_init() { /* ... */ } Main *create_Main_init() { /* ... */ } void Main_mainWithNSStringArray_(IOSObjectArray *args) { Main_initialize(); [((JavaIoPrintStream *) nil_chk(JreLoadStatic(JavaLangSystem, out))) printlnWithNSString:@"Hello World"]; } Objective-C (.m)
  7. 例外 • Objective-C のレイヤーで対処 @try { /* ... */ }

    @catch (JavaLangThrowable *throwable) { /* ... */ } Objective-C (.m)
  8. 弱参照 • @Weak @Property 等を付与してメモリリークを回避 public class Main { @Weak

    private Runnable callback; Java @interface Main () { @public __unsafe_unretained id<JavaLangRunnable> callback_; } Objective-C (.m)
  9. 弱参照 • @Weak @Property 等を付与してメモリリークを回避 public class Main { @Property("weak,

    nonatomic") protected Runnable callback; Java @interface Main : NSObject { @public __unsafe_unretained id<JavaLangRunnable> callback_; } @property (weak, nonatomic) id<JavaLangRunnable> callback; Objective-C (.h)
  10. 関数名 • デフォルトでは型名が関数名に付与される public void setDate(int year, int month, int

    day){ /* … */ } Java - (void)setDateWithInt:(jint)year withInt:(jint)month withInt:(jint)day { Objective-C (.m)
  11. 関数名 • @ObjectiveCName を付与して指定 @ObjectiveCName("setDateWithYear:month:day:") public void setDate(int year, int

    month, int day){ /* … */ } Java - (void)setDateWithYear:(jint)year month:(jint)month day:(jint)day { Objective-C (.m)
  12. Nullability • @Nonnull @Nullable (jsr305) を付与して Nullability を明示 public class

    Main { public void greeting(@Nonnull String name){ /* ... */ } Java - (void)greetingWithNSString:(NSString * __nonnull)name; Objective-C (.h)
  13. gradle-plugin (uakihir0/j2objc-gradle) • 問題のあった箇所を修正して公開中 ◦ Gradle 4.x に対応 ▪ 2.x

    から修正 ◦ 静的ライブラリの作成方法を変更 ▪ ar → libtool に変更 (コマンド長の問題に対応)
  14. Other Problems • HmacSHA1 の暗号化ができない問題 ◦ USの暗号化輸出規制の問題? 再実装して対応 • Java

    のクラスの動的読み込み問題 ◦ Class.forName(“...”) で文字列からクラスを作成される問題 ◦ 生成されそうなクラスは別途コンパイル対象に指定