Authenticate against a web service using AFNetworking 2 - afnetworking-2

I need to authenticate against a web service hosted on Domino Lotus Notes. I can get data from the web service and process it. I modified the code that does that and it works, but I really don't think I am doing it the correct way.
I will have the user enter their username and password, and then call this code below. If the success block is executed I will store their user name and password, if it is failure I will alert them and have them try again.
My questions are
1) What is the URL and method to just authenticate and return back a yes or no? I cannot find it?
2) Is there a way to do this NOT in blocks, or is there a way to stop the user from doing something until I get the block returned.
Any help would be greatly appreciated!!!
AFHTTPRequestOperationManager *manager =
[AFHTTPRequestOperationManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager.requestSerializer
setAuthorizationHeaderFieldWithUsername:#"XXXX"
password:#"XXXX"];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
AFHTTPRequestOperation *operation =
[manager GET:#"https:/xxxxxxxxxxmobile/mobilede.nsf/"
#"restContacts.xsp/Contacts?OpenWebService"
parameters:[self jsonDict]
success:^(AFHTTPRequestOperation *operation,
id responseObject) { NSLog(#"Success"); }
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Failure");
;
}];
[operation start];

Related

How to send query from iOS to PHP code

I am kinda new to Obj-C and Stack Overflow, so bear with me here (:D). I newly found out how to send queries from PHP to the MySQL database, but I'm not really sure how to send the query from my iOS app to PHP. Any help would be much appreciated. Thanks.
We don't pass queries from objective C to PHP. What we do is pass data to the server and let the server process the data and respond accordingly.
JSON is popular method to exchange data between server and a mobile device.
For example: You want to get all the fields of the database which has column name, address , contact of table person. You can't do direct database query from the device. like SELECT * from person;.
What we do is send HTTP request to an API like e.g getPersonDetails.php.
Now it's server's responsibility to verify an authorized app is sending HTTP request to it. And after verification it will respond back the data to the application in JSON format or could be XML whatever you feel comfortable. JSON is the preferred way though.
The server response would be this in JSON format:
[
{
name:John,
address:US,
contact:1234
},
{
name:David,
address:UK,
contact:1234
}
]
Now after app receives this JSON object and it needs to decode the JSON into the the suitable form.
Refer to documentation of AFNetworking here:
https://github.com/AFNetworking/AFNetworking
AFNetworking is a popular library for making HTTP request to the server for Objective-C.
Addition 1:
HTTP POST Request from iOS application in Objective C using AFNetworking:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = #{#"name": #"Andy",
#"address": #"UK",
#"contact": #"1234",};
[manager POST:#"http://example.com/addToDataBase.php" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
Server side code to handle the POST request
http://example.com/addToDataBase.php
<?php
header('Content-type: application/JSON');
$name = $_POST['name'];
$address = $_POST['address'];
$contact = $_POST['contact'];
$mysqli = new mysqli('localhost', 'my_user', 'my_password', 'world');
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$stmt = $mysqli->prepare("INSERT INTO person VALUES (?, ?, ?)");
$stmt->bind_param('sssd', $name, $address, $contact);
$stmt->execute();
$stmt->close();
$mysqli->close();
$result = array( "result" => "Successfully Inserted Data");
$output= json_encode($result);
echo $output;
?>
have IOS output something like:
$run_var = '$varName="variable value"';
then run it through eval like so
eval($run_var);
see for referencehttp://php.net/manual/en/function.eval.php

iOS NSURLSession Get Request JSON always showing outdated data

I have the following doubts about the JSON data returned from using both "GET" versus "POST" request. In the following URL JSON DATA, the data is not always updated based on the server changes (eg: database). For example, if I delete all the suggestion records from the database when I had 3 previously, it still returns 3 suggestion records in my JSON response body when I call dataTaskWithRequest.
However, if I change to POST, then the JSON response body will always be updated with the actual records from the server. In my server code (Using CakePHP), I did not check for post or get data. Actually, it was intended to be a GET method, but for some reason, only POST method seems to always fetch the most up to date data from JSON as opposed to GET.
Below is my code from my iOS client, but I'm not too sure if its very useful. I was wondering if there is a cache issue for GET request as opposed to POST request? However, I tried disabling cache for NSURLSessionConfig but it had no impact.
config.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
The code base is below:
NSString *requestString = [NSString stringWithFormat:#"%#/v/%#.json", hostName, apptIDHash];
NSURL *url = [NSURL URLWithString:requestString];
NSMutableURLRequest *req = [[NSMutableURLRequest alloc] initWithURL:url];
NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:req completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
if (!error) {
NSHTTPURLResponse *httpResp = (NSHTTPURLResponse*) response;
if (httpResp.statusCode == 200) {
NSError *jsonError;
NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&jsonError];
[self printJSONOutputFromDictionary:jsonObject];
if (!jsonError) {
block(jsonObject, nil);
}
else{
block(nil, jsonError);
}
}
else{
NSError *statusError = [self createServerUnavailableNSError:httpResp];
block(nil, statusError);
}
}
else{
block(nil, error);
}
}];
[dataTask resume];
In the above code fragment, the JSON body is always showing outdated data.
I really want to understand the issue, and would really appreciate if anyone could explain this issue for me.
Try adding the following request header:
[req addRequestHeader:#"Cache-Control" value:#"no-cache"];
I encountered the same problem as you and adding the above code solved the problem for me.
Taken from ASIHTTPRequest seems to cache JSON data always

NSURLConnection error. Works on iOS not on OSX

I have a connection issue that I am unsure how to resolve. I have combed through the documentation for the Errors and for NSURLConnection. This is code that I am using in my iOS version of the same app. It works fine there, but when I brought it to the OS X version of the app, it doesn't work. This is the code:
NSURL* url = [NSURL URLWithString:#"url"];
NSString* data = [NSString stringWithFormat:#"command=retrieve&number=%d", number];
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:[data dataUsingEncoding:NSUTF8StringEncoding]];
NSLog(#"Starting Command");
NSOperationQueue* queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSLog([NSString stringWithFormat:#"%#",connectionError]);
if ([data length] > 0 && connectionError == nil) {
dispatch_async(dispatch_get_main_queue(), ^{
[self parseResponseFromCommandRequest:data];
});
}
}];
NSLog(#"Ending Command");
The error occurs in the NSURLConnection. The output is:
Error Domain=NSPOSIXErrorDomain Code=1 "The operation couldn’t be completed. Operation not permitted" UserInfo=0x610000279dc0 {NSErrorFailingURLStringKey=url, NSErrorFailingURLKey=url}
url is actually a functioning url, but I replaced it here. Like I said, it works fine on iOS, but not on OS X. Is there a Library that I could be missing that is causing this? Any other ideas?
It could be just a matter of setting up the entitlements to allow access. It looks from the error that it fails because it's not permitted, which would indicate the app sandbox is doing it's job. For NSURL you would normally use bookmarks.app-scope or bookmarks.document-scope.
See: Enabling Security-Scoped Bookmark and URL Access
Depending on how your app is using the NSURL, network entitlements may be worth looking into:
com.apple.security.network.server = Allow Incoming Connections
com.apple.security.network.client = Allow Outgoing Connections

RestKit with my JSON data is not working

I'm trying to understand the restkit 0.22. I got some tutorials from different blogs and youtubes. I ended up with mixed up code.
Could anyone please help me with this, I really need it to work for my project.
I created Core Data Model with entities Songs.xcdatamodeld
I have a json that comes from my mySQL db:
[{"SongID":"1","SongTitle":"Song1","PerformerName":"Performer1","SongURL":"http://mysite/mysongs/1.mp3","PerformerPic":"PerfPic1.png"},
{"SongID":"2","SongTitle":"Song2","PerformerName":"Performer2","SongURL":"http://mysite/mysongs/2.mp3","PerformerPic":"PerfPic2.png"},
{"SongID":"3","SongTitle":"Song3","PerformerName":"Performer3","SongURL":"http://mysite/mysongs/3.mp3","PerformerPic":"PerfPic3.png"}]
in AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:http://mysite]];
NSURL *modelURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"Songs" ofType:#"momd"]];
//Initialize managed object store
NSManagedObjectModel *managedObjectModel = [[[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL ] mutableCopy];
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
objectManager.managedObjectStore = managedObjectStore;
[RKObjectManager sharedManager].requestSerializationMIMEType = RKMIMETypeJSON;
[RKMIMETypeSerialization registeredMIMETypes];
[objectManager setAcceptHeaderWithMIMEType:#"application/json"];
RKEntityMapping* mapping = [RKEntityMapping mappingForEntityForName:#"Songs"
inManagedObjectStore:[RKObjectManager sharedManager].managedObjectStore];
mapping.identificationAttributes = #[#"songID"];
[mapping addAttributeMappingsFromDictionary:#{#"id" : #"SongID",
#"songTitle" : #"SongTitle",
#"performerName" : #"PerformerName",
#"songURL" : #"SongURL",
#"performerPic" : #"PerformerPic"}];
return YES;
}
in TableView Controller:
- (void)viewDidLoad
{
[super viewDidLoad];
[RKObjectManager.sharedManager getObjectsAtPath:#"/api.php"
parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult)
{
self.Songs = [mappingResult array];
NSLog(#"It Worked: %#", self.Songs);
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"It Failed: %#", error);
}];
}
This is the error I'm getting:
GET 'http://mysite/api.php' (200 OK / 0 objects) [request=3.5566s mapping=0.0000s
total=3.5627s]: Error Domain=org.restkit.RestKit.ErrorDomain Code=1001
"No response descriptors match the response loaded." UserInfo=0xb5920b0
{NSErrorFailingURLStringKey=http://mysite/api.php, NSLocalizedFailureReason=A 200
response was loaded from the URL 'http://mysite/api.php', which failed to match all (0)
response descriptors:, NSLocalizedDescription=No response descriptors match the response
loaded., keyPath=null, NSErrorFailingURLKey=http://mysite/api.php,
NSUnderlyingError=0xb5921b0 "No mappable object representations were found at the key
paths searched."}
First, you don't seem to be creating the managed object contexts as part of your setup code. This will likely cause you issues after you fix your 'main' issue:
Your main issue is quite clearly described in the error message:
which failed to match all (0) response descriptors
I.e. You haven't created any response descriptors.
The Object-mapping guide walks you through the mapping and descriptor creation process (and includes lots more details to boot).
Start with something like:
RKResponseDescriptor *rd = [RKResponseDescriptor responseDescriptorWithMapping:mapping pathPattern:nil keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
then add the mapping to the object manager.
(ensure you're calling createManagedObjectContexts somewhere).

I'm making an IOS application, how do I make the application send me the UDID of the device its on?

Im currently developing and IOS application, For security purposes I would like to know how I can make the app send the device "UDID" to a server.
So basically I need to know how to make the device "fetch" the udid and then take the udid and send it to a server as a "request".
If the UDID is "registered" in the MYSQL database, then the server will send back a confirmation.
Besides finding out how to get the udid, I may need additional help setting up the mysql database :$
Thanks!
You can get the UUID of an iOS device using: CFUUIDRef udid = CFUUIDCreate(NULL);
NSString *udidString = (NSString *) CFUUIDCreateString(NULL, udid);
(Apple dont like you to use the UDID).
As far as posting it to a server, I suggest using a JSON post method, and recording the success. A good JSON library is SBJson which can be found here. Youll need to create a HTTP post, get the response data, and use SBJson library to parse the response.
EDIT: OR instead of SBJson, as Carbonic acid kindly pointed out, you can use NSJSONSerialization. Also, as pointed out by Naz Mir, new UUID method used.
Edit:
[[[UIDevice currentDevice] identifierForVendor] UUIDString] is not deprecated as I stated. Please go through the links below for information.
Getting UDID as stated above NSString *uuididentifier = [[[UIDevice currentDevice] identifierForVendor] UUIDString]; is deprecated and Apple no longer allows it. If your aim is to uniquely identify a device you can use SecureUDID or OpenUDID
I have used OpenUDID sometime back in one of our apps and using it is as simple as -
#import "OpenUDID.h"
[OpenUDID setOptOut:NO];
self.openUDID = [OpenUDID value];
Once you have the required value sending it to the server is trivial. You can use iOS networking library like AFNetworking to send and receive data. For example,
#import "AFHTTPRequestOperation.h"
NSURL *url = [NSURL URLWithString:#"Your sever URL"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSString *postString = [NSString stringWithFormat:#"&UDID=%#", self.
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPMethod:#"POST"];
AFHTTPRequestOperation *httpOperation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[httpOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *httpOperation, id responseObject) {
//handle server response here
NSLog(#"%#", [httpOperation responseString]); //this contains the servers response
}failure:^(AFHTTPRequestOperation *httpOperation, NSError *error) {
//handle server errors here
NSLog(#"error: %#", [httpOperation error]);
}];