简体   繁体   English

使用XCTest将图像添加到ALAssetsLibrary

[英]Adding an Image to ALAssetsLibrary using XCTest

I have an app that uses photos extensively, making several operations on them: 我有一个广泛使用照片的应用程序,对它们进行了多次操作:

  • resizing 调整
  • cropping 种植
  • metadata extraction 元数据提取

Most of the methods I wrote operate on AlAssets therefore I would like to write my tests (I'm using the new XCTest framework) to operate also on ALAssets. 我编写的大多数方法都是在AlAssets上运行的,因此我想编写我的测试(我使用新的XCTest框架)来操作ALAssets。

I included in the project a set of photos to be used as input to the tests, I was planning on adding every single image to the library on [XCTest +setUp] and remove them on [XCTest +tearDown]. 我在项目中包含了一组用作测试输入的照片,我计划在[XCTest + setUp]上将每个图像添加到库中,然后在[XCTest + tearDown]上删除它们。

Everything went smoothly - while, kind of, it was a nightmare to have XCTest compiling - however for every call I make to: 一切顺利 - 虽然,有点,XCTest编译是一场噩梦 - 但是对于我做的每次通话都是:

- (void)writeImageDataToSavedPhotosAlbum:metadata:completionBlock:

The completion block never, ever, gets called and no image is added to the library, if later on, i enumerate all the photos there, I'll only see the photos that were previously available on the library. 从来没有调用完成块,并且没有图像被添加到库中,如果稍后,我枚举那里的所有照片,我将只看到以前在库上可用的照片。

In order to make sure the completion block runs, I control the app flow using semaphores, like this: 为了确保完成块运行,我使用信号量控制应用程序流,如下所示:

UIImage *image = [self imageWithName:@"DSC_0002" extension:@"JPG"];
NSData *dataJpeg = UIImageJPEGRepresentation(image, 0.9f);
ALAssetsLibrary* library = [[ALAssetsLibrary alloc] init];
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
[library writeImageDataToSavedPhotosAlbum:dataJpeg metadata:nil completionBlock:^(NSURL *assetURL, NSError *error) {
        // control will never run this code
        NSLog(@"Asset URL %@",[assetURL absoluteString]);
        dispatch_semaphore_signal(sem);
    }];
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);

Any ideas ? 有任何想法吗 ? Any possibility that it's impossible to write on the library on a XCTest ? 是否有可能在XCTest上写入库?

Thanks in advance, Ze 谢谢你,泽先生

You can stop the test method from exiting before the block executes by firing a runloop until a condition is met. 您可以通过触发runloop来阻止测试方法在块执行之前退出,直到满足条件。 Here is an example: 这是一个例子:

- (void)testAssetLibraryOperation
{
    NSURL *assetURL; // get this however you want
    ALAssetsLibrary *lib =  [ALAssetsLibrary new];

    __block BOOL waiting = YES;

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

        // perform tests on asset
        XCTAssertNotNil(asset, @"asset should not be nil");

        // stop waiting
        waiting = NO;

    } failureBlock:nil];


    // wait until BOOL says NO
    while (waiting) {
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
    }
}

You might want to add logic to stop waiting if the operation takes too long. 如果操作时间过长,您可能希望添加逻辑以停止等待。

Also you can checkout these resources on GitHub for more info and inspiration 您还可以在GitHub上查看这些资源以获取更多信息和灵感

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM