uni-iOS - 基础开发法

我写这篇文章为的是理清思路,将这段时间的所见所得和跨过的坑梳理一遍。这里不能代表官方文档的覆盖量,强烈建议看一遍官方文档后再来看此篇文章,至少能把一些不明白的地方弄明白。希望这套步骤能增加新手接入的成功率,希望你从中学会,获益。以上是我的初衷。

刚好有一个需求对接,在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且包括第三方库的相关错误,则可能是云端或者手动创建的第三方库配置有问题

码字不易,多多支持。希望大家越来越好。

猜你喜欢

转载自juejin.im/post/7042975673622724621