欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

开发 flutter原生ios插件

程序员文章站 2022-05-29 20:05:44
...

安装 flutter

  1. 下载 flutter SDK,地址:

     https://flutter.dev/docs/get-started/install/macos
    
  2. 解压缩:

     unzip ~/Downloads/flutter_macos_v1.7.8+hotfix.4-stable.zip
    
  3. 添加路径到 path 变量:

     open -e .bash_profile
    

    在 .bash_profile 中编辑:

     export PATH=${PATH}:下载的文件夹路径/flutter/bin:$PATH		
    

    刷新 .bash_profile:

     source .bash_profile
    
  4. 检查:

     flutter doctor
    

    结果如下:

    [✓] Xcode - develop for iOS and macOS (Xcode 10.3)
    

[✗] iOS tools - develop for iOS devices
✗ libimobiledevice and ideviceinstaller are not installed. To install with
Brew, run:
brew update
brew install --HEAD usbmuxd
brew link usbmuxd
brew install --HEAD libimobiledevice
brew install ideviceinstaller
✗ ios-deploy not installed. To install:
brew install ios-deploy
[!] Android Studio (version 3.4)
✗ Flutter plugin not installed; this adds Flutter specific functionality.
✗ Dart plugin not installed; this adds Dart specific functionality.
[!] IntelliJ IDEA Ultimate Edition (version 2018.2.7)
✗ Flutter plugin not installed; this adds Flutter specific functionality.
✗ Dart plugin not installed; this adds Dart specific functionality.
[!] VS Code (version 1.32.3)
✗ Flutter extension not installed; install from
https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter
[✓] Connected device (1 available)

```

这些错误中,我们只需要关心 Android Studio 插件的问题。接下来安装 Androi Studio 插件。

安装 Android Studio 插件

开发 flutter原生ios插件

安装后需重启 Android Studio。

创建插件工程并引入第三方依赖

  1. 创建插件工程 zhgd_native_plugin。

  2. 默认插件工程使用项目名称 zhgd_native_plugin 作为通道名,我们需要修改通道名为你和 flutter 端约定的通道名,比如 origin_channel:

    1. 搜索 MethodChannel(,将通道名称从 zhgd_native_plugin 修改为你和 flutter 端约定的通道名称 origin_channel。
    2. 搜索 @“zhgd_native_plugin”,将 o-c 代码中的通道名称修改为 @“origin_channel”。
  3. 默认插件工程调用的方法名为 getPlatformVersion,我们需要修改方法名为你和 flutter 端约定的方法名,比如 hello:

    1. 搜索 getPlatformVersion,将 zhgd_native_plugin.dart 中的 final String version = await _channel.invokeMethod('getPlatformVersion'); 一句修改为:

      await _channel.invokeMethod(
      

    ‘hello’,
    {
    “code”: “1000001”,
    “codeType”: 1,
    “port”: 36357,
    “createTime”: “2019-08-22 19:02:43”,
    “ip”: “26o0e91123.wicp.vip”,
    “effect”: 1,
    “channel”: 0,
    “updateTime”: “2019-08-22 19:02:43”,
    “id”: 1,
    “username”: “admin”,
    “name”: “1号摄像头”,
    “describe”: “1号门位置”
    }
    );
    return “hello”;
    ```

    hello 方法需要一个 map 参数。

  4. 拷贝 include 目录和 lib 目录到 ios/Classes 目录下

  5. 将 .h/.m 文件拷贝到 ios/Classes 目录下

  6. 打开插件的 .podspec 文件,添加:

     # 引入 lib 中所有静态库
     s.vendored_libraries = 'Classes/lib/*.a'
     # 引入第三方 pod
     s.dependency 'MBProgressHUD'
     s.dependency 'Masonry'
     # 引入系统 framework
     s.frameworks   = 'UIKit','Foundation','CoreMedia','AudioToolbox','VideoToolbox'
     # 引入系统静态库
     s.libraries    = 'stdc++'
     # 引入图片资源
     s.resources = ['Assets/*.png']
     # iOS 兼容版本
     s.ios.deployment_target = '10.0'
     # 只支持真机,不支持模拟器,去掉 x86_64\i386
     valid_archs = ['arm64','arm64e','armv7','armv7s']
     s.xcconfig = {
     	'VALID_ARCHS' =>  valid_archs.join(' '),
     }
     # 使用 use_frameworks!,
     s.static_framework = true
    

    s.static_framework 这句很关键,如果 flutter 项目中使用了 Swift 库,则必须在 Podfile 中使用 use_frameworks!,那么插件工程也必须 use_frameworks!。二者保持一致,否则会出现各种问题。

  7. 将图片等静态资源拷贝到 ios/Assets 下。这样打包后,会在 Pods 工程的 Development Pods/<插件名称>/ 下多出一个 Resources 目录,图片资源会放到这个目录下。

  8. Open iOS module in Xcode 功能打包。如果出现错误,可以进入 example 目录,手动打包:

     flutter --no-color build ios --no-simulator
    

    因为这个插件只支持真机,不支持模拟器,所以需要使用 --no-simulator 选项。

  9. 打完包后,进入 example/ios 目录,用 Xcode 打开 Runner.xcworkspace 文件,然后 pod install。

  10. 修改 ZhgdNativePlugin.m 文件的 handleMethodCall 方法:

    #import "DHAPI.h"
    #import "LivePreviewViewController.h"
    
    ... ...
    
    -(void)onMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result{
    if ([[call method] isEqualToString:@"hello"]) {
        
        FlutterAppDelegate* delegate = (FlutterAppDelegate*)[[UIApplication sharedApplication]delegate];
        FlutterViewController* rootVC = (FlutterViewController*)delegate.window.rootViewController;
        
        LoginForm* form = [LoginForm new];
        form.IP = call.arguments[@"IP"];
        form.port = call.arguments[@"port"];
        form.userName = call.arguments[@"userName"];
        form.password = call.arguments[@"password"];
        form.name = call.arguments[@"name"];
        form.describe = call.arguments[@"describe"];
        
        [DHAPI IPLogin:form success:^(LoginResult * _Nonnull result) {
            NSLog(@"登录成功:loginID = %ld,channel = %d",result.loginId,result.channel);
            LivePreviewViewController* vc = [LivePreviewViewController new];
            vc.loginInfo = result;
            
            [rootVC presentViewController:vc animated:YES completion:nil];
            
        } failed:^(NSError * _Nonnull error) {
            NSLog(@"%@",error.localizedDescription);
        }];
        
        
    } else {
        result(FlutterMethodNotImplemented);
    }
    

}

