uni-iOS - 基礎開發法

語言: CN / TW / HK

我寫這篇文章為的是理清思路,將這段時間的所見所得和跨過的坑梳理一遍。這裡不能代表官方文件的覆蓋量,強烈建議看一遍官方文件後再來看此篇文章,至少能把一些不明白的地方弄明白。希望這套步驟能增加新手接入的成功率,希望你從中學會,獲益。以上是我的初衷。

剛好有一個需求對接,在uni中加入原生的功能,uni開發跟我要SDK檔案,由於之前我也寫過一個SDK,於是就把SDK丟給uni開發讓他去配置,結果怎麼也跑不通,我心想uni不是號稱可以替代原生開發嗎?怎麼連framework都用不了,後來才知道是我大意了。在仔細閱讀文件之後,開始了我的 - 比生孩子還難的爬坑之路。

準備階段

  • Xcode
  • HBuilderX
  • uni-SDK包

一、開發外掛

外掛開發包含了製作.framework或.a工程、匯入製作、封裝uni函式這三個方面。

1、製作原生framework或Library

在uni開發中,iOS原生外掛代表framework或.a檔案。所以首先建立一個這樣子的工程,可以參考framework專案指引(Swift)

我們不急著將工程生成為framework檔案,因為這樣直接生成偏原生向的.framework檔案在uni中是不可用的,參考上述指引(1~6步),並將它匯入HBuilder-uniPluginDemo工程中

2、匯入外掛

1.將剛剛建立的工程檔案拖到HBuilder-uniPluginDemo子目錄下,並開啟同級目錄下HBuilder-uniPlugin.xcodeproj工程

Xnip2021-12-16_14-18-01.jpg

2.選中主工程,右鍵選擇Add Files to "Project...",選中外掛目錄中的xcodeproj檔案,分為以下兩步

Xnip2021-12-15_18-36-18.jpg Xnip2021-12-15_18-40-45.jpg

3.匯入framework

選擇主工程 - Targets - Build Phases

Xnip2021-12-17_15-31-48.jpg

4.匯入標頭檔案路徑

選擇外掛工程 - targets - Build Settings

我們需要的DCUni標頭檔案及Weex標頭檔案都存在ins下,所以必須指定這個路徑匯入

Xnip2021-12-17_15-39-59.jpg

5.根據需要新建繼承自DCUniModule、DCUniComponent的OC檔案

Xnip2021-12-16_10-33-46.jpg

以上已經做完了所有匯入步驟,但如果想要完全執行,還需要:

檢查外掛關聯項

配置規範的介面程式碼

3、程式碼規範

原生外掛是基於 DCUniPlugin 規範來實現擴充套件原生的功能,其特點包括:

  • module:不需要參與頁面佈局,只需要讓uni具備呼叫原生能力。
  • component:需要直接參與uni頁面佈局。
  • 在外掛中可以同時有多個檔案,來增加它的不同的能力和功能劃分。

(1)uni-app

```

獲取 module

const swiftSdk = uni.requireNativePlugin("SwiftObject-SwiftModule");

呼叫非同步方法

let bl = swiftSdk.swiftLogFunc({ log: "ok" },(function(e) { //上號結果回撥 console.log(e) })) ​

呼叫同步方法

var ret = swiftSdk.swiftLogWithBoolFunc({ 'ok': 'uni-app' }) ```

(2)原生module

以module為例,分為同步和非同步方法:

非同步方法(不帶返回值,有回撥)

// 通過巨集 UNI_EXPORT_METHOD 將非同步方法暴露給 js 端 UNI_EXPORT_METHOD(@selector(swiftLogFunc:callback:)) -(void)swiftLogFunc:(NSDictionary *)options callback:(UniModuleKeepAliveCallback)callback {   NSString *log = options[@"log"];   callback(@{@"success": log},NO); }

同步方法(帶返回值)

UNI_EXPORT_METHOD(@selector(swiftLogWithBoolFunc:)) -(BOOL)swiftLogWithBoolFunc:(NSDictionary *)options {   NSString *log = options[@"log"];   return YES; }

Module預設在主執行緒,用uniExecuteThread(DCUniModule)可控制執行緒

入參只能傳鍵值對,在開發時與uni端定義好,需要注意key字串檢查和value型別檢查

UniModuleKeepAliveCallback 第一引數回撥引數 第二引數bool 為no方法完成後會自動釋放

二、執行方式

理解

執行方式分為兩種,即HBuilderX執行和Xcode執行。

在HbuilderX,所依賴的是基座,通過安裝基座,選擇在真機或者模擬器上執行

在Xcode,通過HBuilderX生成本地打包資原始檔,執行在Xcode編譯的真機模擬器上


究竟這兩種方式有什麼不同呢?下面主要細說這兩個部分的區別。

首先是打包方式

選擇HBuilderX執行,就需要我們生成一個.framework或.a的外掛包(也就是做一個uni可配的原生SDK包),並將包放置在uni專案的指定檔案,通過製作自定義基座,選擇自定義基座執行

選擇Xcode執行,我們不需要製作外掛包,而是需要用HBuilderX生成一個本地包,放在原生專案的指定檔案,配置uni資訊,然後執行即可

其次是關聯項配置方式

選擇HBuilderX執行,就需要配置package.json,以確保原生資源能在打包編譯時被找到

選擇Xcode執行,我們可以不用配置package.json,但是要配置HBuilder-uniPlugin-Info.info,以確保在Xcode上編譯的uni基座可以找到原生外掛


檢查配置外掛關聯項

要想將自定義基座中包含的外掛執行起來,需要配置正確完善的資訊內容。比較好記的是:

package.json關聯項對應的是HBuilderX除錯

HBuilder-uniPlugin-Info.info關聯項對應的是xcode除錯

操作步驟

1.執行除錯

HBuilderX
1.1 配置package.json關聯項參考

{   "name": "Swift Log",   "id": "SwiftObject",   "version": "1.0.0",   "description": "uni示例外掛",   "_dp_type": "nativeplugin",   "_dp_nativeplugin": {       "ios": {           "plugins": [{               "type": "module",               "name": "SwiftObject-SwiftModule",               "class": "SwiftModule"           }],           "embedSwift": true,//是否開啟swift支援           "integrateType": "framework",           "deploymentTarget": "9.0"       }   } }

1.2 整合外掛包目錄格式

在nativeplugins檔案下建立一個和外掛名稱一樣的資料夾,該資料夾下最多隻能包含三個內容:ios、android、package.json

(1)ios資料夾:用於存放.framework或.a外掛,也可以用來存放BundleResources資料夾(管理bundle資源)

(2)android資料夾:用於存放.aar外掛

(3)package.json:用於配置關聯項

Xnip2021-12-16_15-14-08.jpg

1.3 選擇原生外掛

Xnip2021-12-16_11-01-10.jpg

1.4 開始製作自定義基座

Xnip2021-12-16_11-03-28.jpg Xnip2021-12-16_11-05-52.jpg

BundleID:AppID,對應profile檔案

profile檔案:.mobileprovision描述檔案

證書檔案:通過鑰匙串匯出生成的.p12檔案

證書祕鑰:設定p12檔案時的祕鑰

1.5 製作自定義基座(成功)

Xnip2021-12-16_11-15-52.jpg

1.6 選擇基座執行

Xnip2021-12-16_11-06-34.jpg

1.7 執行到真機或模擬器

Xnip2021-12-16_11-21-53.jpg

1.8 真機安裝(成功)

Xnip2021-12-16_11-23-31.jpg

Xcode
1.1 配置Xcode HBuilder-uniPlugin-Info.info關聯項參考

<dict> <key>plugins</key> <array> <dict> <key>class</key> <string>SwiftModule</string> <key>name</key> <string>SwiftObject-SwiftModule</string> <key>type</key> <string>module</string> </dict> </array> </dict>

1.2 開啟工程HBuilder-uniPlugin.xcodeproj
1.3 替換HBuilder-uniPlugin-Info.info裡面的dcloud_appkey欄位,申請appkey
1.4 替換本地uni資源

(1)使用HBuilderX生成本地包

Xnip2021-12-16_11-37-53.jpg

(2)匯出本地包

Xnip2021-12-16_16-20-07.jpg

(3)替換資源,確保三者一致

f16ec2cf192ebd5a8fa653b444771841.png

1.5 切換Targets 為 HBuilder Schemes

Xnip2021-12-16_16-11-03.jpg

1.6 執行

Xnip2021-12-17_17-18-39.jpg

除錯的差異

你可以從兩種方式任意選擇一種除錯uni-iOS專案,需要注意的是。

使用HBuilderX 加入自定義基座執行,每次修改外掛都需要重新打包基座

使用Xcode,可以任意修改外掛內容,當修改uni內容只需要生成本地包檔案就行了(唯一的就是當我們切換外掛中的函式,需要將原有的app刪掉才能生效)

2.打包ipa檔案

Xcode打包:Xcode - Product - Archive(適用於釋出打包)

HBuilderX自定義基座打包,會在unpackage/debug中生成ipa檔案(僅用於除錯)

三、可能會遇到的問題

雲端拉取外掛無法匯入HBuilderX

如果遇到雲端外掛無法匯入,需要解壓後手動匯入

1.找到HBuilderX.app,右鍵"顯示包內容"

2.將解壓後的檔案匯入HBuilderX-plugins目錄下

A27D38E63D4B439A0E7FF1986EC03BFA.jpg

3.在此路徑下執行

../npm/npm install --save

4.重啟HBuilderX

需要使用iOS相關第三方庫

在製作原生外掛的過程中,我們可能會用到許許多多的第三方庫,並且uni官方文件也告訴我們可以用,怎麼樣使用文件卻並沒有明確交代,遇到這種情況,可以使用手動製作

(1)需要在github下載需要用到的第三方庫,並制定對應版本

(2)開啟第三方庫專案,選擇Build Phases並匯入run script(# framework專案指引(Swift)第5步)

(3)選擇Build Settings,搜尋ios 調整target版本

Xnip2021-12-17_17-56-23.jpg

(4)分別在模擬器和真機環境Build Code

(5)將做好的.framework檔案,放入uni-Demo SDK/Libs路徑下

Xnip2021-12-17_18-11-16.jpg

(6)選擇需要用到第三方庫的外掛工程,Build Settings - Framework Search Paths,拖入檔案路徑

Xnip2021-12-17_18-12-49.jpg

(7)匯入主專案

Xnip2021-12-17_18-15-03.jpg

(8)import匯入和編譯

自定義基座打包失敗

**<Weex>[warn]WXBridgeContext.m:1310, jsLog: [JS Framework] 當前執行的基座不包含原生外掛[SwiftObject-SwiftModule],請在manifest中配置該外掛,重新制作包括該原生外掛的自定義執行基座 __WARN**

  • 排查關聯項是否正確配對
  • 如果關聯項正確,檢視log日誌中輸出的內容,如果含有# Symbol(s) not found for arm64且包括第三方庫的相關錯誤,則可能是雲端或者手動建立的第三方庫配置有問題

碼字不易,多多支援。希望大家越來越好。