AFNetworking was offering the outputStream property for AFHTTPRequestOperation. Right now I'm changing to AFURLSessionManager and I want to keep my logic but I don't know if it's possible.
Old logic (simplified):
- (AFHTTPRequestOperation*)doRequestWithOutputSteam:(NSOutputStream*) outputStream
{
AFHTTPRequestOperationManager* manager = [AFHTTPRequestOperationManager manager];
AFHTTPRequestOperation* operation = [manager GET:#"http://example.com/file/to/download"
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Success");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error.localizedDescription);
}];
if (outputStream)
{
operation.outputStream = outputStream;
}
return operation;
}
I'm using this function because I'm streaming the data directly to another device. I don't want to wait until the download is finished and then stream the data to the device. I want to stream it while the data is received.
Question:
Is there a way to keep the behaviour while using AFURLSessionManager and NSURLSession?
Related
I have string objects and image stored in nsdata. How can i send it to a server by accessing the url? I have seen examples .but its not working.Can someone tell me
Thanks in Advance!!
You could use AFNetworking to easily send string and image to server using url.
Here is a link of tutorial how to use AFNetworking framework.
AFNetworking Tutorial
AFNetworking is the best way to do that. and there are so much tutorials out there.
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *params = #{#"username": _username.text,
#"password": passwordMD5
};
[manager POST:#"http://example.com/ws/test.php" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject); //This is the Response
}else{
//if you didnt get expected output then handle it here
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
//Handle any network errors here. ex: if internet disconnected.
}];
Here is an example how to upload an image with string objects as a dictionary to a server using AFNetworking.
- (void)uploadPhoto {
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:#"http://server.url"]];
NSData *imageData = UIImageJPEGRepresentation(self.avatarView.image, 0.5);
NSDictionary *parameters = #{#"username": self.username, #"password" : self.password};
AFHTTPRequestOperation *op = [manager POST:#"rest.of.url" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
//do not put image inside parameters dictionary as I did, but append it!
[formData appendPartWithFileData:imageData name:paramNameForImage fileName:#"photo.jpg" mimeType:#"image/jpeg"];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Success: %# ***** %#", operation.responseString, responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %# ***** %#", operation.responseString, error);
}];
[op start];
}
I create a background thread to do a series of AFNetworking requests, and I want them to be in order. Some code:
dispatch_queue_t request_queue = dispatch_queue_create("someLabel", NULL);
dispatch_async(request_queue, ^{
dispatch_semaphore_wait(self.mySemaphore, DISPATCH_TIME_FOREVER);
// AFnetworking request I want to be synchronous
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = #{#"foo": #"bar"};
[manager POST:#"http://example.com/resources.json" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
...
How do I make the AFHTTPRequest synchronous?
Thanks!
In this case, you should generate the NSURLSessionDataTask yourself. The AF Operation manager will enqueue the operation immediately (that's just what it does). If you create one yourself, you can call resume when you please or add the operation to your own queue as you please.
I am downloading jpeg images via POST request using AFNetworking 2.0:
[manager.httpManager.requestSerializer setValue:#"image/jpeg" forHTTPHeaderField:#"Accept"];
NSDictionary *parameters = #{#"filename": imageName};
manager.httpManager.responseSerializer = [AFImageResponseSerializer serializer];
AFHTTPRequestOperation *operation = [manager.httpManager POST:URL_BASE_IMG parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Image: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
Showing the responseObject is not an issue. However, how can I specify a path so that the response object is downloaded straight into it? I have seen the use of streams but I do not know how to implement it here. Anybody? Thanks in advance
Imgur's API requires that for simply looking up information about an image you just need to authorize your app with your API keys, no need to log in with an account or anything.
It says:
...all you need to do is send an authorization header with your client_id in your requests
Which apparently looks like:
Authorization: Client-ID YOUR_CLIENT_ID
So I tried doing this using AFHTTPRequestOperationManager, which appears to be the replacement for AFHTTPClient in AFNetworking 2.0 as shown below:
AFHTTPRequestOperationManager *operationManager = [AFHTTPRequestOperationManager manager];
[operationManager POST:#"https://api.imgur.com/3/image/1Nf1quS" parameters:#{#"Authorization": #"Client-ID ---"} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"success");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"failure");
}];
Basically tried to send a request with authorization information (I removed my ID for this post). It keeps giving "failure" as a response however.
So I tried playing around with the credential property but NSURLCredential seems to be based off a username and password, and I have neither of those as I just need my client ID.
So I tried a completely different way again:
AFHTTPRequestOperationManager *operationManager = [AFHTTPRequestOperationManager manager];
NSMutableURLRequest *request= [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"https://api.imgur.com/3/image/1Nf1quS"]];
[request addValue:#"Client-ID ---" forHTTPHeaderField:#"Authorization"];
[operationManager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"success");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"fail");
}];
This time using the authorization things as a value on the request. But this one actually never even logged anything.
I'm quite new to API use, so I'm really confused what I'm doing wrong.
Edit:
Try this code snippet
AFHTTPRequestOperationManager *operationManager = [AFHTTPRequestOperationManager manager];
[operationManager.requestSerializer setValue:#"Client-ID ---" forHTTPHeaderField:#"Authorization"];
[operationManager GET:#"https://api.imgur.com/3/image/1Nf1quS" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"success");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"failure");
}];
I don't know about Imgur API, but for handling header and stuff, if you are just gonna do a few request to the API, you may add the headers just before the request operation. However, if you need to make API calls in more than one place, I think subclassing AFHTTPRequestOperationManager would be a better way to handle this.
For example you can create a subclass named MRTImgurRequestOperationManager:
#interface MRTImgurRequestOperationManager : AFHTTPRequestOperationManager
+ (MRTImgurRequestOperationManager*)sharedManager;
#end
and then in your implementation file:
+ (MRTImgurRequestOperationManager*)sharedManager
{
static MRTImgurRequestOperationManager *_sharedManager;
static dispatch_once_t _dispatchOnceToken;
dispatch_once(&_dispatchOnceToken, ^{
NSURL *baseURL = [NSURL URLWithString:#"API_URL_HERE"];
_sharedManager = [[MRTImgurRequestOperationManager alloc] initWithBaseURL:baseURL];
});
return _sharedManager;
}
- (id)initWithBaseURL:(NSURL*)url
{
self = [super initWithBaseURL:url];
if (self)
{
// Add headers or other options here
// For example
[self.requestSerializer setValue:#"VALUE" forHTTPHeaderField:#"HEADER_NAME"];
}
return self;
}
This way, you can add/remove HTTP headers without ever changing you code in couple of places. This may help with the testing as well.
So to use this, you would:
#import "MRTImgurRequestOperationManager.h"
and then make your Imgur request with the shared manager.
Edit:
You should use GET, not POST, with the API endpoint you are using
[[MRTImgurRequestOperationManager sharedManager] GET:#"path" parameters:params success:success failure:failure]];
In AFNetworking 2.0 you can set header fields. By using method from AFHTTPRequestSerializer
- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field
Try some thing like this:
AFHTTPRequestOperationManager *operationManager = [AFHTTPRequestOperationManager manager];
[operationManager.requestSerializer setValue:#"Client-ID ---" forHTTPHeaderField:#"Authorization"];
[operationManager POST:#"https://api.imgur.com/3/image/1Nf1quS" parameters:#{#"Authorization": #"Client-ID ---"} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"success");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"failure");
}];
I know there are tons ways to POST from an iOS app from nsurlconnection to asihttprequest.
What is the preferred or best practices way to post a few variables, asynchronously, to an end point, in iOS7?
My endpoint can be invoked in the following fashion:
curl -d 'username=tt&email=tt#example.com' 127.0.0.1/register
I ended up using afnetworking. This method works real nice.
-(void) postDictionary:(NSDictionary *)data toEndpoint:(NSString *)endpoint{
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:endpoint parameters:data success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
}