Issue on retrieving Evernote business note attachments by using Evernote ios sdk - ios

I integrated the latest evernote ios sdk in my ios app. When i try to list/retrieve the note attachments from my business notebook (either shared or personal). The call back from evernote sdk giving the same note attachment more than once. Since the return array list has same note attachment more than once. Any idea why?.
Note: this issue happening in both shared business notebook and
personal business note book.
Any help that might be appreciated.
Here is my code:
Caller:
[SEEvernoteHelper getAttachmentsFoeNoteBook:notebook forSeatchString:#"resource:application/*" onCompletion:^(NSArray *list, NSError *error) {
if (error) {
block (nil, error);
} else {
//success
}
}
note book attachment retriever:
+ (void)getAttachmentsFoeNoteBook:(ENNotebook *)notebook forSeatchString:(NSString *)searchString onCompletion:(ZArrayResultBlock)block {
[[ENSession sharedSession] findNotesWithSearch:[ENNoteSearch noteSearchWithSearchString:searchString]
inNotebook:notebook
orScope:nil
sortOrder:ENSessionSortOrderRelevance
maxResults:0
completion:^(NSArray *findNotesResults, NSError *findNotesError) {
if (findNotesError) {
if (block) {
block(nil, findNotesError);
}
} else {
block(findNotesResults, nil);
}
}];
}

I'm the lead developer for the evernote ios sdk.
Can you file a bug on https://github.com/evernote/evernote-cloud-sdk-ios/issues and let's resolve it there?
Thanks

Related

React Native iOS Sentry - Too many arguments to block call, expected 1, have 3

