uni-app中UIDocumentPickerDelegate回调问题

发布于 1周前 作者 itying888 来自 Uni-App

uni-app中UIDocumentPickerDelegate回调问题

问题描述

在使用 UIDocumentPickerDelegate 代理时,点击“取消”时可以触发 documentPickerWasCancelled,但是选中文件时无法触发 documentPicker。请问是什么问题?

代码示例

@objc(UTSSDKModulesIkeFileUtilMyUIDocumentPickerDelegate)  
@objcMembers  
public class MyUIDocumentPickerDelegate : NSObject, UIDocumentPickerDelegate, IUTSSourceMap {  
    public func __$getOriginalPosition() -> UTSSourceMapPosition? {  
        return UTSSourceMapPosition("MyUIDocumentPickerDelegate", "uni_modules/ike-file-util/utssdk/app-ios/index.uts", 63, 7);  
    }  
    public var resultCallback: ((_ res: [String]) -> Void)?;  
    public func documentPicker(_ controller: UIDocumentPickerViewController, _ urls: [URL]) -> Void {  
        console.log("确定选择文件", " at uni_modules/ike-file-util/utssdk/app-ios/index.uts:97");  
        controller.dismiss(animated: true, completion: nil);  
    }  
    public func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) -> Void {  
        console.log("取消选择文件", " at uni_modules/ike-file-util/utssdk/app-ios/index.uts:113");  
        controller.dismiss(animated: true, completion: nil);  
    }  
}  

@objc(UTSSDKModulesIkeFileUtilNativeCode)  
@objcMembers  
public class NativeCode : UIViewController, UIDocumentPickerDelegate {  
    private static var myDelegate = MyUIDocumentPickerDelegate();  
    public func showPicker(_ options: ChooseFileOptions) {  
        NativeCode.myDelegate.resultCallback = options.success;  
        var uiDocumentPickerViewController: UIDocumentPickerViewController = UIDocumentPickerViewController(documentTypes: options.mime_types, in: UIDocumentPickerMode.import);  
        uiDocumentPickerViewController.delegate = NativeCode.myDelegate;  
        if #available(iOS 13.0, *) {  
            uiDocumentPickerViewController.shouldShowFileExtensions = true;  
        }  
        UTSiOS.getCurrentViewController().present(uiDocumentPickerViewController, animated: true, completion: nil);  
    }  
}  

public var chooseFile: ChooseFile = {  
(_ options: ChooseFileOptions) -> Void in  
DispatchQueue.main.async(execute: {  
() -> Void in  
var nativeCode = NativeCode();  
nativeCode.showPicker(options);  
});  
};

开发环境、版本号及项目创建方式

信息
开发环境 iOS
版本号 iOS 13.0+
项目创建方式 未提供

1 回复

在uni-app中,直接处理UIDocumentPickerDelegate回调是不可能的,因为uni-app是一个使用Vue.js开发所有前端代码,并通过DCloud的uni-app框架编译为原生应用的跨平台框架。原生iOS的UIDocumentPickerDelegate通常用于处理文件选择器的事件,这在uni-app的框架内无法直接实现,但你可以通过原生插件或者自定义组件的方式来实现这一功能。

以下是一个通过原生插件的方式,在uni-app中调用UIDocumentPicker并处理回调的示例:

1. 创建iOS原生插件

首先,你需要创建一个iOS原生插件,这个插件会包含UIDocumentPicker的调用和UIDocumentPickerDelegate的实现。

iOSPlugin.h

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface IOSPlugin : NSObject <UIDocumentPickerDelegate>

+ (instancetype)sharedInstance;
- (void)presentDocumentPicker;

@end

IOSPlugin.m

#import "IOSPlugin.h"

@implementation IOSPlugin

+ (instancetype)sharedInstance {
    static IOSPlugin *instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
    });
    return instance;
}

- (void)presentDocumentPicker {
    UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[@"public.item"] inMode:UIDocumentPickerModeImport];
    documentPicker.delegate = self;
    documentPicker.modalPresentationStyle = UIModalPresentationFormSheet;
    [UIApplication.sharedApplication.keyWindow.rootViewController presentViewController:documentPicker animated:YES completion:nil];
}

#pragma mark - UIDocumentPickerDelegate
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls {
    // 处理选择的文件URL
    NSLog(@"Selected URLs: %@", urls);
    // 可以通过JSBridge回调给uni-app
}

@end

2. 在uni-app中调用插件

在uni-app项目中,你需要通过plus.runtime.execute或者plus.ios.invoke(如果DCloud提供了这样的API)来调用这个原生插件的方法。但通常情况下,你需要通过自定义的JSBridge来通信。

3. JSBridge实现

你需要实现一个JSBridge来在uni-app的JavaScript代码和iOS原生代码之间通信。这通常涉及到在iOS原生代码中监听特定的消息,并在JavaScript中发送这些消息。

由于篇幅限制,这里不能详细展示JSBridge的实现,但基本思路是在iOS原生插件中设置一个监听器,然后在JavaScript中通过某种方式(如WebSocket、URL Scheme等)发送消息给原生插件,原生插件接收到消息后执行相应的操作,并通过回调或其他方式将结果返回给JavaScript。

通过上述步骤,你可以在uni-app中实现UIDocumentPicker的调用和回调处理。

回到顶部