iOS UIActivityViewController 分享视频,图片


1.使用UIActivityViewController分享视频

 代码如下:

    NSMutableArray *itemsArray = [NSMutableArray array];
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"temp" ofType:@"MP4"];
    NSURL *url = [NSURL fileURLWithPath:filePath];
    [itemsArray addObject:url];
    UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:itemsArray applicationActivities:nil];
    [self presentViewController:activityVC animated:YES completion:nil];

有点需要注意   url,在这里不是http连接,如果是http连接的话,在分享的界面不会有Save Video 的activity的

运行的效果:(在模拟器上跑的,可能和真机上有一定的差别,不过只要出现Save Video这个activity就说明可以成功分享Video了)

iOS UIActivityViewController 分享视频,图片

分享多个Video也很简单,itemsArray中多加几个url就行了(代码就不写了)。

2.使用UIActivityViewController分享5张以上的图片

在做项目的时候,有一个需求:用系统的UIActivityViewController 将多张图片保存到系统的相册,由上文看来貌似应该很简单(将filePath改成图片的文件路径就行了,如果5张以上就是一个NSArray包含多个url了),可是系统的保存有一些bug:也就是最多只能保存5张,而且iOS 系统会对高清的图片进行一定比例的压缩(会造成保存到手机的图片与保存之前的图片DPI不一样),在stack Overflow上有人提过这样问题,这是链接:http://stackoverflow.com/questions/18868547/iphone-multiple-image-sharing-using-uiactivityviewcontroller

相信很多人保存图片到系统相册用的都是

void UIImageWriteToSavedPhotosAlbum ( UIImage *image, id completionTarget, SEL completionSelector, void *contextInfo );

和这个callBack 

- (void)  image: (UIImage *) image    didFinishSavingWithError: (NSError *) error  contextInfo: (void *) contextInfo;

好了,如何解决呢?,系统的activity不支持5张以上,那么只能自定义一个activity了,先看下系统的SDK

typedef NS_ENUM(NSInteger, UIActivityCategory) {
    UIActivityCategoryAction,
    UIActivityCategoryShare,
}


// override methods
//这个activity的类型:就是上面两种枚举类型,默认是UIActivityCategoryAction,具体有甚么区别,建议大家code试试
+ (UIActivityCategory)activityCategory
  

  //下面3个函数,尽量都override吧,后两个理解起来不难,关键是activityType,SDK有说:
//subclass may override to return custom activity type that is reported to completion handler,其实就是区分 activity,而且在completion handle可以获取到这个返回值。
- (NSString *)activityType;   
- (NSString *)activityTitle;     
- (UIImage *)activityImage;      


//这个函数我一般都是返回YES :如果你自定义一个activity,在分享图片的时候想让activity出现,而分享Video的时候,不想让这个activity出现,这返回值就可以控制是否显示
- (BOOL)canPerformWithActivityItems:(NSArray *)activityItems; 
 
 
 
 //这个才是重点:在这个函数里面,解决只能保存5张图片的图片:顺便说一句activityItems,就是上面的【itemsArray】
- (void)prepareWithActivityItems:(NSArray *)activityItems;    


//下面这几个我也不是太了解。。。。。。
- (UIViewController *)activityViewController;   
- (void)performActivity;                    
- (void)activityDidFinish:(BOOL)completed;

所以我们可以在- (void)prepareWithActivityItems:(NSArray *)activityItems 中遍历 activityItems 去保存图片,保存成功和失败不都是有一个回调么,如果失败了,那就重新保存一次(有点暴力)如果心情好的话,可以尝试一下信号量进行同步,不过目的一样,将所有的图片全部保存到系统相册中。


 3.保存后图片的DPI不一致的问题(什么是DPI呢?姑且理解成像素吧)

也学你会遇见一很蛋疼的问题:如果你保存的图片像素非常的高,将图片保存到系统相册后前后的DPI会有一定的差别,像素越高差别越大

那么试试这个方法

//这里的data就是要保存的图片
- (void)saveImage:(NSData   *)data 
{
    ALAssetsLibrary *assetLib = [[ALAssetsLibrary alloc] init];
    
    [assetLib writeImageDataToSavedPhotosAlbum:data metadata:nil completionBlock:^(NSURL *assetURL, NSError *error) {
        if (error == nil) {
            
            
        }else{
            //如果保存出错,就重复保存一下(暴力下无所谓)
            [self saveImage:data];
        }
    }];
}


