iOS小技能:文件预览、分享

2022-08-22 11:36:46 浏览数 (1)

前言

应用场景:文件下载、打印

I 第三方SDK分享文件

1.1 微信SDK

代码语言:javascript复制
/**

enum WXScene {
  
    WXSceneSession  = 0, 
    WXSceneTimeline = 1,
    WXSceneFavorite = 2,
};

文件真实数据内容
 * @note 大小不能超过10M
 */
@property (nonatomic, retain) NSData    *fileData;

*/
- (void)sendFileContent
{
    WXMediaMessage *message = [WXMediaMessage message];
    message.title = @"ML.pdf";
    message.description = @"Pro CoreData";
    [message setThumbImage:[UIImage imageNamed:@"res2.jpg"]];
    
    WXFileObject *ext = [WXFileObject object];
    ext.fileExtension = @"pdf";
    NSString* filePath = [[NSBundle mainBundle] pathForResource:@"ML" ofType:@"pdf"];
    ext.fileData = [NSData dataWithContentsOfFile:filePath];
    //  (nullable instancetype)dataWithContentsOfURL:(NSURL *)url;
    message.mediaObject = ext;
    
    SendMessageToWXReq* req = [[[SendMessageToWXReq alloc] init]autorelease];
    req.bText = NO;
    req.message = message;
    req.scene = WXSceneSession;
    
    [WXApi sendReq:req completion:nil];
}

1.2 友盟SDK

代码语言:javascript复制


#pragma mark - UMFileObject
/*! @brief 多媒体消息中包含的文件数据对象
 *
 * @see UMShareObject
 */
@interface UMShareFileObject : UMShareObject

/** 文件后缀名
 * @note 长度不超过64字节
 */
@property (nonatomic, retain) NSString  *fileExtension;

/** 文件真实数据内容
 * @note 大小不能超过10M
 */
@property (nonatomic, retain) NSData    *fileData;

/** 文件的名字(不包含后缀)
 * @note 长度不超过64字节
 */
@property (nonatomic, retain) NSString  *fileName;


@end

II 原生API的文件预览及其他应用打开

代码语言:javascript复制
- (BOOL)presentOptionsMenuFromRect:(CGRect)rect inView:(UIView *)view animated:(BOOL)animated;
- (BOOL)presentOptionsMenuFromBarButtonItem:(UIBarButtonItem *)item animated:(BOOL)animated;

// Bypasses the menu and opens the full screen preview window for the item at URL.  Returns NO if the item could not be previewed.
// Note that you must implement the delegate method documentInteractionControllerViewControllerForPreview: to preview the document.
- (BOOL)presentPreviewAnimated:(BOOL)animated;//预览文件

// Presents a menu allowing the user to open the document in another application.  The menu
// will contain all applications that can open the item at URL.
// Returns NO if there are no applications that can open the item at URL.
- (BOOL)presentOpenInMenuFromRect:(CGRect)rect inView:(UIView *)view animated:(BOOL)animated;//包括快速预览菜单、打印、复制
- (BOOL)presentOpenInMenuFromBarButtonItem:(UIBarButtonItem *)item animated:(BOOL)animated;//不包括包括快速预览菜单

  1. 获取NSURL
代码语言:javascript复制
//方式1:
    NSString* filePath = [[NSBundle mainBundle] pathForResource:@"ML" ofType:@"pdf"];
NSURL *url = [NSURL fileURLWithPath:filePath];
// 方式2
    //NSURL *url = [[NSBundle mainBundle] URLForResource:@"ML" withExtension:@"pdf"];


  1. 实例化UIDocumentInteractionController
代码语言:javascript复制
UIDocumentInteractionController *documentController = [UIDocumentInteractionController interactionControllerWithURL:url];
documentController.delegate = self;//UIDocumentInteractionControllerDelegate

2.1 预览文件

代码语言:javascript复制

[documentController presentPreviewAnimated:YES]; // 预览文件

在这里插入图片描述

2.2 文件分享

代码语言:javascript复制

        CGRect rect = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);


       [documentController presentOptionsMenuFromRect:rect inView:self.view  animated:YES];//包括快速预览菜单、打印、复制

//        [documentController presentOpenInMenuFromRect:rect inView:self.view animated:YES];//不包括包括快速预览菜单

在这里插入图片描述

2.3 控制是否显示copy、 print、saveToCameraRoll

代码语言:javascript复制
#pragma mark - UIDocumentInteractionControllerDelegate


