在静态库中使用ALAssetsLibrary时无法枚举组/结果

时间:2014-01-14 07:46:55

标签: ios static-libraries alassetslibrary

这个问题有点解决,但在这个问题的底部还有一个请求。毕竟我会选择一个答案。


我正在创建一个使用AssetsLibrary framework的静态库。我在一个项目中使用它来测试是否有效。当我调用enumerateGroupsWithTypes:usingBlock:failureBlock:实例的AssetsLibrary方法时,它什么都不返回。

我试过了 -

  1. 设置断点以查看它如何运行此方法。事实证明它没有进入传递给usingBlock: ALAssetsLibraryGroupsEnumerationResultsBlock的块,而是failureBlock:。所以我什么也没得到。

  2. 将相同的枚举代码添加到我在开头提到的项目中尝试调用AssetsLibrary的方法。它完美地工作很好

  3. 测试它是否被主线程阻塞,然后在主线程中运行它。得到了与以前相同的结果。

  4. 对于这个问题,我找到了另一个问题的答案,即谈论在静态库中使用媒体:https://stackoverflow.com/a/15331319/1583560,我不确定我是否遇到了同样的情况,是媒体他/她提到包括访问AssetsLibrary,我想这里没有。

    希望有人可以指出这方面的一些指示,谢谢:)


    更新

    这是我使用的代码 -

    [[[ALAssetsLibrary alloc] init] enumerateGroupsWithTypes:ALAssetsGroupAll
                                                  usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
                                                      NSLog(@"%s",__PRETTY_FUNCTION__);
                                                  } failureBlock:^(NSError *error) {
                                                      NSLog(@"%s",__PRETTY_FUNCTION__);
                                                  }];
    

    静态库中的代码与测试项目中的代码相同,唯一的区别是我创建了一个模型类来访问静态库中的AssetsLibrary

    要明确的是,我在静态库中做了一些更改 -

    • 更改目标>中的Build Product Path构建设置$(PROJECT_DIR)/../build
    • 将所需的头文件移动到目标>中的项目部分构建阶段>复制标题
    • 目标>中将Skip Install设为YES构建设置

    环境相关 -

    • OS X 10.9.1
    • Xcode 5.0.2
    • 标准体系结构(包括64位)(静态库和项目)
    • ARC

    更多详情

    我建议创建一个资产模型,以便在此静态库中轻松访问。

    • 让一个组数组存储设备中的所有相册,ALAssetsGroup
    • 在此模型的init枚举相册并存储到群组数组中。
    • 枚举照片,这是ALAssets结果,由需要时提供的群组。

    这个模型使用单例模式。

    BTW ,我试图观察这个静态库中的ALAssetsLibraryChangedNotification。它也不起作用。 AssetsLibrary前面是否有任何潜在的障碍物?


    更新

    我发现我在创建模型时init枚举了这些组。并且有线程使块不起作用。如果我在init完成后触发枚举,将完美运行。我还找到了知道何时完成枚举(参见https://stackoverflow.com/a/13309871/1583560)以获取我存储的组数组的方法。

    进一步 ,我仍然无法找到解决阻止线程的文件Apple,为什么在init时不会调用它。如果有人可以为我指出,我会很感激:)。

2 个答案:

答案 0 :(得分:1)

由于枚举ALAssetsGroup的异步,这不是“无法枚举设备上的资产”。


异步

根据apple关于enumerateGroupsWithTypes:usingBlock:failureBlock:的{​​{1}}的文档,这是一个异步方法,在运行后不会将完整数据存储在数组中。

  

此方法异步。枚举组时,可能会要求用户确认应用程序对数据的访问权限;但是,该方法立即返回。您应该使用enumerationBlock中的资源执行您想要的任何工作。


完成通知

我确实想知道它什么时候完成。所以我找到了一个答案,知道进展何时完成,并执行一个块(参见Create my own completion blocks in iOS)。虽然这不是关于通知的,但仍然给了我一个提示来解决它。

ALAssetsLibrary,当它到达枚举结束时

postNotification:

[_assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) { if(group){ // add into the array you are going to use } else { // the last one will be nil, // it also means the enumeration is done // post notification then [[NSNotificationCenter defaultCenter] postNotificationName:kEnumerateGroupCompleteNotification]; } } failureBlock:nil]; // leave nil here for make subject out 添加观察者以重新加载数据

首先,使用空addObserver:selector:name:object:,这是我们在上一步使用的保留数组,NSArray协议~DataSource或{{ 1}}。

第二次,向UICollectionView添加一个观察者,使用UITableView传递给此方法来触发实例的UIViewController以获取完整的数组,只需枚举。数据将显示在视图中。

@selector

结论

这就是我实现我的要求的方式。我之前只讨论了reloadData,但在// In a UIViewController's implementation - (void)viewDidLoad{ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadTableView:) name:kEnumerateGroupCompleteNotification object:nil]; } -(void)reloadTableView:(NSNotification*) notification { // reloadData after receive the notification [_tableView reloadData]; } 的枚举中它会是相同的。

如果您想获取ALAssetsGroup并重新加载数据,则采用相同的方式。

非常感谢Ramshad的answer,我现在在静态库中访问ALAssets作为您的建议。

答案 1 :(得分:0)

将以下方法添加到您的班级:

+ (ALAssetsLibrary *)defaultAssetsLibrary
{
    static dispatch_once_t pred = 0;
    static ALAssetsLibrary *library = nil;
    dispatch_once(&pred, ^{
        library = [[ALAssetsLibrary alloc] init];
    });
    return library;
}

然后将代码修改为

ALAssetsLibrary *assetsLibrary = [ViewController defaultAssetsLibrary];
[assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop)
 {
    [group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop)
     {
        if(result)
        {
           NSLog(@"Success");
        }
     }];

 } failureBlock:^(NSError *error)
 {
        NSLog(@"Error loading images %@", error);
 }];