Skip to content

Frequently Asked Questions

Aleksey Garbarev edited this page Jun 30, 2015 · 2 revisions

Is it possible to upload binary data or file?

Yes, just specify that data as requestBody. If you want to upload data, you can return NSData object in that method. If you want to upload file, you can return NSInputStream object.

This is example of Redmine upload API implementation

RequestToUploadFile.h

#import "TRCRequest.h"

@interface RequestToUploadFile : NSObject <TRCRequest>

@property (nonatomic, strong) NSString *uploadPath;

@end

RequestToUploadFile.m

#import "RequestToUploadFile.h"

@implementation RequestToUploadFile

- (NSString *)path
{
    return @"uploads.json";
}

- (TRCRequestMethod)method
{
    return TRCRequestMethodPost;
}

- (id)requestBody
{
    return [NSInputStream inputStreamWithFileAtPath:self.uploadPath];
}

- (NSDictionary *)requestHeaders
{
    return @{
        @"Content-Type": @"application/octet-stream"
    };
}

- (id)responseProcessedFromBody:(NSDictionary *)bodyObject headers:(NSDictionary *)responseHeaders status:(TRCHttpStatusCode)statusCode error:(NSError **)parseError
{
    return bodyObject[@"upload"][@"token"];
}

@end

RequestToUploadFile.response.json

{
    "upload": {
        "token": "7167ed1ccdb093229ca1bd0b043618d88743"
    }
}

Is it possible to download file?

Yes, here is short example

RequestToDownloadFile.h

#import "TRCRequest.h"

@interface RequestToDownloadFile : NSObject <TRCRequest>

@property (nonatomic, strong) NSURL *downloadUrl;
@property (nonatomic, strong) NSString *outputPath;

@end

Here is two options available when you processing binary data:

1. Download as NSData then process as you like.

RequestToDownloadFile.m

#import "RequestToDownloadFile.h"

@implementation RequestToDownloadFile

- (NSString *)path
{
    return [self.downloadUrl absoluteString];
}

- (TRCRequestMethod)method
{
    return TRCRequestMethodGet;
}

- (TRCResponseSerialization)responseSerialization
{
    return TRCResponseSerializationData;
}

- (id)responseProcessedFromBody:(NSData *)bodyObject headers:(NSDictionary *)responseHeaders status:(TRCHttpStatusCode)statusCode error:(NSError **)parseError
{
    [bodyObject writeToFile:self.outputPath atomically:YES];
    return nil;
}

@end

2. Download data directly to file.

#import "RequestToDownloadFile.h"

@implementation RequestToDownloadFile

- (NSString *)path
{
    return [self.downloadUrl absoluteString];
}

- (TRCRequestMethod)method
{
    return TRCRequestMethodGet;
}

- (NSOutputStream *)responseBodyOutputStream
{
    return [NSOutputStream outputStreamToFileAtPath:self.outputPath append:NO];
}

@end

How to track download/upload progress?

When you using sendRequest:completion method, you can use returned object to control process. The returned object conform <TRCProgressHandler> protocol, and has next methods:

- (void)setUploadProgressBlock:(TRCUploadProgressBlock)block;
- (TRCUploadProgressBlock)uploadProgressBlock;

- (void)setDownloadProgressBlock:(TRCDownloadProgressBlock)block;
- (TRCDownloadProgressBlock)downloadProgressBlock;

- (void)pause;
- (void)resume;

- (void)cancel;

Example of usage:

RequestToDownloadFile *downloadRequest = [RequestToDownloadFile new];
downloadRequest.downloadUrl = [NSURL URLWithString:@"...."];
downloadRequest.outputPath = @"....";
    
id<TRCProgressHandler> handler = [_restClient sendRequest:downloadRequest completion:^(id result, NSError *error) {
    NSLog(@"Download complete %@ error %@",error?@"with":@"without", error?error.localizedDescription:@"");
}];
    
[handler setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
    NSLog(@"Download progress %g", totalBytesRead / (double)totalBytesExpectedToRead);
}];
    
//[handler cancel];

What kind of serialization available for response, request?

By default, TyphoonRestClient has next serializations for request:

  • JSON
  • Plist
  • Raw Data
  • UTF8 String
  • HTTP Query string

And next serializations for response:

  • JSON
  • Plist
  • Raw Data
  • UTF8 String
  • UIImage

If it's not enough, you can add your own serializations, using these methods:

- (void)registerRequestSerializer:(id<TRCRequestSerializer>)serializer forName:(TRCSerialization)serializerName;
- (void)registerResponseSerializer:(id<TRCResponseSerializer>)serializer forName:(TRCSerialization)serializerName;

TRCSerialization - is synonym for NSString. After registration serializer for specific name, you can use that name in TRCRequest protocol implementation.

Example:

id<TRCRequestSerializer> customSerializer = [CustomRequestSerializer new];
[_restClient registerRequestSerializer:customSerializer forName:@"CustomRequestSerializer"];

Then in some request:

- (NSString *)requestBodyValidationSchemaName
{
    return @"CustomRequestSerializer";
}

See extensions page for more information