- (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)interactionController{

    return self;

}


//
/**
 print: saveToCameraRoll:  copy:
 
 */
- (BOOL)documentInteractionController:(UIDocumentInteractionController *)controller canPerformAction:(SEL)action{
    NSLog(@"canPerformAction  %s %@ ", __func__,NSStringFromSelector(action));
    //NSStringFromSelector(_cmd)  //当前选择器的名字

    

    
//    return NO;不显示copy print
    return YES;//显示copy print

}


- (BOOL)documentInteractionController:(UIDocumentInteractionController *)controller performAction:(SEL)action{
    NSLog(@"canPerformAction  %s", __func__);

    return YES;//显示copy print

//    return NO;

}



III 案例

3.1 文件下载和预览

代码语言:javascript复制

- (void)openfile:(CRMfilePreviewCellM*)m{
    
    
    
    
    //        NSURL *relativeToURL = [NSURL URLWithString:m.url ];//必须先下载,否则无法查看文件内容

    [SVProgressHUD showWithStatus:@"加载中..."];

    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:m.url]];
        [SVProgressHUD dismiss];

    
    if(data== nil){
        
        [SVProgressHUD showInfoWithStatus:@"文件下载失败"];

        return ;
    }
    
    
    
    
    
    //            //用单例类 NSFileManager的对象,将文件写入本地
    NSFileManager *fileManage = [NSFileManager defaultManager];

    NSString *tmp = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
//    NSString *tmp = NSTemporaryDirectory();
    
    NSString *fileName = m.fileName;
    
    tmp =[tmp stringByAppendingPathComponent:fileName];
    
    
    BOOL isSuccess = [fileManage createFileAtPath:tmp contents:data attributes:nil];
    
    
    
    
    if(isSuccess){
        
                
            
            NSURL *url = [NSURL fileURLWithPath:tmp];

        
            
        
        UIDocumentInteractionController *documentController = [UIDocumentInteractionController interactionControllerWithURL:url];
        //UIDocumentInteractionController delegate must implement documentInteractionControllerViewControllerForPreview: to allow preview
        documentController.delegate = self;//UIDocumentInteractionControllerDelegate

        
        [documentController presentPreviewAnimated:YES]; // 预览文件

    }
    
    

    
    
}

#pragma mark - UIDocumentInteractionControllerDelegate


- (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)interactionController{

    return self;

}


//
/**
 print: saveToCameraRoll:  copy:
 
 */
- (BOOL)documentInteractionController:(UIDocumentInteractionController *)controller canPerformAction:(SEL)action{
    NSLog(@"canPerformAction  %s %@ ", __func__,NSStringFromSelector(action));
    //NSStringFromSelector(_cmd)  //当前选择器的名字

    

    
//    return NO;不显示copy print
    return YES;//显示copy print

}


- (BOOL)documentInteractionController:(UIDocumentInteractionController *)controller performAction:(SEL)action{
    NSLog(@"canPerformAction  %s", __func__);

    return YES;//显示copy print

//    return NO;

}



3.2 使用数据模型保存下载文件路径

懒加载

代码语言:javascript复制
    //        NSURL *relativeToURL = [NSURL URLWithString:m.url ];//必须先下载,否则无法查看文件内容
- (NSString *)filePathFromUrl{
    
    if(_filePathFromUrl !=nil){
        return _filePathFromUrl;
        
    }
    
    
    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:self.url]];
    
    if(data== nil){
        
        [SVProgressHUD showInfoWithStatus:@"文件下载失败"];

        return nil;
        
    }
    
    
    
    
    //            //用单例类 NSFileManager的对象,将文件写入本地
    NSFileManager *fileManage = [NSFileManager defaultManager];

    NSString *tmp = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
//    NSString *tmp = NSTemporaryDirectory();
    
    NSString *fileName = self.fileName;
    

    tmp =[tmp stringByAppendingPathComponent:fileName];
    
    
    BOOL isSuccess = [fileManage createFileAtPath:tmp contents:data attributes:nil];
    
    _filePathFromUrl = tmp;
    
    if(!isSuccess){
        
        _filePathFromUrl = nil;
        
        
    }
    return _filePathFromUrl;
}


预览文件

代码语言:javascript复制