最后附上一个源码:

//
//  CustomActivity.h
//  GC
//
//  Created by xuyang on 14-10-20.
//

#import <UIKit/UIKit.h>

@interface CustomActivity : UIActivity{
    dispatch_semaphore_t semphore;
}

+ (UIActivityCategory)activityCategory;
- (NSString *)activityType;       // default returns nil. subclass may override to return custom activity type that is reported to completion handler
- (NSString *)activityTitle;      // default returns nil. subclass must override and must return non-nil value
- (UIImage *)activityImage;       // default returns nil. subclass must override and must return non-nil value
@end

------------------------------
//
//  CustomActivity.m
//  GC
//
//  Created by xuyang on 14-10-20.


#import "CustomActivity.h"
#import "AppDelegate.h"
#import <AssetsLibrary/ALAssetsLibrary.h>

static NSString * const HIPMustachifyActivityType = @"CoustomDelete";
@interface CustomActivity ()
{
    dispatch_queue_t queue;
    
    int itemsCount;
    int haveBeenSave;
}
@end


@implementation CustomActivity


+ (UIActivityCategory)activityCategory {
    return UIActivityCategoryAction;
}
- (NSString *)activityType
{
    return HIPMustachifyActivityType;
}
- (NSString *)activityTitle
{
    return @"save to phone";
}

- (UIImage *)activityImage
{
    return [UIImage new];
    
}
- (BOOL)canPerformWithActivityItems:(NSArray *)activityItems
{
    return YES;
}

- (void)prepareWithActivityItems:(NSArray *)activityItems {
    
    semphore = dispatch_semaphore_create(0); // 创建信号量
    queue = dispatch_queue_create("SaveImageOrVideo", NULL);
    itemsCount = [activityItems count];
    dispatch_async(queue, ^(void) {
        for (id activityItem in activityItems) {
            NSData* data = [NSData dataWithContentsOfURL:activityItem];
            UIImage* image = [UIImage imageWithData:data];
    
            
            if (image) {
                
                //bug  for  image  DIP
                [self saveImage:data AndPath:[(NSURL *)activityItem path]];
                
                
            }
            else
            {
                [self saveVideoToPhotos:activityItem];
                
            }
            dispatch_semaphore_wait(semphore, DISPATCH_TIME_FOREVER); // 等待信号.
            
            
        }
    });
    
}
//bug  for  image  DPI
- (void)saveImage:(NSData   *)data  AndPath:(NSString *)filePath
{
    ALAssetsLibrary *assetLib = [[ALAssetsLibrary alloc] init];
    
    [assetLib writeImageDataToSavedPhotosAlbum:data metadata:nil completionBlock:^(NSURL *assetURL, NSError *error) {
        if (error == nil) {
            
            dispatch_semaphore_signal(semphore);
            
        }else{
            
            [self saveImage:data AndPath:filePath];
        }
    }];
}

- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error
  contextInfo:(void *)contextInfo
{
    if (error != NULL){
        NSLog(@"Error%@",error);
        dispatch_async(queue, ^(void) {
            
            // 图片保存失败,重新写入当前图片.
            UIImageWriteToSavedPhotosAlbum(image,self,@selector(image: didFinishSavingWithError:contextInfo:),contextInfo);
        });
        
    }else{
    
        
        dispatch_semaphore_signal(semphore); // 图片保存成功,发射信号量.
    }
    
}

#pragma mark 保存视频到手机相册中
-(void)saveVideoToPhotos:(id)activityItem{
    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
    [library writeVideoAtPathToSavedPhotosAlbum:activityItem completionBlock:^(NSURL *assetURL, NSError *error) {
        if (error) {
           // 视频写入失败重新写入当前视频.
            [self saveVideoToPhotos:activityItem];
        } else {
            dispatch_semaphore_signal(semphore); // 视频保存成功,发射信号量
        }
    }];
}

@end

刚做iOS半年,写的不完全对,就当个参考吧(希望不要误人子弟),还有代码要亲自运行一下,才知道我说的对不对


你可能感兴趣的:(ios,保存视频,保存多张图片)