Open3

Swift Package Managerをただ使ってみる

Nao-RandDNao-RandD

概要

Swift Packageを作成してGitHubに配置して、それをプロジェクトから実行してみる

Packageの作成

  • 今回はコマンドラインからPackageを作成してみましょう
  • 作成したOpenAISwiftのメソッドを用いるPackage
  • OpenAISwift
    1. プロジェクトのディレクトリを作成:
      まず、プロジェクト用のディレクトリを作成して移動しましょう。

      $ mkdir MySwiftPackage
      $ cd MySwiftPackage
      
    2. Swift パッケージを初期化:
      次に、Swift パッケージを初期化します。ここでは、ライブラリタイプのパッケージを作成するために -type library オプションを使用します。

      $ swift package init --type library
      

      これにより、ディレクトリ構造が作成され、以下のファイルが含まれます。

      • Package.swift: パッケージのメタデータと依存関係を定義
      • Sources/MySwiftPackage: ソースコードディレクトリ
      • Tests/MySwiftPackageTests: テストコードディレクトリ
    3. パッケージの内容を編集:
      Sources/MySwiftPackage/MySwiftPackage.swift ファイルを開き、次のコードを追加して簡単なサンプル機能を作成します。

      public struct MySwiftPackage {
          public static func hello() {
              print("Hello, world!")
          }
      }
      
      
    4. パッケージのビルド:
      プロジェクトディレクトリで swift build コマンドを実行してパッケージをビルドします。

      $ swift build
      
      
    5. テストの実行:
      テストを実行するには、swift test コマンドを使用します。

      $ swift test
      
      
    6. リポジトリを GitHub に公開:
      プロジェクトディレクトリで Git を初期化し、リモートリポジトリを追加してプッシュします。

      $ git init
      $ git add .
      $ git commit -m "Initial commit"
      $ git branch -M main
      $ git remote add origin <https://github.com/YourUsername/MySwiftPackage.git>
      $ git push -u origin main
      
      

      これで、Swift Package Manager を使用して OSS を作成する方法が完了しました。他の人がこのパッケージを利用できるようになりました。他のプロジェクトでこのパッケージを使用するには、Package.swift ファイルに依存関係を追加するだけです。

    7. OpenAISwiftをMySwiftPackage経由で実行してみましょう

      1. Package.swift

        // swift-tools-version: 5.7
        // The swift-tools-version declares the minimum version of Swift required to build this package.
        
        import PackageDescription
        
        let package = Package(
            name: "MySwiftPackage",
            platforms: [
                .iOS(.v13),
            ],
            products: [
                // Products define the executables and libraries a package produces, and make them visible to other packages.
                .library(
                    name: "MySwiftPackage",
                    targets: ["MySwiftPackage"]),
            ],
            dependencies: [
                // Dependencies declare other packages that this package depends on.
                // .package(url: /* package url */, from: "1.0.0"),
                .package(url: "https://github.com/adamrushy/OpenAISwift.git", from: "1.3.0"),
            ],
            targets: [
                // Targets are the basic building blocks of a package. A target can define a module or a test suite.
                // Targets can depend on other targets in this package, and on products in packages this package depends on.
                .target(
                    name: "MySwiftPackage",
                    dependencies: [
                        "OpenAISwift"
                    ]),
                .testTarget(
                    name: "MySwiftPackageTests",
                    dependencies: ["MySwiftPackage"]),
            ]
        )
        
      2. MySwiftPackage.swift

      import OpenAISwift
      
      public struct MySwiftPackage {
          public private(set) var text = "Hello, World!"
      
          public init() {
          }
      
          public static func hello() {
              print("Hello, world!")
          }
      
          public static func getRandomEmoji(token: String) async -> String {
              do {
                  let openAPI = OpenAISwift(authToken: token)
                  let result = try await openAPI.sendCompletion(with: "A random emoji")
                  print(result)
                  return result.choices?.first?.text ?? "nilだったよ"
              } catch {
                  return "失敗:\(error.localizedDescription)"
              }
          }
      }
      
Nao-RandDNao-RandD

Packageを使う

Xcodeを用いない場合

  • MySwiftPackage を使用するサンプルプロジェクトを作成していきます
    1. 新しいディレクトリで実行可能な Swift プロジェクトを作成:

      $ mkdir MySampleApp
      $ cd MySampleApp
      $ swift package init --type executable
      
      
    2. 依存関係を追加:
      Package.swift ファイルを開き、dependenciestargets のセクションに、先ほど作成した MySwiftPackage の GitHub リポジトリを追加します。以下のように変更してください。

      // swift-tools-version:5.5
      import PackageDescription
      
      let package = Package(
          name: "MySampleApp",
          dependencies: [
              // ここに MySwiftPackage を追加
              .package(url: "<https://github.com/YourUsername/MySwiftPackage.git>", from: "0.1.0"),
          ],
          targets: [
              .executableTarget(
                  name: "MySampleApp",
                  dependencies: [
                      // ここに MySwiftPackage を追加
                      "MySwiftPackage"
                  ]),
              .testTarget(
                  name: "MySampleAppTests",
                  dependencies: ["MySampleApp"]),
          ]
      )
      
      
    3. パッケージを使用:
      Sources/MySampleApp/main.swift ファイルを開き、MySwiftPackage をインポートし、その機能を使用します。以下のように変更してください。

      import MySwiftPackage
      
      MySwiftPackage.hello()
      
      
    4. プロジェクトをビルドして実行:
      以下のコマンドを実行して、プロジェクトをビルドし、実行します。

      $ swift build
      $ swift run
      
      

      実行すると、MySwiftPackage から提供される hello() 関数が呼び出され、コンソールに "Hello, world!" と出力されます。これで、他のプロジェクトで MySwiftPackage を使用する方法が分かりました。

Xcodeを用いる場合

  • Package Dependenciesからhttps://github.com/Nao-RandD/MySwiftPackageを追加

  • 作成したプロジェクトで試しに呼び出してみる

    import SwiftUI
    import MySwiftPackage
    
    struct ContentView: View {
        @State var emoji: String = "Hello World"
    
        var body: some View {
            VStack {
                Image(systemName: "globe")
                    .imageScale(.large)
                    .foregroundColor(.accentColor)
                Text(emoji)
                Button(action: {
                    MySwiftPackage.hello()
                    Task {
                        let _emoji = await MySwiftPackage.getRandomEmoji(token: "[OpenAIのAPIトークン]")
                        emoji = _emoji
                    }
                }, label: {
                    Text("SPMの呼び出し")
                })
            }
            .padding()
        }
    }
    
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView(emoji: "😇")
        }
    }
    
Nao-RandDNao-RandD

Packageを作成→GitHubに公開→他のプロジェクトで利用
というものが簡単にできました✨

他のPackageも読み込んでラッパー的に呼び出すこともできて一旦満足です
ここから個人的な用途に応じてOSSとしてPackageを公開したいですね