```
  1. 修改开发者签名,选择真机设备,编译运行。

最好每完成一个步骤,都运行一下,并用 Xcode 打开再运行一下,以保证所有环节都正常。如果某些步骤出现运行不起来的情况,重新创建插件工程,然后从头再来。

常见问题

flutter 无法在真机上运行

  1. 安装 Xcode 命令行工具:xcode-select --install

  2. 重启终端。

  3. 安装 usbmuxd:

     brew install --HEAD usbmuxd
    
  4. 创建软连接:

     brew link usbmuxd
    
  5. 安装 imobiledevice:

     brew install --HEAD libimobiledevice
    
  6. 如果报错 syntax error near unexpected token `libusbmuxd,’,则需要执行:

     brew link --overwrite pkg-config 
    

    再重新安装。

  7. 如果报错 Package requirements (libusbmuxd >= 1.1.0) were not met,说明你安装的 usbmuxd 版本 < 1.1,则需要用以下方式安装:

    1. 卸载 usbmuxd :

       brew uninstall --ignore-dependencies usbmuxd
      
    2. 重新安装 usbmuxd :

       brew install --HEAD usbmuxd
      
    3. 重新创建 usbmuxd 的连接:

       brew unlink usbmuxd
       brew link usbmuxd
      
    4. 重新安装 libimobiledevice:

       brew install --HEAD libimobiledevice
      
  8. 安装 ideviceinstaller:

     brew install ideviceinstaller
    
  9. 安装 ios-deploy:

     brew install ios-deploy
    

Flutter 卡在 package get 的解决办法

storage.googleapis.com 被墙了,解决办法是编辑 .bash_profile 文件,添加两个环境变量:

export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn

Invalid VCS root mapping

点击 Configure…,找到 Version Control->Directory,将红色的 删除,然后 Apply。

执行命令行 flutter build 出错:Target file “lib/main.dart” not found.

这是一个插件工程,有两个 main.dart,你可能执行错了。插件工程本身是不能执行的,你应该执行实际上应该是插件工程下面的 example 工程。你应该进入 example 目录下执行命令,这样才会选择 example/lib 目录下的 main.dart 文件。

编译 Xcode 工程时报错 Expected identifier or ‘(’

  1. 在 o-c 文件中调用了 c++ 代码,将 o-c 文件修改为 o-c++ 文件(将文件后缀名从 .m 修改为 .mm)。
  2. 将.h文件File Type改为Objective C++ Preprocessed Source,默认C Header.