For my app, I need to communicate with many different urls in the same app, I want to handle this requirements with AFNetworking API, but the AFNetworking examples used a singleton to communicate with one base url, and put the http requests with different relative urls in the operation queue. I am still puzzled with the design using AFNetworking, I think I need to create a couple of singletons to handle different urls, that's definitely a weired design, or I need to re-write the AFHTTPClient to fit my requirements, or I need a networkingMgr to maintain a list of AFHTTPClient, it's hard to decouple the AFHTTPClient with different urls. Could anybody give some suggestions? Thank you very much.
I dont understand why you can't use the following code taken from: CocoaDocs
Using you own NSString for the URL
NSString *myUrlString = [NSString stringWithFormat:#"%#%#",baseUrl,relativeUrl];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:myUrlString parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
Related
I am starting learning about web service, where I use one url api to get data and to display in my table view. But I saw some tutorials - in that they use NSURLConnection or Rest API or AFNetworking.
I am really confused about all type. Which one should I use in that above type. For web service which type should I use. And also I saw some doubts in SO that use synchronous or asynchronous. Thus this any another type to get data from URL?
Actually for all web service, which should I use to get data and display?
-(void)JsonDataParsing
{
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager POST:url parameters:params
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSDictionary *jsonDict = (NSDictionary *) responseObject;
//!!! here is answer (parsed from mapped JSON: {"result":"STRING"}) ->
NSString *res = [NSString stringWithFormat:#"%#", [jsonDict objectForKey:#"result"]];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//....
}
];
}
Firstly, AFNetworking and NSURLConnection are used on Mobile Side.
Rest API is not from mobile side. Rest API you implemented on server side which handle CRUD operations like GET, POST, PUT and DELETE.
Third party libraries are there to ease our work. And AFNetworking is very popular and trustworthy library.
AFNetworking makes asynchronous network requests. To read more about it, visit Introduction to AFNetworking.
AFNetworking does everything NSURLConnection can. Using it now will save you a lot of time writing boilerplate code!
NSURLConnection and NSURLSession is apple API use to manage network operation like download and upload, AFNetworking is the framework that use those 2 API and added multithreading/error handling/network reachability....to make your life easier, RESTful is the architecture for client-server connecting, u can implement it in your serverside to return things back to your clientside in easy to use model (JSON).
synchronous mean u wait for it to complete to do anything else, asynchronous means u just start it but don't need to wait for it, like u do a request to server and user still can interact with your UI at the same time, so its advised that use asynchronous task to request to server then only update the UI in synchronous
hope my explain is easy to understand and correct :)
NSURLConnection
This lets you to load the content of URL by providing the URL request object. By using NSURLConnection you can load URL requests both asynchronously using a callback block and synchronously. See this example
NSURL *URL = [NSURL URLWithString:#"http://example.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
// ...
}];
For more you can go to apple docs
AFNetworking
This is third party library built on the top of Foundation URL Loading.
This is very easy to install through pods and handy to use. See below example like how I am using the same in my app
-(AFHTTPRequestOperationManager *)manager
{
if (!_manager)
{
_manager = [AFHTTPRequestOperationManager manager];
_manager.requestSerializer = [AFHTTPRequestSerializer serializer];
_manager.responseSerializer = [AFHTTPResponseSerializer serializer];
}
return _manager;
}
Above we are initializing the instance of AFHTTPRequestOperationManager *manager
[self.manager POST:#"http://example.com" parameters:parameters
success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSError *error;
NSMutableDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:&error];
// return response dictionary in success block
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
// return error in failure block
}]
Above method will load data asynchronously and remaining is self explanatory. But if you want to block the user interface like a synchronous request than use [operation waitUntilFinished] which is an anti-pattern. Here operation is a instance of AFJSONRequestOperation.
I am pretty new to serializing with json, and I am facing a weird issue.
I am trying to send an NSURLRequest with a josn. The json is first stored into an NSSMutableDictionary and eventually is serialized. The serialized json object I get is escaped, meaning it has "\" in it all over the place.
The json is getting sent a server, but is getting denied. According to the admin the json is getting denied because its escaped. How can I removed all the back slashes from the serialized json before sending it.
HELP. I tried creating an NSString then converting to NSData then serialized and failed. I tried NSArray and failed. At least I think I did those correctly.
Did I make a mistake somewhere? is there a better way to do this?
Thanks,
Sam.
I came up with the same problem try AFNetworking
https://github.com/AFNetworking/AFNetworking
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:#"http://example.com/resources.json" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
NSlog(#"value->%#", [responseObject objectForKey#"json_key"]);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
Ive tried to avoid asking such a newb question on here, but im a Android dev learning IOS and I cant figure out for the life of me how to add a simple header to my post requests using AFNetworking 2.0. Below is my code so far which works if i want to make a request that doesnt require a header.Could anyone show me via adding to my snippet or providing a alternate one that does this? I came across this tut: http://www.raywenderlich.com/30445 that shows how to add a header under the "A RESTful Class" heading , but its for afnetworking 1.0 and is now depreciated as far as i can tell.
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = #{#"uid": #"1"};
AFHT
[manager POST:#"http://myface.com/api/profile/format/json" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
//NSLog(#"JSON: %#", responseObject);
self.feedArray = [responseObject objectForKey:#"feed"];
[self.tableView reloadData];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
} ];
}
Under AFHTTPRequestOperationManager you will notice a property called requestSerializer. This is of type AFHTTPRequestSerializer, and requests made through the HTTP manager are constructed with the headers specified by this object.
So, try this:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager.requestSerializer setValue:#"SomeValue" forHTTPHeaderField:#"SomeHeaderField"]
//Make your requests
You can read the headers dictionary from the request serializer as follows:
manager.requestSerializer.HTTPRequestHeaders
Note that once you set a header this way, it will be used for all other operations!
[manager.requestSerializer setAuthorizationHeaderFieldWithUsername:#"staging" password:#"dustylendpa"];
Got a comment to make the main question a separate ticket and separate each question.
I am trying to write code for an SDK. I need to make API calls.
I am using AFNetworking 2.0 to send a POST request to the server:
NSDictionary * params = [self formDictionaryFromCard: card];
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] requestWithMethod:#"POST" URLString: [self apiUrl] parameters: params];
[request addValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request addValue:#"Firefox" forHTTPHeaderField:#"User-Agent"];
AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request];
op.responseSerializer = [AFJSONResponseSerializer serializer];
[op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
successBlock(responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
errorBlock(error);
}];
[[NSOperationQueue mainQueue] addOperation:op];
Is this the correct way to use AFNetworking to make API calls for an SDK?
How do I provide support for https?
Is this the correct way to use AFNetworking to make API calls for an
SDK?
Your code will work as-is. There are a few suggestions I'd make to change it.
Main Queue
Although the sample code on CocoaDocs shows mainQueue being used, consider if you want to use a different NSOperationQueue besides mainQueue. Here are a few possible reasons:
If you'll need to go through and find one of your operations later (for example, if you want to cancel/pause uploads.)
If you use mainQueue for anything else, and you don't want the priority of those operations to be compared to the priority of your network operations when the system looks at which operation to start next
If you'd like more than 1 network request to run at a time (for example, if you want to be able to download a photo and post a message at the same time).
You could use AFNetworking's built-in operation queue (on AFHTTPRequestOperationManager):
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager.operationQueue addOperation:op];
You could also use one of your own.
Check for blocks before calling them
You may want to check for the presence of blocks before calling them to void crashes:
if (successBlock) {
successBlock(responseObject);
}
Avoid redundant code
If all or most of your operations will require these customizations to the header, it's probably easier to subclass AFHTTPRequestOperationManager, and override HTTPRequestOperationWithRequest: success: failure: to add your headers there. Then you can use AFHTTPRequestOperationManager's convenience methods (the ones that begin with POST and GET).
Take a look at the documentation for AFHTTPRequestOperationManager.
How do I provide support for https?
For most uses, simply include https in your URL (in your case, in [self apiUrl]). For specific uses, such as to allow invalid certs, or to only accept specific ones, you will need to look into the AFSecurityPolicy class.
It,s my first time trying to send Images & Data to a PHP Server from an app, and I am quite confused as to what's the best way to achieve this.
In my research, I came across AFNetworking library and this base64 library (which I would take suggestion in another one), but I don't know if I can achieve what I want with that or how to implement it.
What I want to do is to send data & images that have a relationship.
Lets say the User has to upload their user details + their picture and their house details + a picture
my JSON would be something like
{
"userDetails": { "name":"jon",
"surname":"smith",
"phone":"123412",
"userPic":"base64pic"
},
"house": { "address":"123 asd",
"postcode":"w2 e23",
"housePic":"base64pic"
}
}
of course that JSON would also have to include security validations.
My problem comes when I would like to avoid using base64 encoding given the 33% size increase and I don't know how I could send the same information to PHP.
I get very confused when trying to send images & data that have a relationship and should be stored taking that relationship into account in the server.
Basically What I am looking for is a way to send the same information but not base64 encoded images but keeping the relationship in the data and trying to send as fewer request as possible. Is it possible? if so How?
look at this example for instance, eveything is pretty self explanatory but ask me if you have any questions
-(void) postStuff{
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:#"https://www.yourdomain.com/"]];
NSDictionary *parameter = #{#"body"#"Anything you want to say!"};
NSMutableURLRequest *request = [httpClient multipartFormRequestWithMethod:#"POST" path:#"api/v1/posts/newpost/" parameters:parameter constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) {
[formData appendPartWithFileData:imageData name:#"image" fileName:#"image.png" mimeType:#"image/png"];
}];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLOG(#"DONE!!!");
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLOG(#"Error: %#", error);
}];
[httpClient enqueueHTTPRequestOperation:operation];
}