Code Monkey home page Code Monkey logo

posinputstreamlibrary's Introduction

NSInputStream for ALAsset

POSInputStreamLibrary contains NSInputStream implementation which uses ALAsset as its data source. The main features of POSBlobInputStream are the following:

  • Synchronous and asynchronous working modes.
  • Autorefresh after ALAsset invalidation.
  • Smart caching of ALAsset while reading its data.
  • Using NSStreamFileCurrentOffsetKey property for read offset specification.

The category for NSInputStream defines initializers for the most common cases:

@interface NSInputStream (POS)
+ (NSInputStream *)pos_inputStreamWithAssetURL:(NSURL *)assetURL;
+ (NSInputStream *)pos_inputStreamWithAssetURL:(NSURL *)assetURL asynchronous:(BOOL)asynchronous;
+ (NSInputStream *)pos_inputStreamForCFNetworkWithAssetURL:(NSURL *)assetURL;
@end

All of them require NSURL of ALAsset. POSBlobInputStream will query ALAssetLibrary for ALAsset during the opening.

Working modes

Synchronous

In sync mode all methods of POSInputStream completely perform their work during the call. If it is necessary to obtain some data from ALAssetLibrary the calling thread will be blocked. This makes possible to work with a stream without subscribing to its events, but at the same time neither method of NSInputStream should be called from the main thread. The reason is that ALAssetLibrary interacts with the client code in the main thread. Thus there will be a deadlock if POSBlobInputStream waits the answer from ALAssetLibrary in a blocked main thread. Here is an example of POSBlobInputStream usage in a sync mode for calculating checksum of ALAsset.

NSInputStream *stream = [NSInputStream pos_inputStreamWithAssetURL:assetURL asynchronous:NO];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    [stream open];
    if ([stream streamStatus] == NSStreamStatusError) {
        // Error notification
        [stream close];
        return;
    }
    NSParameterAssert([stream streamStatus] == NSStreamStatusOpen);
    while ([stream hasBytesAvailable]) {
        uint8_t buffer[kBufferSize];
        const NSInteger readCount = [stream read:buffer maxLength:kBufferSize];
        if (readCount < 0) {
            break;
        } else {
            // Checksum update
        }
    }
    if ([stream streamStatus] != NSStreamStatusAtEnd) {
        // Error notification
    }
    [stream close];
}

Asynchronous

In async mode all methods of POSBlobInputStream return immediately after call. Client code should provide a delegate to the stream to receive information about its status. This is the only way to know when the stream opened, when it has data to read and about errors. You can see async version of checksum calculation below.

@interface ChecksumCalculator () <NSStreamDelegate>
@end

@implementation ChecksumCalculator

- (void)calculateChecksumForStream:(NSInputStream *)aStream {
    aStream.delegate = self;
    [aStream open];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ @autoreleasepool {
        NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
        [aStream scheduleInRunLoop:runLoop forMode:NSDefaultRunLoopMode];
        for (;;) { @autoreleasepool {
            if (![runLoop runMode:NSDefaultRunLoopMode
                       beforeDate:[NSDate dateWithTimeIntervalSinceNow:kRunLoopInterval]]) {
                break;
            }
            const NSStreamStatus streamStatus = [aStream streamStatus];
            if (streamStatus == NSStreamStatusError || streamStatus == NSStreamStatusClosed) {
                    break;
            }
        }}
    }});
}

#pragma mark - NSStreamDelegate

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode {
    switch (eventCode) {
        case NSStreamEventHasBytesAvailable: {
            [self updateChecksumForStream:aStream];
        } break;
        case NSStreamEventEndEncountered: {
            [self notifyChecksumCalculationCompleted];
            [aStream close];
        } break;
        case NSStreamEventErrorOccurred: {
            [self notifyErrorOccurred:[aStream streamError]];
            [aStream close];
        } break;
    }
}

@end

Integrating with NSURLRequest

POSBlobInputStream provides pos_inputStreamForCFNetworkWithAssetURL initializer for NSURLRequest integration. It takes into account the following CFNetwork "features":

  • CFNetwork works with a stream in a sync mode.
  • CFNetowrk uses deprecated CFReadStreamGetError method to get error description from the stream. This action will crash the app because of the bug in a "toll-free bridging" implementation for NSInputStream. This is the reason why streamStatus method will never return NSStreamStatusError. More over, POSBlobInputStream will not notify about its status change via C-callbacks. The only way to receive actual status of the stream is via NSStreamDelagate callback.

posinputstreamlibrary's People

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.