I am using a PromiseKit framework version 1.7.7 (I need to use this version due another framework that needs it).
So, in this framework that uses the PromiseKit framework has this method:
- (PMKPromise *)paymentTokenForCreditCard:(GNCreditCard *)creditCard {
NSDictionary *cardDict = [creditCard paramsDicionary];
NSString *jsonCard = [self getJSONStringFromDictionary:cardDict];
return [self encryptData:jsonCard]
.then(^(NSString *encryptedData){
NSDictionary *params = #{#"data":encryptedData};
return [self request:kGNApiRouteSaveCard method:#"POST" params:params];
})
.then(^(NSDictionary *response){
return [[GNPaymentToken alloc] initWithDictionary:response];
});
}
And it shows this example on how to use it:
GNConfig *gnConfig = [[GNConfig alloc] initWithAccountCode:#"YOUR_ACCOUNT_CODE" sandbox:YES];
GNApiEndpoints *gnApi = [[GNApiEndpoints alloc] initWithConfig:gnConfig];
GNCreditCard *creditCard = [[GNCreditCard alloc] init];
creditCard.number = #"4012001038443335";
creditCard.brand = kGNMethodBrandVisa;
creditCard.expirationMonth = #"05";
creditCard.expirationYear = #"2018";
creditCard.cvv = #"123";
[gnApi paymentTokenForCreditCard:creditCard]
.then(^(GNPaymentToken *paymentToken){
NSLog(#"%#", paymentToken.token);
})
.catch(^(GNError *error){
NSLog(#"An error occurred: %#", error.message);
});
Well, how I am using Swift instead of Object-C, I am trying to use it this way:
let gnConfig = GNConfig(accountCode: "3f62976bea79971730b67cd62806c256", sandbox: true)
let gnEndpoints = GNApiEndpoints(config: gnConfig)
let gnCreditCard: GNCreditCard! = GNCreditCard(number: "4012001038443335", brand: kGNMethodBrandVisa, expirationMonth: "05", expirationYear: "2018", cvv: "123")
gnEndpoints?.paymentToken(for: gnCreditCard).then({ tokenPagamento in
if let aToken = tokenPagamento?.token {
print("\(aToken)")
}
}).catch({ error in
if let aMessage = error?.message {
print("An error occurred: \(aMessage)")
}
})
And it is showing me this error:
Ambiguous reference to member 'then()'
How could I fix it?
Try this code below. The promise thing should work. Modify it upon your needs.
gnEndpoints?.paymentToken(for: gnCreditCard).then({ token -> () in
if let token = token as? GNPaymentToken {
print(token)
}
}, { (error) -> () in
// catch your error
})
Related
I am playing around with the google drive API and trying to build a simple app that uploads a picture to my google drive. The app is supposed to upload a picture once the user is signed in, however it gives an error of
"2017-09-14 00:55:20.342237-0400 driveTest[6705:1647551] An error
occurred: Error Domain=com.google.GTLRErrorObjectDomain Code=403
"Insufficient Permission"
UserInfo={GTLRStructuredError=GTLRErrorObject 0x1c4251d30:
{message:"Insufficient Permission" errors:[1] code:403},
NSLocalizedDescription=Insufficient Permission}"
I have tried to pass it the service which is of type GTLRDriveService to the initSetup() function of the userSetUp class, but to no avail. Could someone please point me to the right track as to why my permissions are not working even though I have logged on correctly, and the part where I am passing in the GTLRDriveService is in the code that runs after a sucessful login.
I instantiate a userSetUp object and I
let setUpUser = userSetUp()
setUpUser.initSetup(service)
I have userSetUp written in objective c as such and it is bridged correctly as I am able to instantiate it in my viewcontroller file which is written in swift.
UserSetUp:::::::
#import "userSetUp.h"
#import <GoogleSignIn/GoogleSignIn.h>
#import GoogleAPIClientForREST;
#implementation userSetUp
- (void) initSetup:(GTLRDriveService *) driveService {
printf("heloooooaiosuoiadoidauoalo");
//GTLRDriveService *driveService = [GTLRDriveService new];
//NSData *fileData = [[NSFileManager defaultManager] contentsAtPath:#"files/apple.jpg"];
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"apple" ofType:#"jpg"];
NSData *fileData = [NSData dataWithContentsOfFile:filePath];
GTLRDrive_File *metadata = [GTLRDrive_File object];
metadata.name = #"apple.jpg";
//metadata.mimeType = #"application/vnd.google-apps.document";
GTLRUploadParameters *uploadParameters = [GTLRUploadParameters uploadParametersWithData:fileData
MIMEType:#"image/jpeg"];
uploadParameters.shouldUploadWithSingleRequest = TRUE;
GTLRDriveQuery_FilesCreate *query = [GTLRDriveQuery_FilesCreate queryWithObject:metadata
uploadParameters:uploadParameters];
query.fields = #"id";
[driveService executeQuery:query completionHandler:^(GTLRServiceTicket *ticket,
GTLRDrive_File *file,
NSError *error) {
if (error == nil) {
//NSLog(#"File ID %#", file.identifier);
printf("it worked");
} else {
NSLog(#"An error occurred: %#", error);
}
}];
printf("upload complete!");
}
#end
And Viewcontroller. swift
import GoogleAPIClientForREST
import GoogleSignIn
import UIKit
class ViewController: UIViewController, GIDSignInDelegate, GIDSignInUIDelegate {
// If modifying these scopes, delete your previously saved credentials by
// resetting the iOS simulator or uninstall the app.
private let scopes = [kGTLRAuthScopeDriveReadonly]
let service = GTLRDriveService()
let signInButton = GIDSignInButton()
let output = UITextView()
override func viewDidLoad() {
super.viewDidLoad()
// Configure Google Sign-in.
GIDSignIn.sharedInstance().delegate = self
GIDSignIn.sharedInstance().uiDelegate = self
GIDSignIn.sharedInstance().scopes = scopes
GIDSignIn.sharedInstance().signInSilently()
signInButton.frame = CGRect(x: view.frame.width/2 - signInButton.frame.width , y: view.frame.height/2, width: signInButton.frame.width, height: signInButton.frame.height)
// Add the sign-in button.
view.addSubview(signInButton)
// Add a UITextView to display output.
output.frame = view.bounds
output.isEditable = false
output.contentInset = UIEdgeInsets(top: 20, left: 0, bottom: 20, right: 0)
output.autoresizingMask = [.flexibleHeight, .flexibleWidth]
output.isHidden = true
view.addSubview(output);
//let itsASetup()
}
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!,
withError error: Error!) {
if let error = error {
showAlert(title: "Authentication Error", message: error.localizedDescription)
self.service.authorizer = nil
} else {
self.signInButton.isHidden = true
self.output.isHidden = false
self.service.authorizer = user.authentication.fetcherAuthorizer()
listFiles()
}
}
// List up to 10 files in Drive
func listFiles() {
let query = GTLRDriveQuery_FilesList.query()
query.pageSize = 10
service.executeQuery(query,
delegate: self,
didFinish: #selector(displayResultWithTicket(ticket:finishedWithObject:error:))
)
}
// Process the response and display output
#objc func displayResultWithTicket(ticket: GTLRServiceTicket,
finishedWithObject result : GTLRDrive_FileList,
error : NSError?) {
if let error = error {
showAlert(title: "Error", message: error.localizedDescription)
return
}
var text = "";
if let files = result.files, !files.isEmpty {
text += "Files:\n"
for file in files {
text += "\(file.name!) (\(file.identifier!))\n"
}
} else {
text += "No files found."
}
output.text = text
let setUpUser = userSetUp()
setUpUser.initSetup(service)
}
// Helper for showing an alert
func showAlert(title : String, message: String) {
let alert = UIAlertController(
title: title,
message: message,
preferredStyle: UIAlertControllerStyle.alert
)
let ok = UIAlertAction(
title: "OK",
style: UIAlertActionStyle.default,
handler: nil
)
alert.addAction(ok)
present(alert, animated: true, completion: nil)
}
}
try to Change your scope like:
class ViewController: UIViewController, GIDSignInDelegate, GIDSignInUIDelegate
{
// If modifying these scopes, delete your previously saved credentials by
private let scopes = ["https://www.googleapis.com/auth/drive"]
...
}
I am passing my data from javascript to objective-c. for that I am using IFRAME.
Here is my code:
context.html
function openCustomURLinIFrame(src)
{
alert(src);
var rootElm = document.documentElement;
var newFrameElm = document.createElement("IFRAME");
newFrameElm.setAttribute("src",src);
document.documentElement.appendChild(newFrameElm);
//remove the frame now
newFrameElm.parentNode.removeChild(newFrameElm);
newFrameElm = null;
}
Indoor.m
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSLog(#"Loading: %#", [request URL]);
NSURL *url = [request URL];
NSString *urlStr = url.absoluteString;
return [self processURL:urlStr];
}
I am getting
Loading: about:blank
I am using xCode 8.2.1 it is working well in IOS 9.3 but not working in iOS 10.2.
Edit:
My alert screenshot in .html file.
Edit:
Method in html file in which I call openCustomURLinIFrame method.
function calliOSFunction(functionName, args, successCallback, errorCallback)
{
var url = "js2ios://";
var callInfo = {};
callInfo.functionname = functionName;
//alert("Custom menu clicked !!"+functionName);
if (successCallback)
{
//alert("Success !!"+functionName);
callInfo.success = successCallback;
}
if (errorCallback)
{
//alert("Error !!"+functionName);
callInfo.error = errorCallback;
}
if (args)
{
//alert("args !!"+args);
callInfo.args = args;
}
url += JSON.stringify(callInfo)
openCustomURLinIFrame(url);
}
Help me to resolve this issue.
Finally after long time I got my answer.
function calliOSFunction(functionName, args, successCallback, errorCallback)
{
var url = "js2ios:///"; /* Added one more "/" */
var callInfo = {};
callInfo.functionname = functionName;
//alert("Custom menu clicked !!"+functionName);
if (successCallback)
{
//alert("Success !!"+functionName);
callInfo.success = successCallback;
}
if (errorCallback)
{
//alert("Error !!"+functionName);
callInfo.error = errorCallback;
}
if (args)
{
//alert("args !!"+args);
callInfo.args = args;
}
url += JSON.stringify(callInfo)
openCustomURLinIFrame(url);
}
I add one more "/" in url variable.
under iOS using GMTAuth to access gmail. The test code follows below. The account is accessible with MailCore, essentially similar code, but user/pw no oAuth. Any clues would be appreciated.
I get this log output:
__nw_connection_get_connected_socket_block_invoke 3 Connection has no connected handler
2017-02-24 17:20:02.977 Example-iOS[38329:24679819] finished checking account.
2017-02-24 17:20:10.526 Example-iOS[38329:24679819] error loading account: Error Domain=MCOErrorDomain Code=1 "A stable connection to the server could not be established."
and this is the code:
self.imapSession = [[MCOIMAPSession alloc] init];
self.imapSession.hostname = #"imap.google.com";
self.imapSession.port = 993;
self.imapSession.username = [_authorization userEmail];
GTMAppAuthFetcherAuthorization* authorization =
[GTMAppAuthFetcherAuthorization authorizationFromKeychainForName:kExampleAuthorizerKey];
self.imapSession.OAuth2Token = authorization.authState.lastTokenResponse.accessToken;
self.imapSession.authType = MCOAuthTypeXOAuth2;
self.imapSession.connectionType = MCOConnectionTypeTLS;
GTMAppAuthExampleViewController * __weak weakSelf = self;
self.imapSession.connectionLogger = ^(void * connectionID, MCOConnectionLogType type, NSData * data) {
#synchronized(weakSelf) {
if (type != MCOConnectionLogTypeSentPrivate) {
NSLog(#"event logged:%p %li withData: %#", connectionID, (long)type, [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
}
}
};
// Reset the inbox
self.messages = nil;
NSLog(#"checking account");
self.imapCheckOp = [self.imapSession checkAccountOperation];
[self.imapCheckOp start:^(NSError *error) {
GTMAppAuthExampleViewController *strongSelf = weakSelf;
NSLog(#"finished checking account.");
if (error == nil) {
// TBD: [strongSelf loadLastNMessages:NUMBER_OF_MESSAGES_TO_LOAD];
} else {
NSLog(#"error loading account: %#", error);
}
strongSelf.imapCheckOp = nil;
}];
}
Update: I figured out the solution. Here's my full working code:
func loadAccount() {
// This is just a model file holding the account details...
let account = emailAccounts[currentAccount]
imapSession = MCOIMAPSession()
imapSession?.hostname = account.hostname
imapSession?.port = 993
imapSession?.username = account.userName
imapSession?.authType = .xoAuth2
// This email helper code is from this guide:
// https://github.com/MailCore/mailcore2/wiki/Implementing-OAuth-2.0
imapSession?.oAuth2Token = EmailHelper.singleton().authorization?.authState.lastTokenResponse?.accessToken
// This is important too (wasn't working with other values)
imapSession?.connectionType = .TLS
imapSession?.connectionLogger = { [unowned self] (connectionID, type, data) in
let lockQueue = DispatchQueue(label: "com.inboxzero.LockQueue")
lockQueue.sync() {
if (type != MCOConnectionLogType(rawValue: NSInteger(2))) { // MCOConnectionLogTypeSentPrivate
if let theData = data, let str = connectionID {
let theString = String(describing: theData)
print("event logged:\(str) \(type) withData: \(theString)")
}
}
}
}
// Reset the inbox:
messages = nil
isLoading = false
print("checking account \(self.imapSession!.username!)")
imapCheckOp = self.imapSession?.checkAccountOperation()
if let checkOp = imapCheckOp {
checkOp.start( { (error) in
print("finished checking \(self.imapSession!.username!)")
if (error == nil) {
self.loadLastNMessages(nMessages: self.NUMBER_OF_MESSAGES_TO_LOAD)
}
else {
print("error loading account \(self.imapSession!.username!): %#", error!)
self.alertWithTitle(title:"Mail Core", message:error.debugDescription)
return
}
})
}
}
Code to make Token
- (IBAction)save:(id)sender
{
STPCard *card = [[STPCard alloc] init];
card.number = self.paymentView.card.number;
card.expMonth = self.paymentView.card.expMonth;
card.expYear = self.paymentView.card.expYear;
card.cvc = self.paymentView.card.cvc;
[[STPAPIClient sharedClient] createTokenWithCard:card
completion:^(STPToken *token, NSError *error) {
if (error) {
NSLog(#"%#",error);
} else {
NSString *myVal = [NSString stringWithFormat:#"%#",token];
NSLog(#"%#",token);
[PFCloud callFunctionInBackground:#"chargeMoney"
withParameters:#{#"token":myVal}
block:^(NSString *result, NSError *error) {
if (!error) {
NSLog(#"from Cloud Code: %#",result);
}
}];
};
}];
}
Code to Charge
Parse.Cloud.define("chargeMoney", function(request, response) {
response.success(request.params.token);
var stripe = require('stripe');
stripe.initialize('sk_test_ldqwdqwdqwdqwdwqdqwd ');
var stripeToken = request.params.token;
var charge = stripe.charges.create({
amount: 1000, // amount in cents, again
currency: "usd",
source: stripeToken,
description: "payinguser#example.com"
}, function(err, charge) {
if (err && err.type === 'StripeCardError') {
// The card has been declined
}
});
});
Error I am getting
[Error]: TypeError: Cannot call method 'create' of undefined
at main.js:11:31 (Code: 141, Version: 1.7.1)
What's the problem with my code. I haven't change anything i am doing according to the documentation.Any onle please suggest whats the issue in my code.
Hey so I was able to duplicate your error. In the javascript, change var charge = stripe.charges.create({ to var charge = stripe.Charges.create({
Also you can pass the token directly if you want, you don't need to convert it to a string.
After spending one night finally I spotted my errors there is Three errors in my code:
Error 1
Replace this
NSString *myVal = [NSString stringWithFormat:#"%#",token];
with
NSString *myVal = [NSString stringWithFormat:#"%#",token.tokenId];
Error 2
stripe.initialize('sk_test_ldqwdqwdqwdqwdwqdqwd ');
Their is extra space in key after last word i.e 'd'.
Error 3
Remove this
response.success(request.params.token);
from top
Finally working code is ::
Create token
- (IBAction)save:(id)sender
{
STPCard *card = [[STPCard alloc] init];
card.number = self.paymentView.card.number;
card.expMonth = self.paymentView.card.expMonth;
card.expYear = self.paymentView.card.expYear;
card.cvc = self.paymentView.card.cvc;
[[STPAPIClient sharedClient] createTokenWithCard:card
completion:^(STPToken *token, NSError *error) {
if (error) {
NSLog(#"%#",error);
} else {
NSString *myVal = token.tokenId;
NSLog(#"%#",token);
[PFCloud callFunctionInBackground:#"hello" withParameters:#{#"token":myVal}
block:^(NSString *result, NSError *error) {
if (!error) {
NSLog(#"from Cloud Code Res: %#",result);
}
else
{
NSLog(#"from Cloud Code: %#",error);
}
}];
};
}];
}
Parse Cloud code (main.js)
// Use Parse.Cloud.define to define as many cloud functions as you want.
// For example:
var stripe = require('stripe');
stripe.initialize('sk_test_lweGasdaqwMKnZRndg5123G');
Parse.Cloud.define("hello", function(request, response) {
var stripeToken = request.params.token;
var charge = stripe.Charges.create({
amount: 1000, // express dollars in cents
currency: 'usd',
card: stripeToken
}).then(null, function(error) {
console.log('Charging with stripe failed. Error: ' + error);
});
});
Hi I am trying to figure out how to rewrite this in swift:
- (IBAction)requestUserInfo:(id)sender
{
// We will request the user's public picture and the user's birthday
// These are the permissions we need:
NSArray *permissionsNeeded = #[#"public_profile", #"user_birthday", #"email"];
// Request the permissions the user currently has
[FBRequestConnection startWithGraphPath:#"/me/permissions" completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error){
// Parse the list of existing permissions and extract them for easier use
NSMutableArray *currentPermissions = [[NSMutableArray alloc] init];
NSLog(#"The fucking class is: %#", [result class]);
NSArray *returnedPermissions = (NSArray *)[result data];
for (NSDictionary *perm in returnedPermissions) {
if ([[perm objectForKey:#"status"] isEqualToString:#"granted"]) {
[currentPermissions addObject:[perm objectForKey:#"permission"]];
}
} // cut cut here
}
EDIT:
I was having trouble trying to get the required data out of the FBGraphObject but figured it out after some further inspection. I have posted the swift version below so that people can just cut and paste it and get on with using swift. Hope it saves someone some time.
Here:
#IBAction func requestUserInfo(sender: AnyObject){
// These are the permissions we need:
var permissionsNeeded = ["public_profile", "user_birthday", "email"]
// Request the permissions the user currently has
FBRequestConnection.startWithGraphPath("/me/permissions", completionHandler: {(connection, result, error) -> Void in
if error == nil{
// Parse the list of existing permissions and extract them for easier use
var theResult = result as? [String:[AnyObject]]
var currentPermissions = [String]()
let returnedPermissions = theResult?["data"] as [[String:String]]
for perm in returnedPermissions {
if perm["status"] == "granted" {
currentPermissions.append(perm["permission"]!)
}
}
// Build the list of requested permissions by starting with the permissions
// needed and then removing any current permissions
println("Needed: \(permissionsNeeded)")
println("Current: \(currentPermissions)")
var requestPermissions = NSMutableArray(array: permissionsNeeded, copyItems: true)
requestPermissions.removeObjectsInArray(currentPermissions)
println("Asking: \(requestPermissions)")
// TODO PUT A POPUP HERE TO TELL WHAT PERMISSIONS WE NEED!
// If we have permissions to request
if requestPermissions.count > 0 {
// Ask for the missing permissions
FBSession.activeSession().requestNewReadPermissions(requestPermissions, completionHandler: {(session, error) -> Void in
if (error == nil) {
// Permission granted, we can request the user information
self.makeRequestForUserData()
} else {
// An error occurred, we need to handle the error
// Check out our error handling guide: https://developers.facebook.com/docs/ios/errors/
println("error: \(error?.description)")
}
})
} else {
// Permissions are present
// We can request the user information
self.makeRequestForUserData()
}
} else {
// An error occurred, we need to handle the error
// Check out our error handling guide: https://developers.facebook.com/docs/ios/errors/
println("error: \(error?.description)")
}
})
}
private func makeRequestForUserData() {
FBRequestConnection.startForMeWithCompletionHandler({(connection, result, error) -> Void in
if (error == nil) {
// Success! Include your code to handle the results here
println("user info: \(result)")
} else {
// An error occurred, we need to handle the error
// Check out our error handling guide: https://developers.facebook.com/docs/ios/errors/
println("error: \(error?.description)")
}
})
}
// Show an alert message
func showMessage(text : NSString, title : NSString){
var alert = UIAlertController(title: title, message: text, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
UIApplication.sharedApplication().delegate?.window!?.rootViewController?.presentViewController(alert, animated: true, completion: nil)
}