Hướng dẫn gọi Native iOS trong Unity bằng Swift Packages

Hướng dẫn gọi Native iOS trong Unity bằng Swift Packages

Chào các bạn, mình là La Dương Xuân Linh, Unity developer tại OneTech Asia. Hôm nay mình sẽ chia sẻ một bài hướng dẫn cách gọi từ Native iOS sang Unity bằng cách tạo Swift Packages (Calling Native iOS in Unity with Swift Packages).

Tạo một Swift Package bằng Xcode bên phía iOS

  • Chúng ta cần sử dụng một máy tính có hệ điều hành macOS và có XCode phiên bản nhỏ hơn XCode 14.0.0 do tính năng xcodebuild (tính năng này dùng để build một xcodeproj từ terminal thành một framework để chúng ta có thể sử dụng trong Unity) đã bị deprecated ở những phiên bản sau đó.
  • Chúng ta cũng cần set phiên bản xcode sử dụng ở terminal bằng cách chọn trên thành Menu ở: Xcode -> Settings 
Figure 1. Creating a Swift Package
Figure 1. Creating a Swift Package
    Figure 2. Our Swift Package
    Figure 2. Our Swift Package

    Định nghĩa một Swift function để sử dụng trong Unity

    • Tiếp đến chúng ta truy cập vào Sources/ và tạo một file .swift để tạo một function mà chúng ta có thể xuất ra và sử dụng trong Unity.
    • Để định nghĩa một function như vậy thì chúng ta cần thêm keyword @_cdecl(“function_Name”) ở trước function đó để khi chúng ta gọi xcodebuild trong terminal thì function đó sẽ được định nghĩa ở các tầng thấp hơn (C) => Điều này giúp chúng ta gọi được **DllImport(“__Internal”)*** trong Unity và sử dụng function đó.*
    • Ví dụ, chúng ta có một trường hợp như thế này:

    NativeiOS.swift

    public struct NativeiOSCode {
        static func callFromNative(input: String) {
            print("Hello - I am running a native iOS function ! ✅ - Your input was: \(input)")
        }
    }

    Unity_NativeiOS.swift

    import Foundation 
     @_cdecl("NativeiOSCode_callFromNative")
     public func NativeiOSCode_callFromNative(input: UnsafePointer<CChar?>){
         guard let input else {
             print("🚨 Input was null!")
         } 
         if let inputString = String(validatingUTF8:input){
             NativeiOSCode.callFromNative(input: inputString)
         } else{
             print("🚨 Wrong input format!")
         }
     }
    • Ở đây chúng ta có một struct NativeiOSCode sở hữu một static function (static là keyword chúng ta dùng khi ta muốn một thuộc tính hoặc một function của một class là của chung class đó chứ không phải của từng Instance được tạo của class đó). Static function này sẽ in ra một chuỗi ký tự và nhận một parameter tên input thuộc type string
    • Khi chúng ta muốn sử dụng function này trong Unity, chúng ta sẽ tạo một function keyword cdecl với tên gọi mà chúng ta muốn gọi bên phía Unity như trên (Trong trường hợp này là NativeiOSCode_callFromNative) ## 3. Đóng gói Package thành framework
    • Trước khi đóng gói những gì chúng ta đã làm để sử dụng trong Unity, trước hết ta phải tạo một xcodeproj cho package này.

    Tạo framework

    Chúng ta vào terminal và navigate vào thư mục tương ứng để tạo file .framework theo các lệnh như sau:

    cd Projects/NativeiOSCode
    swift package generate-xcodeproj --skip-extra-files
    xcodebuild -project NativeiOSCode.xcodeproj -scheme NativeiOSCode-Package -configuration Release -sdk iphoneos CONFIGURATION_BUILD_DIR=.

    Hình ảnh directory sau khi chúng ta tạo được framework

    Figure 3.Image of the framework being created
    Figure 3.Image of the framework being created

    Sử dụng Swift framework trong Unity

    Trước hết chúng ta cần thư mục NativeiOSCode.framework vào project Unity ở thụ mục Assets\ để có thể sử dụng những gì chúng ta hiện thực bên phía Swift.

    Unity Plugin Folder
    Figure 4. Unity Plugin Folder

    Sau đó, chúng ta import function NativeiOSCode_callFromNative ở trên (Lưu ý khi import chúng vẫn phải sử dụng tên này do compiler đã nhận tên này khi chúng ta đóng gói bên phía Swift).

    Lưu ý: Đổi platform Unity sang iOS và build project iOS để sử dụng.

    UnityCode.cs

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using System.Runtime.InteropServices;
    #if UNITY_IOS
        [DllImport("__Internal")]
        private static extern void NativeiOSCode_callFromNative(string input);
    #endif
    public class UnityCode : MonoBehaviour{
        void Start()
        {
            callNativeiOS("Running native iOS Code from Unity");
        }
        private void callNativeiOS(string message){
            #if UNITY_IOS
            NativeiOSCode_callFromNative(message);
            #endif
        }
    }

    Đây là kết quả chúng ta có được sau khi build project trên platform iOS:

    Results of the framework
    Figure 5. Results of the built framework

    Kết luận

    Như vậy, chúng ta đã gọi một function từ iOS trong Unity bằng cách tạo framework thông qua việc tạo một Swift Package. Tôi mong thông qua bài hướng dẫn này, các bạn có thể làm được nhiều thứ hơn trong Unity thông qua việc gọi được NativeiOS.

    Reference: Bài viết trên của mình được thực hiện sau khi tìm hiểu các tài liệu sau, nếu các bạn quan tâm có thể tham khảo thêm nhé:

    La Dương Xuân Linh | ✉ linhldx@onetech.vn | 📅 2023/11/11

    Tư vấn - Báo giá
    Mở rộng quy mô doanh nghiệp của bạn với ONETECH!
    Hãy liên hệ với chúng tôi để được cung cấp các dịch vụ phát triển phần mềm chất lượng cao với chi phí hợp lý nhất. Các kỹ sư của chúng tôi sẽ giúp bạn phát triển một giải pháp phù hợp để vượt lên đối thủ cạnh tranh của mình.
    Mọi thông tin tư vấn và báo giá đều miễn phí.

      「Chính sách bảo mật」Nếu bạn đồng ý với những điều trên, vui lòng nhấp vào nút "Gửi"
      Một email trả lời tự động sẽ được gửi đến địa chỉ email bạn đã nhập, vì vậy hãy kiểm tra điều đó.
      Tư vấn - Báo giá
      Mở rộng quy mô doanh nghiệp của bạn với ONETECH!
      Hãy liên hệ với chúng tôi để được cung cấp các dịch vụ phát triển phần mềm chất lượng cao với chi phí hợp lý nhất. Các kỹ sư của chúng tôi sẽ giúp bạn phát triển một giải pháp phù hợp để vượt lên đối thủ cạnh tranh của mình.
      Mọi thông tin tư vấn và báo giá đều miễn phí.

        「Chính sách bảo mật」Nếu bạn đồng ý với những điều trên, vui lòng nhấp vào nút "Gửi"
        Một email trả lời tự động sẽ được gửi đến địa chỉ email bạn đã nhập, vì vậy hãy kiểm tra điều đó.
        liên hệ