I am working on a Mac app in objective-c which will use the eBay API to access the eBay functionality, including trading. I have successfully retrieved items and categories, but for trading, I need the session ID and token, which I have not been able to do.
I have made many changes after reading various posts and the documentation, but always get this error after responding to the challenge:
error: Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo={NSUnderlyingError=0x6080000585a0 {Error Domain=kCFErrorDomainCFNetwork Code=-1005 "(null)" UserInfo={_kCFStreamErrorCodeKey=-4, _kCFStreamErrorDomainKey=4}}, NSErrorFailingURLStringKey=https://api.sandbox.ebay.com/ws/api.dll, NSErrorFailingURLKey=https://api.sandbox.ebay.com/ws/api.dll, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-4, NSLocalizedDescription=The network connection was lost.}
After making the call, I get the challenge callback and handle it here:
- (void)URLSession:(NSURLSession *)session
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition,
NSURLCredential *credential))completionHandler{
NSLog(#"didReceiveChallenge: %#", challenge);
NSURLCredential* credential = [NSURLCredential credentialWithUser:sandBoxUserID password:sandBoxPassword persistence:NSURLCredentialPersistenceForSession];
completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
}
The call for the session ID is here:
-(void) retrieveSessionID{
// retrieve a session ID for this user for this app
// headers for auth
NSURLSessionConfiguration* configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration];
NSMutableString* urlString = [[NSMutableString alloc]initWithCapacity:200];
[urlString appendString:sandBoxEndPoint];
NSString* callname = #"GetSessionID";
NSString* version = #"768";
NSString* contentType = #"text/xml";
NSString* siteID = #"0";
NSMutableDictionary* headersDictionary = [[NSMutableDictionary alloc]initWithCapacity:10];
[headersDictionary setObject:contentType forKey:#"Content-Type"];
[headersDictionary setObject:sandBoxAppID forKey:#"X-EBAY-API-APP-NAME"];
[headersDictionary setObject:devID forKey:#"X-EBAY-API-DEV-NAME"];
[headersDictionary setObject:sandBoxCertID forKey:#"X-EBAY-API-CERT-NAME"];
[headersDictionary setObject:callname forKey:#"X-EBAY-API-CALL-NAME"];
[headersDictionary setObject:version forKey:#"X-EBAY-API-COMPATIBILITY-LEVEL"];
[headersDictionary setObject:siteID forKey:#"X-EBAY-API-SITEID"];
configuration.HTTPAdditionalHeaders = headersDictionary;
NSLog(#"configuration.HTTPAdditionalHeaders: %#", configuration.HTTPAdditionalHeaders);
NSLog(#"urlString: %#", urlString);
NSURL *eBayUrl = [NSURL URLWithString:urlString];
NSLog(#"eBayUrl: %#", eBayUrl);
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:eBayUrl];
request.HTTPMethod = #"GET";
NSXMLElement *root = [[NSXMLElement alloc] initWithName:#"GetSessionIDRequest"];
[root addAttribute:[NSXMLNode attributeWithName:#"xmnls" stringValue:#"urn:ebay:apis:eBLBaseComponents"]];
NSXMLElement *childElement1 = [[NSXMLElement alloc] initWithName:#"RuName"];
childElement1.stringValue = sandBoxRuName;
[root addChild:childElement1];
NSXMLDocument *xmlRequest = [NSXMLDocument documentWithRootElement:root];
NSData* xmlRequestAsData = [xmlRequest XMLData];
request.HTTPBody = xmlRequestAsData;
NSURLSessionDataTask* dataTask = [session dataTaskWithRequest:request
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error) {
NSLog(#"error: %#", error);
NSLog(#"response: %#", response);
self.sessionIDRequestXMLstring = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"self.sessionIDRequestXMLstring: %#", self.sessionIDRequestXMLstring);
[self.delegate receivedSessionIDRequestXMLstring:self.sessionIDRequestXMLstring];
}
];
[dataTask resume];
}
I apologize for the formatting here, but I haven't quite figured out how to use it correctly.
Related
i'm hiting an API in postman there i get result fine, this how i'm making POST request in postman,
But when i hit same API in my application using objective c, i got errors, i'm passing parameters fine but result is not coming true, i'm confuse that why it is not showing results true, This is my code for POST request,
- (void)sendRequest
{
NSArray *userArray = [NSArray arrayWithObjects: #"ishaqshafiq#hotmail.com",nil];
NSDictionary *emp = #{#"lstUsers": userArray,
#"message":#"Your Order is Booked",
#"data": #{
#"type":#"text",
}};
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: nil delegateQueue: [NSOperationQueue mainQueue]];
NSString *urlLinkA=#"http://sajjenweb.azurewebsites.net/api/HubConnection/PostMobileNotification";
NSURL * url = [NSURL URLWithString:urlLinkA];
NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:url];
NSString *parameters = [NSString stringWithFormat:#"%#",emp];
NSLog(#"parameter %#",parameters);
[urlRequest setHTTPMethod:#"POST"];
//[urlRequest setHTTPBody:[parameters dataUsingEncoding:NSUTF8StringEncoding]];
NSURLSessionDataTask * dataTask =[defaultSession dataTaskWithRequest:urlRequest
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(#"Response:%# ", response);
NSLog(#"Error is %#",error);
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
// NSLog(#"DDD %#",dictionary);
NSString *res = [dictionary valueForKey:#"recipients"];
NSLog(#"RR: %#", res);
NSString *msg=#"Successfully Submitted";
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Success"
message:msg
preferredStyle:UIAlertControllerStyleAlert];
int duration = 2; // duration in seconds
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, duration * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[alert dismissViewControllerAnimated:YES completion:nil];
});
}];
NSLog(#"network error :");
[dataTask resume];
}
I come from a Swift background; therefore, am used to Alamofire. I am trying to learn Objective-C and have been plying with AFNetworking.
The following is a simple method that calls the Yelp search API to find business in the vicinity.
- (void) getBusinesses: (NSString *) usingToken{
NSString *starbucks = #"Starbucks";
NSString *latitude = #""; //enter latitude
NSString *longitude = #""; //enter longitude
NSString *URLString = [NSString stringWithFormat:#"https://api.yelp.com/v3/businesses/search?term=%#&latitude=%#&longitude=%#", starbucks, latitude, longitude];
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
AFHTTPRequestSerializer *request = [[AFHTTPRequestSerializer alloc] requestWithMethod:#"GET" URLString:URLString parameters:nil error:nil];
NSString *bearerToken = [NSString stringWithFormat: #"Bearer %#", usingToken];
[request setValue: bearerToken forHTTPHeaderField:#"Authorization"];
NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error){
if (error){
NSLog(#"*** Failed!");
} else {
NSLog(#"*** Succeeded!");
}
}];
dataTask.resume;
}
When running this code I get the following error:
Incorrect NSStringEncoding value 0x0000 detected. Assuming NSASCIIStringEncoding. Will stop this compatibility mapping behavior in the near future.
I have tested the above Yelp URL with my valid access token on Postman and it works perfectly.
If someone could point me in the right direction to figure out what is going on I'd appreciate it!
P.S. this is the documentation for the Yelp search endpoint
I know this question was answered multiple times, but I tried all the answers with no luck. I don't think that I do something fundamentally wrong but something goes definitely wrong here.
I use the following code to upload PNG files to tinypng.com. As far as I can see the upload itself works, but I receive the error message: Request failed: unsupported media type (415)
The images I use are loaded as JPEG, then resized and transformed to PNG format. The saved files are fine. Now I want send them to the TinyPNG API before I save them to disc.
If anyone has an idea whats wrong or has experience with that service, please let me know.
Thanks in advance!
Detailed error message
Error Domain=com.alamofire.error.serialization.response Code=-1011 "Request failed: unsupported media type (415)"
UserInfo=0x6000000e4900 {
com.alamofire.serialization.response.error.response=<NSHTTPURLResponse: 0x600000220200> { URL: https://api.tinypng.com/shrink }
{
status code: 415, headers {
Connection = "keep-alive";
"Content-Length" = 77;
"Content-Type" = "application/json; charset=utf-8";
Date = "Tue, 16 Dec 2014 20:24:16 GMT";
Server = "Apache/2";
"Strict-Transport-Security" = "max-age=31536000";
"X-Powered-By" = "Voormedia (voormedia.com/jobs)";
}
},
NSErrorFailingURLKey=https://api.tinypng.com/shrink,
com.alamofire.serialization.response.error.data=<7b226572 726f7222 3a224261 64536967 6e617475
7265222c 226d6573 73616765 223a2244 6f657320 6e6f7420 61707065 61722074 6f206265 20612050
4e47206f 72204a50 45472066 696c6522 7d>,
NSLocalizedDescription=Request failed: unsupported media type (415)
}
The code I use
-(void) uploadImage:(NSImage *)image {
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:TINY_PNG_URL]];
CGImageRef cgRef = [image CGImageForProposedRect:NULL
context:nil
hints:nil];
NSBitmapImageRep *newRep = [[NSBitmapImageRep alloc] initWithCGImage:cgRef];
[newRep setSize:[image size]]; // if you want the same resolution
NSData *imageData = [newRep representationUsingType:NSPNGFileType properties:nil];
NSDictionary *parameters = #{#"username": USERNAME, #"password" : PASSWORD};
AFHTTPRequestOperation *operation = [manager POST:#"" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
//append image
[formData appendPartWithFileData:imageData
name:#"filename"
fileName:#"photo.png"
mimeType:#"image/png"];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Success: %# ***** %#", operation.responseString, responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %# ***** %#", operation.responseString, error);
}];
[operation start];
}
With the support of Mattijs from TinyPNG I've got it working! Thanks Mattijs!
The problem was, that the TinyPNG API expects the request body to only be the image data, which isn't the case with the multipart form data body I used in my original code.
My working solution is:
-(void) uploadImage:(NSImage *)image {
NSData *imageData = [self PNGRepresentationOfImage:image];
NSURL *url = [NSURL URLWithString:TINY_PNG_URL];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:imageData];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"image/png" forHTTPHeaderField:#"Content-Type"];
NSString *authStr = [NSString stringWithFormat:#"%#:%#", USERNAME, PASSWORD];
NSData *authData = [authStr dataUsingEncoding:NSASCIIStringEncoding];
NSString *authValue = [NSString stringWithFormat:#"Basic %#", [authData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed]];
[request setValue:authValue forHTTPHeaderField:#"Authorization"];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id result) {
NSLog(#"Success: %# ***** %#", operation.responseString, result);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %# ***** %#", operation.responseString, error);
}];
[operation start];
}
I'm trying to submit a GET request from a web service and I want to pass a JSON argument as a parameter in the HTTP header. I have the following code that performs the get request without the JSON argument. How would I add the JSON argument in the HTTP body to pass the JSON parameter?
Heres is my code that works without the JSON argument:
-(void) getReposByDate:(void (^)(NSMutableArray *))handler
{
//Get credentials
NSDictionary *credentials = [KeychainUserPass load:#"APP NAME"];
NSString *userName = [credentials allKeys][0];
NSString *password = credentials[userName];
//Create request
NSString *requestString = #"SOME WEB SERVICE URL";
NSURL *url = [NSURL URLWithString:requestString];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
NSData *userPasswordData = [[NSString stringWithFormat:#"%#:%#", userName, password] dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64EncodedCredential = [userPasswordData base64EncodedStringWithOptions:0];
NSString *authString = [NSString stringWithFormat:#"Basic %#", base64EncodedCredential];
NSURLSessionConfiguration *sessionConfig=[NSURLSessionConfiguration defaultSessionConfiguration];
sessionConfig.HTTPAdditionalHeaders=#{#"Authorization":authString};
self.session=[NSURLSession sessionWithConfiguration:sessionConfig];
NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:req completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSMutableDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSLog(#"%#", jsonObject);
handler([jsonObject valueForKeyPath:#"name"]);
}];
[dataTask resume];
}
Most of the information here refers to the abandoned ASIHTTPREQUEST project so forgive me for asking again.
Effectively, I need to swipe a magnetic strip and send the track 2 data to a webservice that returns "enrolled" or "notenrolled" (depending on the status of the card...)
So my data comes in simply as
NSData *data = [notification object];
And then I need to pass this to a url to the order of
http://example.com/CardSwipe.cfc?method=isenrolled&track2=data
And then just receive a response string...
I've searched a ton and there seems to be some conflicting answers as to whether this should be accomplished simply with AFNetworking, RESTkit, or with the native NSURL/NSMutableURLRequest protocols.
The options for performing HTTP requests in Objective-C can be a little intimidating. One solution that has worked well for me is to use NSMutableURLRequest. An example (using ARC, so YMMV) is:
- (NSString *) getDataFrom:(NSString *)url{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setHTTPMethod:#"GET"];
[request setURL:[NSURL URLWithString:url]];
NSError *error = nil;
NSHTTPURLResponse *responseCode = nil;
NSData *oResponseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&responseCode error:&error];
if([responseCode statusCode] != 200){
NSLog(#"Error getting %#, HTTP status code %i", url, [responseCode statusCode]);
return nil;
}
return [[NSString alloc] initWithData:oResponseData encoding:NSUTF8StringEncoding];
}
Update:
Your question's title, and tagging say POST, but your example URL would indicate a GET request. In the case of a GET request, the above example is sufficient. For a POST, you'd change it up as follows:
- (NSString *) getDataFrom:(NSString *)url withBody:(NSData *)body{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:body];
[request setValue:[NSString stringWithFormat:#"%d", [body length]] forHTTPHeaderField:#"Content-Length"];
[request setURL:[NSURL URLWithString:url]];
/* the same as above from here out */
}
Update for iOS 9:
So, [NSURLConnection sendSynchronousRequest] is deprecated starting from iOS 9. Here's how to do a GET request using NSURLSession starting from iOS 9
GET Request
// making a GET request to /init
NSString *targetUrl = [NSString stringWithFormat:#"%#/init", baseUrl];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setHTTPMethod:#"GET"];
[request setURL:[NSURL URLWithString:targetUrl]];
[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:
^(NSData * _Nullable data,
NSURLResponse * _Nullable response,
NSError * _Nullable error) {
NSString *myString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Data received: %#", myString);
}] resume];
POST Request
// making a POST request to /init
NSString *targetUrl = [NSString stringWithFormat:#"%#/init", baseUrl];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
//Make an NSDictionary that would be converted to an NSData object sent over as JSON with the request body
NSDictionary *tmp = [[NSDictionary alloc] initWithObjectsAndKeys:
#"basic_attribution", #"scenario_type",
nil];
NSError *error;
NSData *postData = [NSJSONSerialization dataWithJSONObject:tmp options:0 error:&error];
[request setHTTPBody:postData];
[request setHTTPMethod:#"POST"];
[request setURL:[NSURL URLWithString:targetUrl]];
[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:
^(NSData * _Nullable data,
NSURLResponse * _Nullable response,
NSError * _Nullable error) {
NSString *responseStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Data received: %#", responseStr);
}] resume];
Tested 100% working
Only for Objective C
-(void)fetchData
{
NSURLSessionConfiguration *defaultSessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration:defaultSessionConfiguration];
// Setup the request with URL
NSURL *url = [NSURL URLWithString:#"https://test.orgorg.net/ios/getStory.php?"];
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];
// Convert POST string parameters to data using UTF8 Encoding
NSString *postParams = #"";
NSData *postData = [postParams dataUsingEncoding:NSUTF8StringEncoding];
// Convert POST string parameters to data using UTF8 Encoding
[urlRequest setHTTPMethod:#"POST"];
[urlRequest setHTTPBody:postData];
// Create dataTask
NSURLSessionDataTask *dataTask = [defaultSession dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSDictionary *results = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
//JSON Parsing....
NSString *message = results[#"Message"];
BOOL status = results[#"Status"];
if (status){
// Here you go for data....
}else{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"App"
message:message
preferredStyle:UIAlertControllerStyleAlert]; // 1
UIAlertAction *firstAction = [UIAlertAction actionWithTitle:#"Ok"
style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
NSLog(#"You pressed button one");
}]; // 2
[alert addAction:firstAction]; // 4
[self presentViewController:alert animated:YES completion:nil];
}
}];
// Fire the request
[dataTask resume];
}
For Objective c :
-(void)loadData:(NSString*)url{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:#"https://jsonplaceholder.typicode.com/posts"]];
[request setHTTPMethod:#"GET"];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
[[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSMutableArray *jsonArray = (NSMutableArray *)[NSJSONSerialization JSONObjectWithData:data options:NSASCIIStringEncoding error:&error];
if([self.delegate respondsToSelector:#selector(loadingData:)]){
[self.delegate loadingData:jsonArray];
}
}] resume];
}
Swift 5.5:
// MARK: - Posts
func getPosts(endPath : String, completion: #escaping ([Post]) -> ()) {
let urlPath = Constants.Network.BASE_URL + endPath
guard let url = URL(string: urlPath) else {
print("Invalid URL")
return
}
var request = URLRequest(url: url)
request.httpMethod = Constants.Network.HTTPS_METHOD
URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data {
if let decodedResponse = try? JSONDecoder().decode([Post].self, from: data) {
DispatchQueue.main.async {
completion(decodedResponse)
}
return
}
}
print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")")
}.resume()
}
**Simply Call and get your JSON Data.**
-(void)getJSONData
{
NSURL *url = [NSURL URLWithString:#"http://itunes.apple.com/us/rss/topaudiobooks/limit=10/json"];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *data = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSError *erro = nil;
if (data!=nil) {
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&erro ];
if (json.count > 0) {
for(int i = 0; i<10 ; i++){
[arr addObject:[[[json[#"feed"][#"entry"] objectAtIndex:i]valueForKeyPath:#"im:image"] objectAtIndex:0][#"label"]];
}
}
}
dispatch_sync(dispatch_get_main_queue(),^{
[table reloadData];
});
}];
[data resume];
}