Kisaragi's Hack Diary

とにかく興味のあることに挑戦していく日記です

iOSからPythonコードを呼び出せるようにしてみる。

ブログ始めました。

自分が学んだことを記録に残して共有したいと思ってブログを始めました。

これから不定期に更新していきます。

本題に入る前に軽く自己紹介しとくと、

  • ほぼ機械系学生
  • swiftが大好き
  • 脱獄Tweak作成始めました。

そろそろ皆さんブラウザバックしようとしてるかもなので、前置きはこれくらいにして本題に入ります。

この記事の目的

Macでは標準でPythonが入っているので標準のPython.frameworkを追加することで簡単にswiftからPythonコードを呼び出すことはできますが、iOSに関してはPython.frameworkが用意されていません。

そこで、「どうしてもiOSアプリにPythonライブラリを組み込みたい」という方に向けて記事を書きました。



やっていく

※環境macOS Catalina 10.15.1でしてます。

1.必要なファイルをダウンロード 

今回は以下のファイルを使用させていただきます。

github.com

Read.meの中から使用したいPythonのバージョンを選べます。今回は3.4を使用します。 遷移先のリポジトリのRead.meからfor iOSのリンクをクリックすると必要ファイルがダウンロードされます。

フォルダ内のSupportフォルダを開くと以下のようになっていると思います。 f:id:kisaragi_jb:20191130033608p:plain

2.プロジェクトにフレームワークを追加

先ほど作成したファイルをPythonを使用できるようにしたいxcodeのプロジェクトに追加します。 以下のフォルダ内にframeworksというフォルダを作成して先ほどの4つのファイルを追加します。

f:id:kisaragi_jb:20191130034537p:plain

次にPythonTest.xcodeprojを開き、Target->general->Frameworks,Libraries~の部分の+ボタンを押します。 f:id:kisaragi_jb:20191130035301p:plain すると以下のようになると思うのでAdd Files...を押します。 f:id:kisaragi_jb:20191130040126p:plain

そこからさっき追加した4つのフォルダ内にある以下の4つのファイルを追加します。

  • libPython.a
  • libOpenSSL.a
  • libxz.a
  • libbzip2.a

加えて検索バーから以下の二つのファイルを追加します。

  • libz.tbz
  • libsqlite3.tbz

XcodeのTarget->Build setting->Header Search Paths$(PROJECT_DIR)/frameworks/Pythonと入力します。 f:id:kisaragi_jb:20191130070818p:plain

3.Pythonをimport

ここまでの設定でpythonの導入はできていますが、最後にimportしてコードから使えるようにします。 Xcode->File->New->File..からobjective-cのファイルを作成します。このファイルはこれ以降使用することはないので名前は適当で大丈夫です。 すると以下のような画面が出てくるので、 f:id:kisaragi_jb:20191202000532p:plain 一番右のCreateを押します。すると、アプリ名-Bridging-Header.hというファイルができるので、そのファイル内に#include "Python/Python.h"と記入します。

4.PYTHONHOMEの設定

AppDelegateのdidFinishLaunchingWithOptionsやviewDidLoadなどで以下の記述をします。

let resourcePath = Bundle.main.resourcePath! + "/Python3/Resources"
let python_home = "PYTHONHOME=\(resourcePath)" as NSString
putenv(UnsafeMutablePointer(mutating: python_home.utf8String))

5.完了

あとはコードを使う前などにPy_Initialize()を行ってから好きに使ってください。 試しに以下のコードを実行してみます。

PyRun_SimpleStringFlags("import sys\nprint(sys.version_info)", nil)

成功 f:id:kisaragi_jb:20191202005316p:plain

最後に

いきなりマイナーで需要のあまりなさそうな内容の記事になりましたが、自分が必要になったときにかなり大変だったのでまとめてみました。

指摘事項、質問等ございましたら気軽に連絡ください。 返信が遅い場合はtwitterのDM等で催促してもらえればすぐ返信します。


最後になりましたが、

Twitterフォローしろ

twitter.com