iosobjective-cin-app-purchaseself-hostingrmstore

How to associate self hosted content with transaction?


I'm trying to add in-app purchase feature to my application and I want to download contents that I host in my own server. RMStore provides an API to do this, however I couldn't figure out how to do it.

Documentation says:

RMStore delegates the downloading of self-hosted content via the optional contentDownloader delegate. You can provide your own implementation using the RMStoreContentDownloader protocol:

- (void)downloadContentForTransaction:(SKPaymentTransaction*)transaction
                              success:(void (^)())successBlock
                             progress:(void (^)(float progress))progressBlock
                              failure:(void (^)(NSError *error))failureBlock;

Call successBlock if the download is successful, failureBlock if it isn't and progressBlock to notify the download progress. RMStore will consider that a transaction has finished or failed only after the content downloader delegate has successfully or unsuccessfully downloaded its content.

And here is the protocol (from RMStore.h):

@protocol RMStoreContentDownloader <NSObject>

/**
 Downloads the self-hosted content associated to the given transaction and calls the given success or failure block accordingly. Can also call the given progress block to notify progress.
 @param transaction The transaction whose associated content will be downloaded.
 @param successBlock Called if the download was successful. Must be called in the main queue.
 @param progressBlock Called to notify progress. Provides a number between 0.0 and 1.0, inclusive, where 0.0 means no data has been downloaded and 1.0 means all the data has been downloaded. Must be called in the main queue.
 @param failureBlock Called if the download failed. Must be called in the main queue.
 @discussion Hosted content from Apple’s server (@c SKDownload) is handled automatically by RMStore.
 */
- (void)downloadContentForTransaction:(SKPaymentTransaction*)transaction
                              success:(void (^)())successBlock
                             progress:(void (^)(float progress))progressBlock
                              failure:(void (^)(NSError *error))failureBlock;

@end

Simply it says, downloads the self-hosted content associated to the given transaction. How do I associate the self-hosted to transaction?


Solution

  • Here what I did. Obviously you need to add RMStore.h and the protocol RMStoreContentDownloader in the class where you run this method. It works, although I did not understand how it is managed the progressBlock (maybe my download is too short?)...

    - (void)downloadContentForTransaction:(SKPaymentTransaction*)transaction
                              success:(void (^)())successBlock
                             progress:(void (^)(float progress))progressBlock
                              failure:(void (^)(NSError *error))failureBlock
    {
        //the product purchased
        NSString *productID = transaction.payment.productIdentifier;
    
    
        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
        AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
    
        //HERE IS WHERE TO INSERT THE URL
        NSURL *URL = [NSURL URLWithString:@"http://example.com/download.zip"];
        NSURLRequest *request = [NSURLRequest requestWithURL:URL];
    
        NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
        NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
        return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
        } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
        if (error == nil)
            NSLog(@"File downloaded to: %@", filePath);
            successBlock();
        else
            NSLog(@"Error in download: %@", error.localizedDescription);
            failureBlock();
        }];
        [downloadTask resume];
        [manager setDownloadTaskDidWriteDataBlock:^(NSURLSession *session,    NSURLSessionDownloadTask *downloadTask, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite)
        {
            float percentDone = (((float)((int)totalBytesWritten) / (float)((int)totalBytesExpectedToWrite))*100);
            progressBlock(percentDone);
        }];
    
    }
    

    Then the method will be called by RMStore at the right moment!

    Hope it helps!