- (void)openfile:(CRMfilePreviewCellM*)m{
    
    
    if(!m.filePathFromUrl){
        return;
    
    }
    
            NSURL *url = [NSURL fileURLWithPath:m.filePathFromUrl];
    
        UIDocumentInteractionController *documentController = [UIDocumentInteractionController interactionControllerWithURL:url];
        //UIDocumentInteractionController delegate must implement documentInteractionControllerViewControllerForPreview: to allow preview
        documentController.delegate = self;//UIDocumentInteractionControllerDelegate

        
        [documentController presentPreviewAnimated:YES]; // 预览文件

        
}

3.3 使用数据模型分享文件

在这里插入图片描述

代码语言:javascript复制

@property (nonatomic,copy) NSString *fileName;

@property (nonatomic,copy) NSString *url;
//
@property (nonatomic,copy) NSString *filePathFromUrl;

/**

/** 文件真实数据内容
 * @note微信文件分享 大小不能超过10M
 */
@property (nonatomic, retain) NSData    *fileData;

- (void)sendFileContent;



- (NSData *)fileData{
    if(_fileData==nil){

        NSString* filePath= [self filePathFromUrl];
        _fileData =[NSData dataWithContentsOfFile:filePath];
        
    }
    return _fileData;
    
}

- (void)sendFileContent
{
    WXMediaMessage *message = [WXMediaMessage message];
    message.title = self.fileName;
    
    message.description =self.fileName;
    
    [message setThumbImage:[UIImage imageNamed:self.iconName]];
    
        
    WXFileObject *ext = [WXFileObject object];
    
    ext.fileExtension =self.fileExtension;
    
    
    ext.fileData =self.fileData;
    
    //  (nullable instancetype)dataWithContentsOfURL:(NSURL *)url;
    message.mediaObject = ext;
    
    SendMessageToWXReq* req = [[SendMessageToWXReq alloc] init];
    
    
    
    req.bText = NO;
    req.message = message;
    req.scene = WXSceneSession;
    
    [WXApi sendReq:req completion:nil];
    
    

}


3.4 清理缓存

获取沙盒缓存路径

代码语言:javascript复制
  (nullable NSString *)userCacheDirectory {
    NSArray<NSString *> *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    return paths.firstObject;
}

清理沙河文件缓存

代码语言:javascript复制
- (void)removeAllData {
    [self.fileManager removeItemAtPath:self.diskCachePath error:nil];
    [self.fileManager createDirectoryAtPath:self.diskCachePath
            withIntermediateDirectories:YES
                             attributes:nil
                                  error:NULL];
}

清理WKWebView的缓存

代码语言:javascript复制
  (void)clearWebCacheCompletion:(dispatch_block_t)completion {
    if (@available(iOS 9.0, *)) {
        NSSet *websiteDataTypes = [WKWebsiteDataStore allWebsiteDataTypes];
        NSDate *dateFrom = [NSDate dateWithTimeIntervalSince1970:0];
        [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:websiteDataTypes modifiedSince:dateFrom completionHandler:completion];
    } else {
        NSString *libraryDir = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)[0];
        NSString *bundleId  =  [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
        NSString *webkitFolderInLib = [NSString stringWithFormat:@"%@/WebKit",libraryDir];
        NSString *webKitFolderInCaches = [NSString stringWithFormat:@"%@/Caches/%@/WebKit",libraryDir,bundleId];
        NSString *webKitFolderInCachesfs = [NSString stringWithFormat:@"%@/Caches/%@/fsCachedData",libraryDir,bundleId];
        
        NSError *error;
        /* iOS8.0 WebView Cache path */
        [[NSFileManager defaultManager] removeItemAtPath:webKitFolderInCaches error:&error];
        [[NSFileManager defaultManager] removeItemAtPath:webkitFolderInLib error:nil];
        
        /* iOS7.0 WebView Cache path */
        [[NSFileManager defaultManager] removeItemAtPath:webKitFolderInCachesfs error:&error];
        if (completion) {
            completion();
        }
    }
    
}


清理图片缓存

代码语言:javascript复制
 (void)clearCache:(NSString *)path{
    NSFileManager *fileManager=[NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:path]) {
        NSArray *childerFiles=[fileManager subpathsAtPath:path];
        for (NSString *fileName in childerFiles) {
            //如有需要,加入条件,过滤掉不想删除的文件
            NSString *absolutePath=[path stringByAppendingPathComponent:fileName];
            [fileManager removeItemAtPath:absolutePath error:nil];
        }
    }
    //    [[SDImageCache sharedImageCache] cleanDisk];

    [[SDImageCache sharedImageCache] clearDiskOnCompletion:^{
        
    }];
}


0 人点赞