Swiftでframeworkを作って利用する

# なぜframeworkを作ろうと思ったか
数値の配列からその特徴を抽出するクラスを生成しました。
割といい感じのクラスで、使いやすく、尚且つそのアルゴリズムが簡単...
ソースコードの中身がわかると「そんな程度でできるんだ...」と思われるのもなんか悔しい。
ならばソースコード非公開で利用してもらうのがいい！
その手法の一つがframeworkだったわけです。
# frameworkを作る
### Xcodeプロジェクトを作る
今回はmacOS、iOSの両方で使える`Multipratform`のframeworkを作ります。
数値計算だけのプログラムでGUIが関わらないため、macOS、iOSとも同じソースコードが利用できます。
`MyFramework`というプロジェクト名にしました。

![スクリーンショット 2024-10-20 9.59.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202602/ef91f615-6719-a3ad-962c-5861e1fec04e.png)

実際に処理をする`MyFramework`というソースファイルをプロジェクトに追加します。
MyFrameworkクラスに`hello()`というメソッドを実装します。
「Hello, World!」という文字列を返すメソッドです。
``` swift
public class MyFramework {
    ///プロパティ、メソッドの使い方などのコメント
    public static func hello() -> String {
        return "Hello, World!"
    }
}
```

![スクリーンショット 2024-10-20 10.28.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202602/c9234638-9237-1cb0-94aa-3db6fa37a8f5.png)

これでプログラム自体は完成です。

### ビルドの準備
今回の目標は
- ソースコードは非公開にする
- macOS、iOSでも使える

です。
#### ビルドスキーム
ソースコードを非公開にするには`Release`でビルドします。
Releaseビルドにより、デバッグシンボルがframeworkに含まれなくなります。

#### プラットフォームごとにビルド
macOS、iOSの実機、iOSのシミュレータごとにビルドする必要があります。
どのプラットフォームでビルドするかは下記のように選ぶことができます。

![スクリーンショット 2024-10-20 10.29.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202602/14270c54-82bb-9eba-6b6f-5e38f6aed629.png)

ビルドされたProductsのフォルダ内を見てみると、それぞれのプラットフォームごとにframeworkが出来上がっています。
これでframeworkは完成です。

![スクリーンショット 2024-10-20 10.25.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202602/22e2c796-4b67-52cc-565b-c3960b8abcf5.png)

# 作ったframeworkを使う
frameworkを使うプロジェクトをXcodeで作成します。
もちろん、既存のプロジェクトに取り込んで使うこともできます。
今回はmacOSの`FrameworkTEST`というプロジェクトを作りました。

![スクリーンショット 2024-10-20 10.31.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202602/cb9d9a21-3b3c-5845-3ef9-fdd9b984d276.png)

### プロジェクトにフレームワークを取り込む
ビルドしたframeworkを利用したいプロジェクトにドラッグ&ドロップします。
わかりやすいように、プロジェクト内に`frameworks`というフォルダを作りました。

![スクリーンショット 2024-10-20 10.39.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202602/e016f196-5206-5ce3-502f-a0a0d626d213.png)

この後、いくつかやらなければならない作業があります。
まず、frameworkの設定を`Embed & Sign`にします。

![スクリーンショット 2024-10-20 10.41.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202602/f07a3d22-61af-8d66-1d75-eeabd00927c2.png)

次にBuild Settingの`framework Search Paths`を指定します。
今回はプロジェクト内のフォルダに入れたので、そのフォルダを設定用のポップオーバーにドラッグ&ドロップすれば簡単に指定できます。

![スクリーンショット 2024-10-20 10.47.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202602/76947dab-e812-53d9-844e-9f7a19d23bab.png)

これでframeworkを使う準備は完了しました。

### ソースコードでframeworkを利用する
まずは利用するソースコードの冒頭でインポートします。
``` swift
import MyFramework
```
MyFrameworkのhello()メソッドを使います。
``` swift
print(MyFramework.hello())
```
ソースコード全体はこんな感じです。
``` swift
import Cocoa
import MyFramework

class ViewController: NSViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        print(MyFramework.hello())
    }

    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }
}
```
実行すれば、ターミナルに「Hello, World!」が表示されます。

![スクリーンショット 2024-10-20 11.11.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202602/7592c985-4d7c-90f7-5b02-12964db89f3b.png)

# ソースコードが非公開になっているか？
私はここでハマりました...
設定類は問題なく、実際は非公開になるはずです。
しかし、デバッガでframeworkのメソッドにStep Inすると、なんとソースコードが見えています！
これ、同じMacでframeworkを作って、同じMacで使っていることが原因です。
Mac内にデバッグシンボルが残っているので、それを参照してしまうということです。

なので、同じMacに別のログインアカウントを作り、そちらで確認してみます。
これでStep Inできなければ、無事非公開になっています。
別のアカウントで実行したところ、Step Inできないので、無事非公開になっています。
ターミナルには「Hello, World!」が表示され、無事frameworkが使えています。

![スクリーンショット 2024-10-20 11.08.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202602/5a2a8a9e-d8a6-bdf6-5d14-19f96d9c9beb.png)


また、frameworkで利用できるプロパティ、メソッドの定義も見ることができました。

![スクリーンショット 2024-10-20 11.09.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202602/002bcc1c-2707-5fb3-77ac-6680930095f3.png)

# 無事完成
これでソースコードを非公開にしつつ、frameworkを通して自分で作ったクラスなどを多くの人に利用してもらうことができます。