I have a need to upload a file to our server. However the server will process the file and fire it into a database. I am looking at NSInputStream
which appears to work fine, however, I also need additional parameters like user token and file extension and I am not sure how to achieve this. I can use HTTPBodyStream
for the stream itself, but then the method complains that not all parameters are supplied. The code I am using is below and is based on other areas where I post data to the web method.
- (IBAction)uploadFile:(id)sender {
// File will be replaced in production with selected file from resources directory
NSString* path = [[NSBundle mainBundle] pathForResource:@"myFile"
ofType:@"docx"];
NSInputStream *stream = [[NSInputStream alloc] initWithFileAtPath:path];
// JSON Method
NSURL *uploadURL = [NSURL URLWithString:@"myDomain/myMethod"];
NSDictionary *requestDict = [[NSDictionary alloc] initWithObjectsAndKeys:
@"userTokenValue", @"userToken",
stream,@"fileStream",
@"docx", @"fileExt",
nil];
NSError *error;
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:requestDict options:NSJSONReadingMutableContainers|NSJSONReadingAllowFragments error:&error];
NSString *json=[[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];
NSData *postData=[NSData dataWithBytes:[json UTF8String] length:[json length]];
request = [[NSMutableURLRequest alloc] initWithURL:uploadURL];
// Allows all parameters to be sent in other calls in the app, however generates SIGABRT here - detail below
[request setHTTPBody:postData];
// Reaches method, but method complains that not all parameters are supplied obviously
[request setHTTPBodyStream:stream];
[request setHTTPMethod:@"POST"];
NSError *requestError=nil;
NSURLResponse *response = nil;
NSData *data=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&requestError];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
if (requestError == nil) {
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
if (statusCode != 200) {
NSLog(@"Warning, status code of response was not 200, it was %ld", (long)statusCode);
}
}
NSError *error;
NSDictionary *returnDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
if (returnDictionary) {
NSLog(@"returnDictionary=%@", returnDictionary);
} else {
NSLog(@"error parsing JSON response: %@", error);
NSString *returnString = [[NSString alloc] initWithBytes:[data bytes] length:[data length] encoding:NSUTF8StringEncoding];
NSLog(@"returnString: %@", returnString);
}
} else {
NSLog(@"NSURLConnection sendSynchronousRequest error: %@", requestError);
}
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
The SIGABRT mentioned above is:
'NSInvalidArgumentException', reason: 'Invalid type in JSON write (__NSCFInputStream)'
How can I stream the file data via the web method as well as supplying the other parameters. Thanks.