最近開發(fā)的Flutter APP iOS端需要用到一個(gè)從其他應(yīng)用分享上傳附件的功能筋量,這里記錄一下實(shí)現(xiàn)的過程
配置
要讓系統(tǒng)分享的列表里出現(xiàn)我們自己的APP盈厘,首先是需要小小的配置一下。打開項(xiàng)目/ios/Runner/Info.plist
文件
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>Text</string>
<key>LSHandlerRank</key>
<string>Alternate</string>
<key>LSItemContentTypes</key>
<array>
<string>public.text</string>
<string>public.plain-text</string>
<string>public.utf8-plain-text</string>
<string>public.utf16-external-plain-text</string>
<string>public.utf16-plain-text</string>
<string>com.apple.traditional-mac-plain-text</string>
</array>
</dict>
<dict>
<key>CFBundleTypeName</key>
<string>PDF</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>LSItemContentTypes</key>
<array>
<string>com.adobe.pdf</string>
</array>
</dict>
<dict>
<key>CFBundleTypeName</key>
<string>Microsoft Word</string>
<key>LSHandlerRank</key>
<string>Alternate</string>
<key>LSItemContentTypes</key>
<array>
<string>com.microsoft.word.docx</string>
<string>com.microsoft.word.doc</string>
<string>com.microsoft.word.wordml</string>
<string>org.openxmlformats.wordprocessingml.document</string>
</array>
</dict>
</array>
這樣的話就配置完成了剧蚣。順便解釋下每個(gè)字段的意思
CFBundleDocumentTypes
:指的是可以接收文件的類型鸭巴,比如圖片、文檔立轧、壓縮包等等
LSItemContentTypes
: 指的是具體可以接收的類型,比如txt
、jpg
氛改、doc
帐萎、pdf
等,這個(gè)key對應(yīng)的是一個(gè)Array胜卤,Array中是支持字段的類型疆导。支持的字段類型參考這里
應(yīng)用內(nèi)處理
分享過來的文件會存儲在沙盒文件夾Documents/Inbox
下,所以我們這邊需要在AppDelegate
中重寫openURL
方法瑰艘。
swift
我們在項(xiàng)目目錄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
的方法芒率,并且創(chuàng)建了一個(gè)FlutterMethodChannel
,并且創(chuàng)建了兩個(gè)方法getLastShareFilePath
篙顺、clearLastShareFilePath
偶芍。這兩個(gè)方法的作用是:獲取最后分享文件的路徑,清除最后分享文件的路徑德玫。
Flutter處理
在上面我們實(shí)現(xiàn)了FlutterMethodChannel
匪蟀。這樣還不夠,我們需要在flutter中來建一個(gè)通道來調(diào)用宰僧。
我們新建一個(gè)文件tools.dart
import 'package:flutter/services.dart';
class Tools {
static const MethodChannel _channel = MethodChannel('yzp.cn/tools');
Future<String> get lastShareFilePath async {
String path = await _channel.invokeMethod('getLastShareFilePath');
return path;
}
Future<bool> get clearLastShareFilePath async {
bool status = await _channel.invokeMethod('clearLastShareFilePath');
return status;
}
}
然后材彪,我們就能在項(xiàng)目中使用這個(gè)方法了
main.dart
中
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
// 當(dāng)APP打開時(shí)我們?nèi)カ@取分享文件的鏈接
getLastShareFilePath();
}
}
getLastShareFilePath () async {
String path = await Tools().getLastShareFilePath;
print(path);
// 這里記得將最后一次分享的文件鏈接清空
await Tools().clearLastShareFilePath;
}
}
這樣的話,我們就可以實(shí)現(xiàn)在ios系統(tǒng)分享中加上自己的應(yīng)用啦琴儿。并且可以在Flutter中操作這樣文件啦
結(jié)尾
如果在使用途中遇到什么問題或者BUG段化,請?jiān)谙路搅粞苑答?/p>