flutter iOS端实现在系统分享列表中加入自己的应用

最近开发的Flutter APP iOS端需要用到一个从其他应用分享上传附件的功能,这里记录一下实现的过程

配置

要让系统分享的列表里出现我们自己的APP,首先是需要小小的配置一下。打开项目/ios/Runner/Info.plist文件

CFBundleDocumentTypes

    
             CFBundleTypeName
             Text
             LSHandlerRank
             Alternate
             LSItemContentTypes
             
                 public.text
                 public.plain-text
                 public.utf8-plain-text
                 public.utf16-external-plain-text
                 public.utf16-plain-text
                 com.apple.traditional-mac-plain-text
             
         
         
             CFBundleTypeName
             PDF
             LSHandlerRank
             Owner
             LSItemContentTypes
             
                 com.adobe.pdf
             
         
         
             CFBundleTypeName
             Microsoft Word
             LSHandlerRank
             Alternate
             LSItemContentTypes
             
                 com.microsoft.word.docx
                 com.microsoft.word.doc
                 com.microsoft.word.wordml
                 org.openxmlformats.wordprocessingml.document
            
        

这样的话就配置完成了。顺便解释下每个字段的意思

CFBundleDocumentTypes:指的是可以接收文件的类型,比如图片、文档、压缩包等等

LSItemContentTypes: 指的是具体可以接收的类型,比如txtjpgdocpdf等,这个key对应的是一个Array,Array中是支持字段的类型。支持的字段类型参考这里

应用内处理

分享过来的文件会存储在沙盒文件夹Documents/Inbox下,所以我们这边需要在AppDelegate中重写openURL方法。

swift

我们在项目目录ios/下,双击Runner.xcworkspace文件,就会在xcode中打开工程目录,我们编辑AppDelegate.swift文件。
如下

import UIKit
import Flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
   // new add
   // 文件沙盒路径 
    var lastFilePath = String.init("");
  
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)
  
    // new add
    let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
    let yizhipinToolsChannel = FlutterMethodChannel.init(name: "zrong.life/tools", binaryMessenger: controller as! FlutterBinaryMessenger)
  
    yizhipinToolsChannel.setMethodCallHandler({
        (call: FlutterMethodCall, result: FlutterResult) -> Void in
        if (call.method == "getLastShareFilePath") {
            self.getLastShareFilePath(result: result)
        } else if (call.method == "clearLastShareFilePath") {
            self.clearLastShareFilePath(result: result)
        }
    })
  
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
  
    // new add
    override func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        if url.scheme == "file" {
            let path = url.absoluteString
            lastFilePath = path
            return true
        }
        return super.application(app, open: url, options: options)
    }
  
    // new add
    private func getLastShareFilePath(result: FlutterResult) {
        result(lastFilePath)
    }
  
   // new add
    private func clearLastShareFilePath(result: FlutterResult) {
        lastFilePath = ""
        result(true)
    }
}

在上面,我们重写了openURL的方法,并且创建了一个FlutterMethodChannel,并且创建了两个方法getLastShareFilePathclearLastShareFilePath。这两个方法的作用是:获取最后分享文件的路径,清除最后分享文件的路径。

Flutter处理

在上面我们实现了FlutterMethodChannel。这样还不够,我们需要在flutter中来建一个通道来调用。

我们新建一个文件tools.dart

import 'package:flutter/services.dart';

class Tools {
  static const MethodChannel _channel = MethodChannel('yzp.cn/tools');

  Future get lastShareFilePath async {
    String path = await _channel.invokeMethod('getLastShareFilePath');
    return path;
  }

  Future get clearLastShareFilePath async {
    bool status = await _channel.invokeMethod('clearLastShareFilePath');
    return status;
  }
}

然后,我们就能在项目中使用这个方法了
main.dart

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();

    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.resumed) {
      // 当APP打开时我们去获取分享文件的链接
      getLastShareFilePath();
    }
  }
  
  getLastShareFilePath () async {
    String path = await Tools().getLastShareFilePath;
    print(path);
  
    // 这里记得将最后一次分享的文件链接清空
    await Tools().clearLastShareFilePath;
  }
}

这样的话,我们就可以实现在ios系统分享中加上自己的应用啦。并且可以在Flutter中操作这样文件啦

结尾

如果在使用途中遇到什么问题或者BUG,请在下方留言反馈

原文地址

你可能感兴趣的:(flutter iOS端实现在系统分享列表中加入自己的应用)