Всегда сохранять скриншот в альбоме приложения с тем же именем в Фото

Я создаю приложение с кнопкой, которая делает снимок экрана. Теперь я хочу сохранить все снимки экрана, сделанные в этом приложении, в альбоме приложения с тем же именем. Я уже знаю, как создать альбом только в первый раз, когда приложение открывается с кодом ниже. Я создаю свой альбом с фреймворком Photos, например:

-(void)createAppAlbum
{

[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
    PHAssetCollectionChangeRequest *changeRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:@"App Album Name"];
    albumPlaceholder = changeRequest.placeholderForCreatedAssetCollection;

}

 completionHandler:^(BOOL success, NSError *error) {
                         if (success) {
                         fetchResult = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[albumPlaceholder.localIdentifier] options:nil];
                                          assetCollection = fetchResult.firstObject;

} 
                        else {
                              NSLog(@"Error creating album: %@", error);}
                                  }];

}

Итак, мое приложение создает альбом с именем «Имя альбома приложения». Я могу сделать снимок экрана и сохранить его в своем новом альбоме с помощью такой кнопки:

 -(IBAction)screenshot:(id)sender
{

if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
    UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, [UIScreen mainScreen].scale);
else
    UIGraphicsBeginImageContext(self.view.bounds.size);

[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();


[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
    PHAssetChangeRequest *assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];

    PHAssetCollectionChangeRequest *assetCollectionChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection];
    [assetCollectionChangeRequest addAssets:@[[assetChangeRequest placeholderForCreatedAsset]]];
} completionHandler:^(BOOL success, NSError *error) {
    if (!success) {
        NSLog(@"Error creating asset: %@", error);
    }
}];

}

В случае, если я покину этот viewController и вернусь позже, я хочу найти альбом, который я уже создал, и сохранить еще один снимок экрана в том же альбоме, потому что я не хочу создавать новый каждый раз, когда я вхожу в этот контроллер представления.

Итак, мой вопрос: как мне получить альбом, который я создал в первый раз, по имени, а затем сохранить новые снимки экрана.


person MOzeb    schedule 13.10.2015    source источник
comment
Возможный дубликат сохранения фотографии iOS в конкретном альбоме приложения   -  person Fennelouski    schedule 13.10.2015
comment
@Fennelouski - iOS 5, а также без использования Photo framework..   -  person MOzeb    schedule 13.10.2015
comment
Можешь объяснить, в чем сложность? При создании альбома вы получаете его идентификатор. С этого момента доступ к альбому осуществляется по его идентификатору. В чем сложность для вас?   -  person matt    schedule 13.10.2015


Ответы (1)


Поскольку этот вопрос специально нацелен на iOS 8, этот код будет работать нормально:

- (void)saveImage:(UIImage *)image {
    if (!self.library) {
        self.library = [[ALAssetsLibrary alloc] init];
    }

    __weak ALAssetsLibrary *lib = self.library;

    [self.library addAssetsGroupAlbumWithName:@"My Photo Album" resultBlock:^(ALAssetsGroup *group) {

        ///checks if group previously created
        if(group == nil){

            //enumerate albums
            [lib enumerateGroupsWithTypes:ALAssetsGroupAlbum
                               usingBlock:^(ALAssetsGroup *g, BOOL *stop)
             {
                 //if the album is equal to our album
                 if ([[g valueForProperty:ALAssetsGroupPropertyName] isEqualToString:@"My Photo Album"]) {

                     //save image
                     [lib writeImageDataToSavedPhotosAlbum:UIImagePNGRepresentation(image) metadata:nil
                                           completionBlock:^(NSURL *assetURL, NSError *error) {

                                               //then get the image asseturl
                                               [lib assetForURL:assetURL
                                                    resultBlock:^(ALAsset *asset) {
                                                        //put it into our album
                                                        [g addAsset:asset];
                                                    } failureBlock:^(NSError *error) {

                                                    }];
                                           }];

                 }
             }failureBlock:^(NSError *error){

             }];

        }else{
            // save image directly to library
            [lib writeImageDataToSavedPhotosAlbum:UIImagePNGRepresentation(image) metadata:nil
                                  completionBlock:^(NSURL *assetURL, NSError *error) {

                                      [lib assetForURL:assetURL
                                           resultBlock:^(ALAsset *asset) {

                                               [group addAsset:asset];

                                           } failureBlock:^(NSError *error) {

                                           }];
                                  }];
        }

    } failureBlock:^(NSError *error) {

    }];
}

Чтобы проверить, работает ли это, я создал одноэкранное приложение, добавил кнопку в представление и добавил метод, который делает снимок экрана, а затем передает изображение функции saveImage:. Вот код, который я добавил к нему, чтобы заставить его работать:

#import <AssetsLibrary/AssetsLibrary.h>

@interface ViewController ()
@property (nonatomic, strong) UIButton *screenshotButton;
@property (nonatomic, strong) ALAssetsLibrary *library;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    [self.view addSubview:self.screenshotButton];
}

- (UIButton *)screenshotButton {
    if (!_screenshotButton) {
        _screenshotButton = [[UIButton alloc] initWithFrame:CGRectInset(self.view.bounds, 100.0f, 120.0f)];
        _screenshotButton.layer.borderColor = [UIColor blueColor].CGColor;
        _screenshotButton.layer.borderWidth = 2.0f;
        _screenshotButton.layer.cornerRadius = 5.0f;
        [_screenshotButton setTitle:@"Take Screenshot" forState:UIControlStateNormal];
        [_screenshotButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
        [_screenshotButton addTarget:self action:@selector(takeScreenshot) forControlEvents:UIControlEventTouchUpInside];
    }

    return _screenshotButton;
}

- (void)takeScreenshot {
    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
        UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, [UIScreen mainScreen].scale);
    else
        UIGraphicsBeginImageContext(self.view.bounds.size);

    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    NSData * imgData = UIImagePNGRepresentation(image);
    if(imgData)
        [imgData writeToFile:@"screenshot.png" atomically:YES];
    else
        NSLog(@"error while taking screenshot");


    UIColor *randomColor = [UIColor colorWithHue:((CGFloat)(arc4random()%255)/255.0f)
                                      saturation:((CGFloat)(arc4random()%255)/200.0f)
                                      brightness:((CGFloat)(arc4random()%100)/255.0f) + 0.5f
                                           alpha:1.0f];
    self.screenshotButton.layer.borderColor = randomColor.CGColor;
    [self.screenshotButton setTitleColor:randomColor forState:UIControlStateNormal];

    [self saveImage:image];
}

Несколько замечаний:

  • AssetsLibrary устарело в iOS 9, поэтому его не рекомендуется использовать после iOS 8, но он все равно будет работать.
  • Это можно реализовать и использовать с любым UIImage, переданным в saveImage:, поэтому он может работать, даже если вы используете другую библиотеку.
  • Обязательно укажите #import <AssetsLibrary/AssetsLibrary.h>.
  • Измените «Мой фотоальбом» на правильное название альбома и, возможно, установите его статически.
person Fennelouski    schedule 13.10.2015
comment
Проблема легко решается с помощью Photo Kit; использование библиотеки активов - это просто костыль. - person matt; 14.10.2015
comment
Здорово! Я только что добавил оператор If, чтобы создать папку, если пользователь ее удалит. Спасибо! - person MOzeb; 14.10.2015
comment
Я не согласен с тем, что это не идеально, и, вероятно, есть лучший вариант, который больше подходит для iOS 9, но он работает и соответствует требованиям для iOS 8. - person Fennelouski; 14.10.2015