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

Unable to enumerate groups/results while using ALAssetsLibrary in static library

提问人:vc7 提问时间:1/14/2014 最后编辑:Communityvc7 更新时间:1/18/2014 访问量:847

问:

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


我正在创建一个使用 .当我在项目中使用它来测试是否有效时。当我调用 的实例的方法时,它不返回任何内容。AssetsLibrary frameworkenumerateGroupsWithTypes:usingBlock:failureBlock:AssetsLibrary

我试过——

  1. 设置断点以查看它如何运行此方法。事实证明,它没有进入传递给 的块,这是 ,并且 .所以我一无所获。usingBlock:ALAssetsLibraryGroupsEnumerationResultsBlockfailureBlock:

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

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

对于这个问题,我找到了另一个问题的答案,该问题正在讨论在静态库中使用媒体: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
  • 将所需的头文件移动到 Target > Build Phases > Copy Headers 中的 Project 部分
  • “目标>生成设置”中设置为Skip InstallYES

环境相关 -

  • 操作系统 X 10.9.1
  • X代码 5.0.2
  • 标准体系结构(包括 64 位)(静态库和项目)

更多详情

这是我的建议,即制作一个资产模型,以便于在这个静态库中访问。

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

而这个模型使用单例模式。

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


更新

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

此外,我仍然找不到 Apple 的文档,该文档解决了块的线程,为什么它不会被调用。如果有人能为我指出,我将不胜感激:)。init

ios 静态 alassets库

评论

0赞 vc7 1/16/2014
您好,感谢您询问代码。我已经更新了问题并将其添加到原始问题的末尾。

答:

0赞 Shamsudheen TK 1/16/2014 #1

将以下方法添加到类中:

+ (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);
 }];

评论

0赞 vc7 1/16/2014
谢谢,使用单例是一个很好的方法,但是在遵循您的建议后我仍然一无所获,我将更新我制作的资产模型的更多细节。AssetsLibrary
1赞 vc7 1/18/2014 #2

这与“无法枚举设备上的资产”无关,因为枚举 .ALAssetsGroup


异步

根据苹果的文档,这是一个异步方法,运行后不会得到存储在数组中的完整数据。enumerateGroupsWithTypes:usingBlock:failureBlock:ALAssetsLibrary

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


竣工通知

我确实想知道什么时候完成。这样我就找到了知道进度何时完成的答案,并执行一个块(参见在 iOS 中创建我自己的完成块)。尽管这与通知无关,但仍然给了我一个提示来解决这个问题。

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~DataSourceUICollectionViewUITableView

其次,向 添加一个观察者,使用传递给此方法以触发实例获取刚刚枚举的完整数组。数据将显示在视图上。UIViewController@selectorreloadData

// 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];

}

结论

这就是我实现要求的方式。我只在上面谈到了,但在枚举中将是相同的。ALAssetsGroupALAssets

如果您想获取和重新加载数据,也是一样的。ALAssetsLibraryChangedNotification

非常感谢 Ramshad 的回答,我现在可以在我的静态库中访问您的建议。ALAssetsLibrary