Trying to build my React-Native app for iOS. Previous build was fine, but since I added Sentry for error logging, I can not build it. Linking was fine, I did it and it was successful.
I am getting this error:
Too many arguments to block call, expected 1, have 3
RNSentry.m
inside this part of code:
RCT_EXPORT_METHOD(sendEvent:(NSDictionary * _Nonnull)event
resolve:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul), ^{
if ([NSJSONSerialization isValidJSONObject:event]) {
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:event
options:0
error:nil];
SentryEvent *sentryEvent = [[SentryEvent alloc] initWithJSON:jsonData];
[SentryClient.sharedClient sendEvent:sentryEvent withCompletionHandler:^(NSError * _Nullable error) {
if (nil != error) {
reject(#"SentryReactNative", error.localizedDescription, error);
} else {
resolve(#YES);
}
}];
} else {
reject(#"SentryReactNative", #"Cannot serialize event", nil);
}
});
}
on this line:
reject(#"SentryReactNative", error.localizedDescription, error);
I am using RN version 0.59.9 and React version is 16.8.3
Tried to google if someone had similar issues but found nothing. Any help will be appreciated.
Hi i has same issues like you. After I struggled for a few days I replace it by installing it manually .This error occurs because when we install react-native-sentry through the pod we will also install the pod react too.

Google Places for iOS version 3

Today Google released version 3 of its Places API for iOS. Upgrading my project and using the new findPlaceLikelihoodsFromCurrentLocationWithPlaceFieldsmethod I get the following error:
"Pick Place error The operation couldn’t be completed. An internal
error occurred in the Places API library...."
Any ideas?
Here is my complete Objective C code:
GMSPlaceField fields = GMSPlaceFieldName;
GMSPlacesClient *placesClient;
placesClient = [GMSPlacesClient sharedClient];
[placesClient findPlaceLikelihoodsFromCurrentLocationWithPlaceFields:fields callback:^(NSArray* likelihoods, NSError* error){
if(error != nil)
{
//##
NSLog(#"Pick Place error %#", [error localizedDescription]);
return;
}
for(GMSPlaceLikelihood *likelihood in likelihoods)
{
//##
NSLog(#"likelihood.place : %#",likelihood.place.name);
}
}];
Turns out Google changed things without being terribly obvious.
In my case, I used to have the "Places SDK for iOS" restriction added on the API key, but the new stuff requires the "Places API" restriction.

Getting user infos using ObjectiveDropboxOfficial framework

I am using ObjectiveDropboxOfficial framework for Dropbox integration within Objective-C app (due to the deprecation of v1 dropbox api).
Framework link
I am trying to get logged in dropbox user info (email, name, etc). Here is my code:
DropboxClient *client=[DropboxClientsManager authorizedClient];
[[client.usersRoutes getCurrentAccount]
response:^_Nonnull(DBUSERSBasicAccount *response, DBError *dberror)
{
// loginLabel.text=[NSString stringWithFormat: #"%#\n%#", account.name, account.email];
return response;
}
}];
This code doesn't work and additionnally causes weird error from xcode: enter image description here
The method definition is:
- (DBRpcTask<DBUSERSBasicAccount *, DBUSERSGetAccountError *> *_Nonnull) getAccount:(NSString *_Nonnull)accountId;
- (DBRpcTask<TResponse, TError> *_Nonnull)response:
(void (^_Nonnull)(TResponse _Nullable, TError _Nullable,
DBError *_Nullable))responseBlock;
I was stuck with this for a whole day, any help would be appreciated:
1- How to get user infos using the framework, or
2- What is causing the error and how should that Nonnull method be called?
Thank you in advance
So finally after 2 days of struggling I found the response :
DropboxClient *client = [DropboxClientsManager authorizedClient];
if(client)
{
[[client.usersRoutes getCurrentAccount] response:^(DBUSERSFullAccount *account, DBNilObject *obj, DBError *error) {
if (error != nil) {
NSLog(#"Error %#", error.errorContent);
}
if (account != nil) {
NSLog(#"User's name %#", account.name.displayName);
}
if(self.hud)
[self.hud hideAnimated:YES];
}];
I hope this would save another developer's energy and mental health :)

Onedrive SDK - Authentication Token is getting nil value

During OneDrive Authentication using OneDrive SDK for iOS, after the authentication screen, At times, the highlighted values of “response” objects are NIL . I’m not sure why this is happening.
Out of 10 trials, 2-3 times the values inside the Repsonse object is NIL. So this is landing the App in crash.Any guess why this is happening? May be because of poor network? Or any other thing I might have missed? In Onedrive SDK - LiveAuthRequest.m file has the following lines of code.
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
id response = [LiveAuthHelper readAuthResponse:self.tokenResponseData];
if ([response isKindOfClass:[LiveConnectSession class]])
{
_client.session = response; => Crash is Happening Here*
self.session = response;
[self updateStatus:AuthTokenRetrieved];
}
else
{
self.error = response;
[self updateStatus:AuthFailed];
}
self.tokenResponseData = nil;
self.tokenConnection = nil;
}
The Response from the Onedrive Server side. 1. authentication_Token, 2.refreshToken, 3.scope 4.expires_in 5.tokenType",
iOS version:5.1.1
OneDrive SDK Version:5.0

iOS Parse Stripe Integration

I'm fairly new to programming and I created an app to charge customers and would like to store their CC information and charge it at a later time. I've been going through all the tutorials and documentation and I am unable to follow how I can integrate this into my app. Do I need to know other technical skills such as Rest API, Curl, Ruby, etc to get this set up? All the guides and documentation is pointing to that direction. I don't really understand what GET/POST is for and how that fits into iOS Objective-C programming.
Any guidance on how to set this up would be tremendously appreciated. I've been stuck on this for some time now.
Parse's stripe API is not as complete as it could and should be. There are many features it does not include natively, but can be accomplished VIA an HTTP Request. I had to learn a little bit of Javascript, and HTTP request to get many features working. Of course your first instinct should tell you do NOT store a CC number on any device ever! Anytime you have a user input a CC number, immediately get a token and then that is all you will need to use.
Luckily stripe gives you the ability to save customers, and attached CC to customers, and then charge that customer in the future without getting the CC number again. Parse's api does not handle adding a CC to a customer so I added the feature myself.
So Step 1 and 2 Generate a Customer using Parse's API, and generate a Token from the CC information they enter again using Parse's API. If you need help with this, and the cloud code required let me know.
Step 3 Add a CC to a customer. I'm using a custom Customer object, but the main thing you really need is the stripe customerId which is customer.identifier in my code, and tokenID from your CC which in my case is token.tokenId. The response back will be a JSON string with the card information, I turn this into a Dictionary, and then create a STPCard from the dictionary. Also I show how to remove a card from a customer.
iOS Code:
+(void)addToken:(STPToken *)token toCustomerId:(NSString *)customerId completionHandler:(PFIdResultBlock)block
{
[PFCloud callFunctionInBackground:#"stripeUpdateCustomer" withParameters:#{#"customerId":customerId,#"data":#{#"card":token.tokenId}} block:block];
}
+ (void)removeCard:(STPCard *)card FromCustomer:(ELCustomer *)customer completion:(STPCardDeletionBlock)handler
{
if (!customer ||!customer.identifier || !card || !card.identifier || !handler) [NSException raise:#"RequiredParameter" format:#"Required Parameter Missing for deleting card from customer"];
[PFCloud callFunctionInBackground:#"stripeDeleteCardFromCustomer" withParameters:#{#"cardId":card.identifier,#"customerId":customer.identifier} block:^(id object, NSError *error)
{
NSDictionary *dict = nil;
NSError *jsonError = nil;
if (object && [object isKindOfClass:[NSString class]] && !error) {
dict = [NSJSONSerialization JSONObjectWithData:[object dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&jsonError];
}
if (!jsonError && dict) {
handler(dict[#"id"],[dict[#"deleted"] boolValue],error);
}
else if(jsonError) handler(nil,NO,jsonError);
else handler(nil,NO,error);
}];
}
Cloud Code Required:
Parse.Cloud.define("stripeUpdateCustomer", function(request, response)
{
Stripe.Customers.update
(
request.params["customerId"],
request.params["data"],
{
success:function(results)
{
console.log(results["id"]);
response.success(results);
},
error:function(error)
{
response.error("Error:" +error);
}
}
);
});
Parse.Cloud.define("stripeDeleteCardFromCustomer", function(request, response)
{
Stripe.initialize(STRIPE_SECRET_KEY);
Parse.Cloud.httpRequest({
method:"DELETE",
//STRIPE_SECRET_KEY will be your stripe secrect key obviously, this is different from the public key that you will use in your iOS/Android side.
// STRIPE_API_BASE_URL = 'api.stripe.com/v1'
url: "https://" + STRIPE_SECRET_KEY + ':#' + STRIPE_API_BASE_URL + "/customers/" + request.params.customerId + "/cards/" + request.params.cardId,
success: function(httpResponse) {
response.success(httpResponse.text);
},
error: function(httpResponse) {
response.error('Request failed with response code ' + httpResponse.status);
}
});
});
iOS Code for applying a charge to a customer or token notice the required parameters in the dictionary are an amount in cents not dollars, a currency, and then either a customer or a tokenId. Note a customer can have many credit cards, but one of them is the active credit card. The active card is the card that will be charged when you charge a customer:
//Will attempt to charge customer, if no customer exists, or it fails to charge the custoemr it will attempt to charge a card token directly;
//*********Warning: This is the final step it will APPLY A CHARGE TO THE ACCOUNT.***************
-(void)processChargeThroughStripeWithCompletionHandler:(STPChargeCompletionHandler)handler
{
if (![self validForCardProcessing] && ![self validForCustomerProcessing]) {
handler(nil,[NSError errorWithDomain:MY_ERROR_DOMAIN code:elErrorCodeNoCustomerOrTokenID userInfo:[NSDictionary dictionary]]);
return;
}
[self processChargeThroughStripeUsingCustomerWithCompletionHandler:^(STPCharge *charge, NSError *error)
{
if (!error) handler(charge,error);
else{
[self processChargeThroughStripeUsingCardWithCompletionHandler:^(STPCharge *charge, NSError *error) {
handler(charge, error);
}];
}
}];
}
//Process payment using a customer to their active card. No token is required if customer exists with a card on record.
//*********Warning: This is the final step it will APPLY A CHARGE TO THE ACCOUNT.***************
-(void)processChargeThroughStripeUsingCustomerWithCompletionHandler:(STPChargeCompletionHandler)handler
{
if (!self.validForCustomerProcessing)
{
handler(self,[NSError errorWithDomain:MY_ERROR_DOMAIN code:elErrorCodeNoCustomerID userInfo:[NSDictionary dictionary]]);
return;
}
[PFCloud callFunctionInBackground:#"chargeToken" withParameters:[STPCharge dictionaryFromSTPChargeForProccessingUsingCustomer:self] block:^(id object, NSError *error)
{
if (!error)
{
[self initSelfWithDictionary:object];
NSLog(#"object:%#",object);
}
handler(self,error);
}];
}
//Process payment using a token that is attached to the charge, when complete self will be updated with the new charge information
//*********Warning: This is the final step it will APPLY A CHARGE TO THE ACCOUNT.***************
-(void)processChargeThroughStripeUsingCardWithCompletionHandler:(STPChargeCompletionHandler)handler
{
if (!self.validForCardProcessing)
{
handler(self,[NSError errorWithDomain:MY_ERROR_DOMAIN code:elErrorCodeNoTokenID userInfo:[NSDictionary dictionary]]);
return;
}
[PFCloud callFunctionInBackground:#"chargeToken" withParameters:[STPCharge dictionaryFromSTPChargeForProccessingUsingCard:self] block:^(id object, NSError *error)
{
if (!error)
{
[self initSelfWithDictionary:object];
}
handler(self,error);
}];
}
+ (NSDictionary *)dictionaryFromSTPChargeForProccessingUsingCard:(STPCharge *)charge
{
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
dictionary[#"amount"] = charge.amountInCents;
dictionary[#"currency"] = charge.currency;
dictionary[#"card"] = charge.token.tokenId;
return dictionary;
}
+ (NSDictionary *)dictionaryFromSTPChargeForProccessingUsingCustomer:(STPCharge *)charge
{
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
dictionary[#"amount"] = charge.amountInCents;
dictionary[#"currency"] = charge.currency;
dictionary[#"customer"] = charge.customer.identifier;
return dictionary;
}
Cloud code for charging a customer/token:
Parse.Cloud.define("chargeToken",function(request,response)
{
Stripe.initialize(STRIPE_SECRET_KEY);
Stripe.Charges.create
(
request.params,
{
success:function(results)
{
response.success(results);
},
error:function(error)
{
response.error("Error:" +error);
}
}
);
});
How are you storing their CC information to charge it at a later time? Before proceeding, you need to know if it is PCI compliant or not. At most, the only things you should be looking to store is the expiration date, last 4 digits, and an associated record object that Parse Stripe gives you that corresponds to that CC. Do not try to store the full CC.
As to your other questions:
Generally you need to know a web language to do something like this. Here is an example of a possible stack that I've seen in a situation like this:
iOS App -> sends request to Server (rails, python, php, etc) -> Will send request to 3rd party site
3rd party site response -> Server -> iOS app.
The point of the server is to intercept the call from the mobile App to Parse, and the response from Parse back to the mobile app. The reason for this is so you can have a "master" db of the transactions/states and can recover if the app is ever reinstalled on the user's phone. It also will let you store an identifier that points to the user's CC on parse stripe (I'm assuming).
You should really understand GET/POST as they are becoming a very basic feature of any iOS app. They are simply how you get/insert records from a server. Considering almost all of the popular apps have some kind of network connectivity embedded in them, it really is a core part of iOS programming IMO.

Resources