2

ここでは、ブロックと ALAssetLibrary ルーチンに少し苦労しています。ブロックに関する WWDC + スタンフォードのビデオを見て、少し読んだことがありますが、まだ十分に理解できていません。

私がやろうとしているのは、カスタム フォト ライブラリの posterImage を取得することです。以下の最初のルーチンはメインの viewControllerにありgetPosterImageForAlbum:、ALAssetLibrary クラス拡張にある関数を呼び出します。

私が苦労している/混乱している/試したこと:

  1. 参照 (CGImageRef または UIImage) を渡して、ALAssetLibrary メソッドでそれを設定するか、ALAssetLibrary メソッドの戻り値を定義してから、メイン クラスで画像を処理する必要がありますか? 私は両方の方法で試しましたが、成功しませんでした。

  2. ALAssetLibrary 列挙メソッドの非同期の性質は、ちょっと扱いにくいので、間違っていると思います。

  3. パラメータとして渡されるブロックの定義: 常に typedef する必要がありますか?

私はすべての概念的な小片を渦巻いていると思いますが、ブロックの操作を明確に理解するにはまだそれらをまとめることができていません. 良い記事へのヒントやポインタ*をいただければ幸いです。///

- (IBAction)getPosterImage:(id)sender {

    NSString *groupName = self.groupNameField.text;
    NSLog(@"%@", groupName);

    __weak typeof(self) weakSelf = self;

   CGImageRef tmpImg = [weakSelf.library getPosterImageForAlbum:groupName withCompletionBlock:(CGImageRef)(^GetPosterImageCompletion)(NSError *error){
        if (error!=nil) {
            NSLog(@"getPosterImage error: %@", [error description]);
        } else {
            if (tmpImg != nil){
                UIImage * posterImg = [UIImage imageWithCGImage:tmpImg];
                weakSelf.pImage.image = posterImg;
            }
        }
    }];
}

// これは ALAssetLibrary の拡張です

typedef CGImageRef(^GetPosterImageCompletion)(NSError* error);

-(CGImageRef)getPosterImageForAlbum:(NSString*)albumName
                withCompletionBlock:(GetPosterImageCompletion)completionBlock
{
    __block BOOL albumWasFound = NO;
    __block CGImageRef thePosterImage = nil;

    SaveImageCompletion test;
    //search all photo albums in the library
    [self enumerateGroupsWithTypes:ALAssetsGroupAlbum
                        usingBlock:^(ALAssetsGroup *group, BOOL *stop) {

            NSLog(@"this group name: %@",
                  [group valueForProperty:ALAssetsGroupPropertyName]);

            //compare the names of the albums              
            if ([albumName compare:
                 [group valueForProperty:ALAssetsGroupPropertyName]]==NSOrderedSame) {

                printf("matches \n");    //target album is found
                albumWasFound = YES;
                thePosterImage = group.posterImage;
                *stop = true;
                return ;
            }

        } failureBlock: test];

    if (albumWasFound==NO) {
        NSLog(@"%@", @"No group found");
    }
    return thePosterImage;
}
4

1 に答える 1

2

元の回答を大幅に編集しています。投稿した後で初めて、あなたがやろうとしていることを本当に理解できたからです。ALAssetLibrary に、アルバムのポスター画像を見つけるだけでなく、名前でアルバムのポスター画像を見つけるクラス拡張を記述します。ポスター画像は可能な限り名前で。

これを処理するには、UIImage 型の 1 つのパラメーター (またはオプションで NSError パラメーターも) を受け入れる完了ブロックをパラメーターとして受け取る拡張メソッドを記述します。その完了ブロックでは、呼び出し元は、非同期的に返された画像に対して、好きなことを行うことができます。ブロックを typedef する必要はありません -- メソッドを次のように書くことができます:

- (void) getPosterImageForAlbumNamed: (NSString *) albumName completionBlock: (void (^)(UIImage *, NSError *)) completionBlock
{
    __block ALAssetsGroup * foundAlbum = nil;
    [self enumerateGroupsWithTypes: ALAssetsGroupAlbum
                           usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
                               if (group) {
                                   if ([(NSString *) [group valueForProperty: ALAssetsGroupPropertyName] compare: albumName] == NSOrderedSame) {
                                       *stop = YES;
                                       foundAlbum = group;
                                       completionBlock([UIImage imageWithCGImage: [group posterImage]], nil);
                                   }
                               } else{
                                   if (! foundAlbum) {
                                       NSLog(@"Album wasn't found");
                                       // completionBlock(nil, XX SOME ERROR XX);
                                   }
                               }
                           } failureBlock:^(NSError *error) {
                               NSLog(@"Couldn't access photo library");
                               // completionBlock(nil, XX SOME ERROR XX);
                           }];

}

次に、この方法でメソッドを呼び出すことができます。

-(IBAction) getPosterForAlbum: (id) sender
{
    NSString * albumName = self.textField.text;
    ALAssetsLibrary * library = [[ALAssetsLibrary alloc] init];

    __weak typeof(self) weakSelf = self;
    [library getPosterImageForAlbumNamed: albumName completionBlock:^(UIImage * image, NSError * error) {
        if (! error) {
            [weakSelf doSomethingWithPosterImage: image];
        }
    }];
}

それはあなたがやろうとしていることの線に沿っていますか?(大幅な編集ですみません…)

于 2013-01-05T05:23:59.617 に答える