如何在 iOS 中使用 UIActivityViewController 创建和保存特定相册

Posted

技术标签:

【中文标题】如何在 iOS 中使用 UIActivityViewController 创建和保存特定相册【英文标题】:How to create and save specific photo album using UIActivityViewController in iOS 【发布时间】:2013-12-31 01:48:33 【问题描述】:

我想在 ios 7 中创建自定义相册并将照片保存到特定相册。我使用 ALAssetsLibrary 找到了iOS save photo in an app specific album。

但我不知道如何使用 UIActivityViewController。

NSArray* actItems = [NSArray arrayWithObjects: image, nil];

    UIActivityViewController *activityView = [[UIActivityViewController alloc]
                                              initWithActivityItems:actItems
                                              applicationActivities:nil];


    [activityView setCompletionHandler:^(NSString *activityType, BOOL completed)
    

        if ([activityType isEqualToString:UIActivityTypeSaveToCameraRoll])
        
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"#Saved_title", nil)
                                                            message:NSLocalizedString(@"#Saved_message2", nil)
                                                           delegate:self
                                                  cancelButtonTitle:NSLocalizedString(@"OK", nil)
                                                  otherButtonTitles: nil];
            [alert show];
        



    ];

【问题讨论】:

【参考方案1】:

我意识到这个问题已经存在几个月了,并且 OP 可能已经继续,但我需要这样做,但没有找到其他解决方案,需要自己想出一个解决方案。

这不是万无一失的,就好像相机胶卷中有多个您想要复制的视频/图像副本一样,它会复制所有这些副本,这可能需要也可能不需要。另外,出于我的目的,我正在考虑维护我已写入自定义相册的资产 URL 的持久列表,以便将来跳过该资产,但我尚未对其进行编码,因为如果用户删除自定义相册中的视频/图像,如果不通过资产组进行更多迭代,几乎不可能更新该列表:我想避免这种情况。

最后的免责声明:我还没有完全测试过这个,但它适用于我的目的,所以希望其他人可以从中受益。

我扩充了 Marin Todorov 的 ALAssetsLibrary+CustomPhotoAlbum 类别,我在这里找到了:https://github.com/yusenhan/Smooth-Line-View/tree/master/ALAssetsLibrary%2BCustomPhotoAlbum。注意:那里没有提供许可信息,所以我假设修改该类别的源是可以的。

这是我设置和显示 UIActivityViewController 的方法:

- (void)showActivitySheet:(NSString *)path 
    NSURL *newURL = [NSURL fileURLWithPath:path];
    NSArray *itemsToShare = @[newURL];
    UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:itemsToShare applicationActivities:nil];
    activityVC.excludedActivityTypes = @[UIActivityTypePrint, UIActivityTypeAssignToContact, UIActivityTypeAddToReadingList];

    // Once the OS has finished with whatever the user wants to do with it,
    // we'll begin figuring out if we need to save it to the Album, too!
    [activityVC setCompletionHandler:^(NSString *activityType, BOOL completed) 
    
        // If the user selected "Save to Camera Roll"
        if ([activityType isEqualToString:UIActivityTypeSaveToCameraRoll]) 
            
            ALAssetsLibrary *lib = [[ALAssetsLibrary alloc] init];
            NSURL *tempUrl = [NSURL fileURLWithPath:path];
                    
            // saveMovie: below is a method I added to the category, but you can use saveImage:,
            // which you'll also likely want to add some kind of parameter to so, in the category,
            // you know when you only want to copy to the Album instead of the Album AND Camera Roll
            [lib saveMovie:tempUrl toAlbum:@"CUSTOM ALBUM NAME"
                       withCompletionBlock:^(NSURL *url, NSError *error) 
                           if (error) 
                               NSLog(@"Error writing movie to custom album: %@", error.debugDescription);
                           
                        
   onlyWriteToCustomAlbum:YES];
        
    ];

    [self presentViewController:activityVC animated:YES completion:nil];

您可以将以下代码添加到 ALAssetsLibrary+CustomPhotoAlbum 类别中的 saveImage: 方法中,这样您也可以将其保存到您的自定义相册中!您只能在要添加到类别中的 BOOL 的 YES 情况下执行此部分。

NSData *dataToCompareTo = [NSData dataWithContentsOfURL:url]; // This data represents the image/movie which you want to save into the custom album. The one you handed to the UIActivityViewController.
    
    // Note use of self, as this is a category on ALAssetsLibrary; also, this
    // assumes that you've already written the photo to the Camera Roll, which
    // should be automatically handled by the OS, if the user hit the "Save" button
    // on the UIActivityViewController.

    // Enumerate through Camera Roll/Saved Photos group.
    [self enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos
                       usingBlock:^(ALAssetsGroup *group, BOOL *stop) 
                           
                           // Enumerate the assets in each group. 
                           [group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) 
                               
                               ALAssetRepresentation *rep = [result defaultRepresentation];
                               
                               // If the asset isn't the same size as the source image/movie
                               // it shouldn't be the same. Check the size first, since it
                               // is a less costly operation than byte checking the data itself.
                               if ([rep size] == [dataToCompareTo length]) 
                                   Byte *buffer = malloc([NSNumber numberWithLongLong:rep.size].unsignedLongValue);
                                   NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:[NSNumber numberWithLongLong:rep.size].unsignedLongValue error:nil];
                                   NSData *data = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];
                                   
                                   // If the buffer has more than the null-termination char, free it!  I'm doing this in case the above call to dataWithBytesNoCopy fails to free() the buffer.
                                   if (sizeof(buffer) > 4) 
                                       free(buffer);
                                   
                                   
                                   // Ensure they are the same by comparing the NSData instances.
                                   if ([data isEqualToData:dataToCompareTo]) 
                                       NSLog(@"they are the same!!");
                                       [self addAssetURL:[rep url]
                                                 toAlbum:albumName
                                withMovieCompletionBlock:completionBlock];
                                    else 
                                       NSLog(@"they are different");
                                   
                               
                           ];
                        failureBlock:^(NSError *error) 
                           NSLog(@"Failed to write to custom album!");
                       ];

希望对您有所帮助! TLDR?也这么觉得! ;-)

【讨论】:

以上是关于如何在 iOS 中使用 UIActivityViewController 创建和保存特定相册的主要内容,如果未能解决你的问题,请参考以下文章

如何在 iOS 8 中使用带有 NSNotificationCenter 的小部件

如何在ios5中使用identifierForVendor。?

如何在 iOS 8 中使用 UIAlertView? [复制]

我应该如何在 iOS 7 中使用具有 iOS 6 风格的 UIButtons?

如何在 iOS 中使用边缘插图?

如何在 iOS 中使用 Crashlytics 而不使用 Fabric