Pythonista3 のメインヒロイン。objc_util での実装の流れ（実装事例随時更新）

この記事は、[Pythonista3 Advent Calendar 2022](https://qiita.com/advent-calendar/2022/pythonista3) の14日目の記事です。

https://qiita.com/advent-calendar/2022/pythonista3


一方的な偏った目線で、Pythonista3 を紹介していきます。

ほぼ毎日iPhone（Pythonista3）で、コーディングをしている者です。よろしくお願いします。

以下、私の2022年12月時点の環境です。

``` .log
--- SYSTEM INFORMATION ---
* Pythonista 3.3 (330025), Default interpreter 3.6.1
* iOS 16.1.1, model iPhone12,1, resolution (portrait) 828.0 x 1792.0 @ 2.0
```

他の環境(iPad や端末の種類、iOS のバージョン違い)では、意図としない挙動(エラーになる)なる場合もあります。ご了承ください。

ちなみに、`model iPhone12,1` は、iPhone11 です。

## 宝探しとか、もしくは脱出ゲームのような

Pythonista3 では用意されていないiOS の機能を呼び出したい場合、`objc_util` を使います。

[objc_util — Utilities for bridging Objective-C APIs — Python 3.6.1 documentation](https://omz-software.com/pythonista/docs/ios/objc_util.html)

https://omz-software.com/pythonista/docs/ios/objc_util.html


> objc_util モジュールは、Python から Objective-C の API を利用するための「橋渡し」をしてくれます。

> ctypes と Objective-C ランタイムライブラリに基づいて、objc_util は既存の Objective-C クラスを、Python のメソッド呼び出しを対応する Objective-C メッセージに自動的に変換する方法で「ラップ」することを可能にします。

Objective-C（もしくは、Swift）のコードサンプルを参考にPythonista3 で実装ができるようになります。

私はiOS アプリ開発も、Objective-C・Swift も普段は書かないので、毎回検索の繰り返しです。

### 手順や確認点

`objc_uitl` を使い始めると「Python を書いているはずなのになんだ、これは？」と、定食屋で割り箸を使ってフレンチのフルコースを食べてる感覚になります（ぜんぜん違う）。

お気持ちも含めた、流れです。

#### 余裕ライン。ぜんぜんあるあるのやつ

- 既に`objc_util` へ取り込まれているか
  - Documentation を読む
  - `from objc_util import *` でinspector を確認
    - module を直接見に行ったりもします
      - `[Python Modules]` → `[Standard Library(3.6)]` → `[site-packages]` → `objc_util.py`
      - `__all__` に入ってない、Documentation に書いてない可能性もあり

`CGRect` からの`CGPoint`, `CGSize` を再実装しがちです。

`UIColor` も実は実装されています（inspector で確認できます）。

- Apple Developer Documentation（Language:Objective-C）で確認
  - [Technologies | Apple Developer Documentation](https://developer.apple.com/documentation/technologies?language=objc)

Swift で表示されがちですが、Objective-C にしましょう。

- Class か？
  - `ObjCClass` で呼び出してみる
    - エラーの場合は、Framework は何かを確認

- Framework か？
  - `load_framework` でFramework を呼び出す
  - `〜Kit`, `〜View` などで分かれてFramework が存在していないか

`ObjCClass` や`load_framework` だけで、済む時の嬉しさ。

#### おっ、あ。なるほどですねぇ

- Enumeration Case
  - Apple Developer Documentation の`Declaration` にある整数を指定
    - だいたい整数の意味を忘れるので、変数で対象の名前に
    - Objective-C だとキャメルケースで長い
    - Swift だと`.` で区切られている

- Instance Method
  - `objc_util` のオブジェクトから素直に呼び出せる
  - `.hoge_fuga_` となる引数の確認の方が大事
    - Swift だと名称が変わっていることの方が多いので注意

- Instance Property
  - `objc_util` で呼び出したオブジェクトから持ってくることが多い
    - `print` して確認
  - 要素を絞りきれていない可能性があるので、Apple Developer Documentation の`See Also` から、それっぽいのを探す

- Swift の`override`
  - `override` するものがないので、`override` のつもりで普通に実装

「Swift やObjective-C 書いている人ならわかるんだろうな」と、なんとなく考えつつ、地道ながらも調べて出てきたものでなんとかなる。

#### （正座をしだす）

- Function
  - `c.` を使って、`ctypes` の`argtypes`, `restype` で、定義する
  - 引数の型の確認

- Delegate
  - `create_objc_class` を使いながら実装
    - [objc_util.create_objc_class | objc_util — Utilities for bridging Objective-C APIs — Python 3.6.1 documentation](https://omz-software.com/pythonista/docs/ios/objc_util.html#objc_util.create_objc_class)
  - サンプルにあるような`self` を代入ではなく、`create_objc_class` インスタンスを渡す
  - 変数管理が面倒
  - `print` デバッグが面倒
    - とりあえず、実装を先送りする

- Block
  - `ObjCBlock`
    - [objc_util.ObjCBlock | objc_util — Utilities for bridging Objective-C APIs — Python 3.6.1 documentation](https://omz-software.com/pythonista/docs/ios/objc_util.html#objc_util.ObjCBlock)
  - 変数管理が面倒
  - Pythonista3 で`ObjCBlock` が動くかわからないので不安

- Type Alias
  - 指定されている型を調べ`ctypes` で実装
  - `ctypes` で構造体を作る可能性も
  - ポインタの取り回しを意識する

- Global Variable
  - 最悪のパターンとして、GitHub に上がっている謎のアーカイブみたいなやつから、謎の数桁整数値をコピペしてくる
  - とりあえず`str` で入れてみるなど悪あがきも

ここら辺となると、検索したサイトでは普通に呼び出して普通に実装（Swift やObjective-C なので当たり前）しています。

前処理の変数や引数情報が、日本語の解説では皆無な場面も出てきます。

一つの希望として、Xamarin のドキュメントで調べる手もあります。

日本語ドキュメントは機械翻訳がメインと考えられるので、避けるが吉でしょう。

[Xamarin.iOS - Xamarin | Microsoft Learn](https://learn.microsoft.com/ja-jp/xamarin/ios/)

https://learn.microsoft.com/ja-jp/xamarin/ios/


また過去に1度だけ（何かは忘れましたが）、React Native のGitHub リポジトリのissues から見つけて解決したこともありました。

[Issues · facebook/react-native](https://github.com/facebook/react-native/issues?q=is%3Aissue)

https://github.com/facebook/react-native/issues?q=is%3Aissue


しれっと、`ctypes` モジュールを使う場面も出てきます。もうPython を書いているのか何なのかわからなくなります。

[ctypes --- Pythonのための外部関数ライブラリ — Python 3.11.0b5 ドキュメント](https://docs.python.org/ja/3/library/ctypes.html)

https://docs.python.org/ja/3/library/ctypes.html


```Function呼び出し例.py
Function = c.Function
Function.argtypes = []
Function.restype = ctypes.c_void_p
```

### 実装事例

事例は、[Pythonista3 Advent Calendar 2022](https://qiita.com/advent-calendar/2022/pythonista3) で更新していきます。

（以下更新予定: 対応リンクを貼り付ける予定です）

## 次回は

`objc_util` モジュールの実装手順と、`print` 出力による確認方法について紹介しました。

次回より、私の`objc_util` を使った実装を紹介していきます。


ここまで、読んでいただきありがとうございました。

## せんでん

### Discord

Pythonista3 の日本語コミュニティーがあります。みなさん優しくて、わからないところも親身に教えてくれるのでこの機会に覗いてみてください。

https://t.co/0IOW2hn1VC

### 書籍

iPhone/iPad でプログラミングする最強の本。

- [Python や Jupyter で iPhone/iPad 先端機能を簡単･自由にプログラミング！「活用篇」：hirax](https://techbookfest.org/product/1WiyV4LEev3f4YrzesRKWV?productVariantID=axX32srsSgtLtZWUtjkj99)

https://techbookfest.org/product/1WiyV4LEev3f4YrzesRKWV?productVariantID=axX32srsSgtLtZWUtjkj99

- [Python や Jupyter で iPhone/iPad 先端機能を簡単･自由にプログラミング！「土台篇」：hirax](https://techbookfest.org/product/wTZTyeibm5GQ5XgdfMrEBV?productVariantID=kRDmN1udbEYZUWbETdwL8r)

https://techbookfest.org/product/wTZTyeibm5GQ5XgdfMrEBV?productVariantID=kRDmN1udbEYZUWbETdwL8r

### その他

- サンプルコード

[Pythonista3 Advent Calendar 2022](https://qiita.com/advent-calendar/2022/pythonista3) でのコードをまとめているリポジトリがあります。

コードのエラーや変なところや改善点など。ご指摘やPR お待ちしておりますー

https://github.com/pome-ta/Pythonista3AdventCalendar2022sampleCode

- Twitter

なんしかガチャガチャしていますが、お気兼ねなくお声がけくださいませー

https://twitter.com/pome_ta93

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">やれるか、やれないか。ではなく、やるんだけども、紹介説明することは尽きないと思うけど、締め切り守れるか？って話よ！（クズ）<br><br>Pythonista3 Advent Calendar 2022 <a href="https://t.co/JKUxA525Pt">https://t.co/JKUxA525Pt</a> <a href="https://twitter.com/hashtag/Qiita?src=hash&amp;ref_src=twsrc%5Etfw">#Qiita</a></p>&mdash; pome-ta (@pome_ta93) <a href="https://twitter.com/pome_ta93/status/1588570697777152006?ref_src=twsrc%5Etfw">November 4, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

- GitHub

基本的にGitHub にコードをあげているので、何にハマって何を実装しているのか観測できると思います。

https://github.com/pome-ta