I am using the exported API Gateway IOS SDK. The API was originally imported to the API Gateway via Swagger as a template, but since modified with the AWS portal to map back to the response model and class within the IOS SDK. All 200 requests are returned with no issue. I am using pod 'AWSAPIGateway', '= 2.4.1'
The issue i am having is nothing else other then 200 response is handled and/or received by the IOS SDK. I know it is sent because Cloudwatch shows the correct mapping, but nothing is returned in the IOS App.
At first i thought maybe i was conflicting with the API Gateway's own response codes so i switched to 403 which wasn't on it list. But that didn't work. I am also not getting 500 response errors.
Here is the calling function:
client.apiRequestPut(apiRequestVar).continueWithSuccessBlock {
(task: AWSTask!) -> AnyObject! in
print(task)
if ((task.error) != nil) {
print(task.error)
return nil;
}
if( (task.result != nil)) {
print(task.result)
}
}
return nil
}
And the AWS SDK Generated Client Function:
- (AWSTask *)apiRequestPut:(APINewRequest *)body {
NSDictionary *headerParameters = #{
#"Content-Type": #"application/json",
#"Accept": #"application/json",
};
NSDictionary *queryParameters = #{
};
NSDictionary *pathParameters = #{
};
return [self invokeHTTPRequest:#"PUT"
URLString:#"/requestVariable"
pathParameters:pathParameters
queryParameters:queryParameters
headerParameters:headerParameters
body:body
responseClass:[APIModel class]];
}
}
Here is the Error Model:
#implementation APIErrorModel
+ (NSDictionary *)JSONKeyPathsByPropertyKey {
return #{
#"success": #"success",
#"theFunction": #"theFunction",
#"action": #"action",
#"timeStamp": #"timeStamp",
#"error": #"error",
#"data": #"data"
};
}
+ (NSValueTransformer *)timeStampJSONTransformer {
return [AWSMTLValueTransformer reversibleTransformerWithForwardBlock:^id(NSString *dateString) {
return [NSDate aws_dateFromString:dateString format:AWSDateISO8601DateFormat1];
} reverseBlock:^id(NSDate *date) {
return [date aws_stringValue:AWSDateISO8601DateFormat1];
}];
}
Here is the mapping in the API Gateway for 400 response code:
#set($inputRoot = $input.path('$'))
{
"success" : $input.json('$.success'),
"theFunction" : "foo",
"action" : "foo",
"timeStamp" : "foo",
"error" : "foo",
"data" : $input.json('$.message')
}
Here is the resulting Cloudwatch log entry:
Endpoint response body before transformations:
{
"success": false,
"message": "{\"message\":\"The conditional request failed\",\"code\":\"ConditionalCheckFailedException\",\"time\":\"2016-05- 12T20:16:03.165Z\",\"statusCode\":400,\"retryable\":false,\"retryDelay\":0} "
}
Endpoint response headers: {content-length=217, Connection=keep-alive, content-type=application/json; charset=utf-8, cache-control=no-cache, Date=Thu, 12 May 2016 20:16:03 GMT
}
Method response body after transformations:
{
"success": false,
"theFunction": "foo",
"action": "foo",
"timeStamp": "foo",
"error": "foo",
"data": "{\"message\":\"The conditional request failed\",\"code\":\"ConditionalCheckFailedException\",\"time\":\"2016-05- 12T20:16:03.165Z\",\"statusCode\":400,\"retryable\":false,\"retryDelay\":0} "
}
Method response headers: {Content-Type=application/json}
Successfully completed execution
Method completed with status: 400
But then i get nothing received back in the iOS app?
Any help to what i am missing would be much appreciated!
- continueWithSuccessBlock: is used when you want to extract only the result from the task object. The task object in - continueWithSuccessBlock: always has the nil error property. If you want to receive errors, you need to use - continueWithBlock: instead.
See the Bolts documentation for more details.
Related
I'm trying to add a sharing feature to my existing app using Unity Branch SDK.
I created the short URL using the following code.
BranchUniversalObject universalObject = new BranchUniversalObject();
BranchLinkProperties linkProperties = new BranchLinkProperties();
string deviceUniqueIdentifier = SystemInfo.deviceUniqueIdentifier;
universalObject.canonicalIdentifier = $"xLeague/{deviceUniqueIdentifier}";
universalObject.canonicalUrl = "http://xleague.games/";
universalObject.title = MetaDataManager.Title;
universalObject.contentDescription = MetaDataManager.Description;
universalObject.imageUrl = MetaDataManager.Image;
linkProperties.controlParams.Add("$desktop_url", "http://xleague.games/xleague-solitaire-share/");
linkProperties.controlParams.Add("$android_url", "http://xleague.games/android");
linkProperties.controlParams.Add("$ios_url", "https://apps.apple.com/us/app/xleague-solitaire/id1480117114");
linkProperties.controlParams.Add("$ipad_url", "https://apps.apple.com/us/app/xleague-solitaire/id1480117114");
linkProperties.controlParams.Add("$match_duration", "2000");
linkProperties.controlParams.Add("$og_title", MetaDataManager.Title);
linkProperties.controlParams.Add("$og_description", MetaDataManager.Description);
linkProperties.controlParams.Add("$og_image_url", MetaDataManager.Image);
linkProperties.controlParams.Add("$deviceID", deviceUniqueIdentifier);
Branch.getShortURL(universalObject, linkProperties, (param, error) =>
{
if (error != null)
{
Debug.LogError("Branch.getShortURL failed: " + error);
}
else if (param != null)
{
callback(param);
}
});
I can get the following short URLs from Unity Branch.
https://xleague.app.link/r7DxT2wkZ5
https://xleague.app.link/4WPwY7jm05
https://xleague.app.link/LFfAOZuo05
https://xleague.app.link/hVR3fr0n05
And I retrieve BranchUniversalObject and BranchLinkProperties using the following code.
void Start()
{
Branch.initSession(CallbackWithBranchUniversalObject);
}
void CallbackWithBranchUniversalObject(BranchUniversalObject buo, BranchLinkProperties linkProps, string error)
{
if (error != null)
Debug.Log($"Error : {error}");
else
{
Debug.Log(buo.ToJsonString());
Debug.Log(linkProps.ToJsonString());
if (linkProps.controlParams.ContainsKey("$deviceID"))
{
string senderDeviceID = linkProps.controlParams["$deviceID"];
...
}
}
}
If I click the shared link on iPhone or Android, it will redirect me to Appstore or Google Play Store. I can install the app on the Appstore and Google Play Store.
But when I opened the app, initSession returns empty BranchUniversalObject JSON and BranchLinkProperties JSON.
BranchUniversalObject JSON
{
"$canonical_identifier": "",
"$canonical_url": "",
"$og_title": "",
"$og_description": "",
"$og_image_url": "",
"$publicly_indexable": "0",
"$locally_indexable": "0",
"$exp_date": "69425078400000",
"$keywords": [],
"metadata": "{}"
}
BranchLinkProperties JSON
{
"~tags": [],
"~feature": "",
"~alias": "",
"~channel": "",
"~stage": "",
"~duration": "0",
"control_params": {}
}
What makes me more confused is that initSession sometimes returns correct BranchUniversalObject JSON and BranchLinkProperties JSON as expected. I guess the Branch Short URL that I created only works for the first click.
I'd be much appreciated you if you could help me.
A Branchster Here -
Please double check your integration as mentioned here. For further troubleshooting you can also follow as mentioned here. If this is happening when you click a link from background please make sure that you are following the intra-app linking guidelines and make sure onNewIntent is implemented as recommended.
Please note thaT when a link is clicked, it should only open the Activity which has the initSession() method. Also please don't share your Branch Keys publicly.
We have an app where we are using social media share with Linkedin, earlier the app was using v1 Api and post share was working fine, but now all of the sudden it has stopped working. I checked on google seems like v1 Apis are now deprecated, so I tried using v2 api's. But now I am getting below error-:
Domain=com.alamofire.error.serialization.response Code=-1011 "Request
failed: forbidden (403)" UserInfo={NSLocalizedDescription=Request
failed: forbidden (403)
Below is the code where I am passing access permissions and all other parameters for getting access token.
- (LIALinkedInHttpClient *)client {
UIViewController *top = [UIApplication sharedApplication].keyWindow.rootViewController;
// [top presentViewController:secondView animated:YES completion: nil];
LIALinkedInApplication *application = [LIALinkedInApplication applicationWithRedirectURL:#"https://com.xxxxxx.linkedin.oauth/oauth"
clientId:#"xxxxxxxxx"
clientSecret:#"xxxxxxxx"
state:#"xxxxxxxxx"
grantedAccess:#[#"w_member_social"]];
return [LIALinkedInHttpClient clientForApplication:application presentingViewController:top.presentedViewController]; //[LIALinkedInHttpClient clientForApplication:application];
}
v2 URL - : https://www.linkedin.com/oauth/v2/shared?/accessToken, here accessToken is the valid token value which is appended to the URL, when I check the value in console.
I am not getting how to make a valid request with v2 Api's, or if there are more parameters that we need to pass for new Api's, can anyone help me on this? Thanks in advance.
Kindly let me know if any other information is required.
According to LinkedIn Share API v2.0, your HTTP call should be looked like this:
POST https://api.linkedin.com/v2/shares
json:
{
"content": {
"contentEntities": [
{
"entityLocation": "https://www.example.com/content.html",
"thumbnails": [
{
"resolvedUrl": "https://www.example.com/image.jpg"
}
]
}
],
"title": "Test Share with Content"
},
"distribution": {
"linkedInDistributionTarget": {}
},
"owner": "urn:li:person:324_kGGaLE",
"subject": "Test Share Subject",
"text": {
"text": "Test Share!"
}
}
GET /drives/{drive-id}/items/{item-id}/analytics
refrence: https://learn.microsoft.com/en-us/graph/api/itemanalytics-get?view=graph-rest-beta
On trying to call this endpoint, it is returning empty as response with 200 status code.
As per documentation, it should have return something like
{
"allTime": {
"access": {
"actionCount": 123,
"actorCount": 89
}
},
"lastSevenDays": {
"access": {
"actionCount": 52,
"actorCount": 41
}
}
}
request-id: 67aa7bd8-6bd3-40c0-8f12-a1c4cabda4af
Try adding /lastSevenDays or /AllTime to it and it should return the data.
GET /drives/{drive-id}/items/{item-id}/analytics/lastSevenDays
GET /drives/{drive-id}/items/{item-id}/analytics/allTime
This is still an issue and now that endpoint is under the 1.0 ref (not beta any more)
I have a very hard time figuring out how to do this from the iOS app programmatically.
Im using (besides other) the following classes from github:
https://github.com/hybrdthry911/ELStripe
Class: ELCharge.m
+(ELCharge *)charge{
return [[ELCharge alloc]init];
}
(*****************code in between ************************)
//Will attempt to charge either a customer or card. Exactly one must exist
per charge. If multiple or neither exist an exception will be raised.
//Warning: This is the final step it will APPLY A CHARGE TO THE
ACCOUNT.
-(void)createChargeWithCompletion:(ELChargeCompletionBlock)handler{
[ELCharge createCharge:self completion:handler];
}
+(void)createCharge:(ELCharge *)charge completion
(ELChargeCompletionBlock)handler{
NSError *chargeError;
if (![charge validForProcessingWithError:&chargeError]) {
handler(nil,chargeError);
return;
}
if (!chargeError) {
[ELStripe executeStripeCloudCodeWithMethod:#"POST"
prefix:#"charges" parameters:[ELCharge
dictionaryForCreatingCharge:charge] completionHandler:^(id
jsonObject, NSError *error) {
handler([ELCharge
chargeFromParseStripeDictionary:jsonObject],error);
}];
}
}
In the iOS class, I do the following in order to create a test charge:
//create an automatic charge in stripe from an existing customer with card
attached to him
-(void) executeChargeInStripe:(UIButton*)sender
{
ELCharge *charge = [ELCharge charge];
//Assign the charge properties
charge.customerID = #"cus_72xvQI6Q5IC9it";
charge.currency = #"USD";
NSNumber *chargeAmount = [NSNumber numberWithInt:111];
charge.amountInCents = chargeAmount;
//Call ChargeMethod from Github Framework
[ELCharge createCharge:charge completion:^(ELCharge *charge, NSError
*error) {
if (!error) {
//code for normal handling
NSLog(#"Charge has been made successfully");
} else {
// error code handling
NSLog(#"Charge NOT made");
}
}];
}
Im passing this to the following clould code:
Parse.Cloud.define("stripeHTTPRequest", function(request, response)
{
//Check for valid pre/suf/postfixes, if they are not there do not include
them.
var prefix = request.params["prefix"];
var suffix = "";
var postfix = "";
var secondPostfix = "";
if (!isEmpty(request.params["suffix"])) suffix =
'/'+request.params['suffix'];
if (!isEmpty(request.params["postfix"])) postfix =
'/'+request.params['postfix'];
if (!isEmpty(request.params["secondPostfix"])) secondPostfix =
'/'+request.params['secondPostfix'];
//call from parse to stripe done by http request as parse/stripe api
uncomplete
Parse.Cloud.httpRequest(
{
method: request.params["method"],
//Create URL from base url and pre/suf/postfixes
url: 'https://'+STRIPE_API_BASE_URL + prefix + suffix + postfix +
secondPostfix,
headers: {
'Authorization': "Bearer " + STRIPE_SECRET_KEY
},
params:request.params["params"],
success: function(httpResponse)
{
//response text is a json dictionary
response.success(httpResponse.text);
},
error: function(httpResponse)
{
response.error(httpResponse.text);
}
});
});
Im now getting the following error:
Charge NOT made (my error message from the IOS class I created).
Im really surprised that I recieve neither an error in Parse Cloud nor in Stripe.
If for example, I use an already used token instead of the customerID, I have an error in both. So the connection seems to work I assume, maybe there is something which I do wrong in the iOS class.
Thank you!
have you reverted your Parse JavaScript SDK to 1.5.0? Anything past 1.5.0 is no longer supported.
When I use the following query, I get a good response (with only the first 5 days of May, so apparently the default is not 'This Fiscal Year-to-date' as the documentation suggests, but I digress):
https://quickbooks.api.intuit.com/v3/company/0123456789/reports/CustomerSales
When I add parameters, I get an oauth exception. For example:
https://quickbooks.api.intuit.com/v3/company/0123456789/reports/CustomerSales?start_date='2013-01-01'&end_date='2014-05-06'
Gives me this:
{
"Fault": {
"type": "AUTHENTICATION",
"Error": [
{
"Message": "message=Exception authenticating OAuth; errorCode=003200; statusCode=401",
"code": "3200"
}
]
},
"requestId": "[redacted]",
"time": "[redacted]"
}
This gives me the same result:
https://quickbooks.api.intuit.com/v3/company/0123456789/reports/CustomerSales?date_macro='This Fiscal Year'
So does this:
https://quickbooks.api.intuit.com/v3/company/148305798/reports/CustomerSales?accounting_method='Accrual'
I figure I'm missing something small. I'm not changing any of the headers or any of the other request details...just the url.
I tried without the single quotes around the dates and other params too.
What am I breaking?
Are you including the data to the right of the ? in the URL in the "base" string and are you sorting it with the other parameters?
I've tried this report using java devkit.
It worked fine for me. PFB details.
Request URI - https://quickbooks.api.intuit.com/v3/company/1092175540/reports/CustomerSales?accounting_method=Accrual&start_date=2014-01-01&requestid=61234ddb7e14ce2a5fe4e2f0318b31c&minorversion=1&
My test company file is empty.. That's why got the following JSON response.
{
"Header":{
"Time":"2014-05-06T20:42:08.783-07:00",
"ReportName":"CustomerSales",
"ReportBasis":"Accrual",
"StartPeriod":"2014-05-01",
"EndPeriod":"2014-05-06",
"SummarizeColumnsBy":"Total",
"Currency":"USD"
},
"Columns":{
"Column":[
{
"ColTitle":"",
"ColType":"Customer"
}
]
},
"Rows":{
"Row":[
{
"ColData":[
{
"value":"TOTAL"
}
],
"group":"GrandTotal"
}
]
}
}
JAVA code
void testCustomerSalesReport(Context context) {
Config.setProperty(Config.SERIALIZATION_RESPONSE_FORMAT, "json");
ReportService service = new ReportService(context);
service.setStart_date("2014-01-01");
service.setAccounting_method("Accrual");
Report report = null;
try {
report = service.executeReport(ReportName.CUSTOMERSALES.toString());
} catch (FMSException e) {
e.printStackTrace();
}
}
API Doc Ref - https://developer.intuit.com/docs/0025_quickbooksapi/0050_data_services/reports/customersales
Hope it will be useful.
Thanks