I have the next block that is called when user wants signOut:
Im using Swift 5 and call the signOut, but need the globalSignOut.
class LoginController: UIViewController{
var auth: AWSCognitoAuth = AWSCognitoAuth.default()
var session: AWSCognitoAuthUserSession?
//..
override func viewDidLoad() {
super.viewDidLoad()
self.auth.delegate = self
}
func signOutAws(){
self.auth.signOut(self, completion: { (error) in
if error != nil{
//show alert..
}else{
self.session = nil
self.auth = AWSCognitoAuth.default()
self.auth.delegate = self
}
})
}
//..
}
I expect that the user session expired in all apps, but has not expired session in all apps.
I'm having 2 buttons button1 & button2
when button1 is pressed I have to get url1 and when button2 is pressed get url2 in the below function
func fetchXMLData() {
XMLParserFactory.fetchData(url: "https://brwterrgn.ergwgw.com/etwtt.cms") { (listOfXMLVM, error) in
print("Fetch xml data")
if error == nil {
self.listOfNewsVM = listOfXMLVM!
self.tableView.reloadData()
}
else {
print(error?.localizedDescription ?? "Error")
}
}
}
}
Add parameter to this fetchXMLData function
func fetchXMLData(withUrl url: String)
also replace your url by this url variable
XMLParserFactory.fetchData(url: url)
Now in every IBAction call this function with different url passed as parameter of this method
#IBAction func button1pressed(_ sender: UIButton) {
fetchXMLData(withUrl: "url1.com")
}
#IBAction func button2pressed(_ sender: UIButton) {
fetchXMLData(withUrl: "url2.com")
}
You can try to make the url a parameter and change it from the caller place
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
fetchXMLData(url: "https://value.com/etwtt.cms")
}
func buttonAct(_ sender: UIButton) {
fetchXMLData(url: "https://brwterrgn.ergwgw.com/etwtt.cms")
}
func fetchXMLData(url:String) {
XMLParserFactory.fetchData(url:url) { (listOfXMLVM, error) in
print("Fetch xml data")
if error == nil {
self.listOfNewsVM = listOfXMLVM!
self.tableView.reloadData()
}
else {
print(error?.localizedDescription ?? "Error")
}
}
}
Edit
class FirstVC: UIViewController {
func showSecond(_ sender: UIButton) {
let sec = //
sec.delegate = self
present/push(sec)
}
func fetchXMLData(url:String) {
XMLParserFactory.fetchData(url:url) { (listOfXMLVM, error) in
print("Fetch xml data")
if error == nil {
self.listOfNewsVM = listOfXMLVM!
self.tableView.reloadData()
}
else {
print(error?.localizedDescription ?? "Error")
}
}
}
class SecondVC: UIViewController {
weak var delegate:FirstVC?
func buttonAct(_ sender: UIButton) {
delegate?.fetchXMLData(url: "https://brwterrgn.ergwgw.com/etwtt.cms")
}
}
The service I want to connect to is published via Bonjour.
I can find all the info with the Bonjour Browser, however if I try to gather the data programmatically, the only value I get, is the name of the service.
The NetService delegate is set and the function netServiceWillPublish is called.
The functions DidNotPublish or DidPublish are not executed.
The function netServiceBrowser gets all published netServices, but all properties are set to the default value of the datatype.
import UIKit
class BMNSDelegate : NSObject, NetServiceDelegate {
func netServiceWillPublish(_ sender: NetService) {
print("netServiceWillPublish:\(sender)"); //This method is called
}
func netService(_ sender: NetService, didNotPublish errorDict: [String : NSNumber]){
print("didNotPublish:\(sender)");
}
func netServiceDidPublish(_ sender: NetService) {
print("netServiceDidPublish:\(sender)");
}
func netServiceWillResolve(_ sender: NetService) {
print("netServiceWillResolve:\(sender)");
}
func netService(_ sender: NetService, didNotResolve errorDict: [String : NSNumber]) {
print("netServiceDidNotResolve:\(sender)");
}
func netServiceDidResolveAddress(_ sender: NetService) {
print("netServiceDidResolve:\(sender)");
}
func netService(_ sender: NetService, didUpdateTXTRecord data: Data) {
print("netServiceDidUpdateTXTRecordData:\(sender)");
}
func netServiceDidStop(_ sender: NetService) {
print("netServiceDidStopService:\(sender)");
}
func netService(_ sender: NetService,
didAcceptConnectionWith inputStream: InputStream,
outputStream stream: OutputStream) {
print("netServiceDidAcceptConnection:\(sender)");
}
}
class BMBrowserDelegate : NSObject, NetServiceBrowserDelegate, NetServiceDelegate {
func netServiceBrowser(_ netServiceBrowser: NetServiceBrowser,
didFind netService: NetService,
moreComing moreServicesComing: Bool) {
let nsnsdel = BMNSDelegate()
netService.delegate = nsnsdel
netService.resolve(withTimeout: 1)
print(netService.domain) // local.
print(netService.name) // This property is correct
print(netService.type) // _http._tcp.
print(netService.addresses) // Optional([])
print(netService.hostName) // nil
print(netService.port) // -1
print(moreServicesComing) //false
}
}
let SERVICE_TYPE = "_http._tcp."
let BM_DOMAIN = "local."
let browser = NetServiceBrowser()
let nsbdel = BMBrowserDelegate()
browser.delegate = nsbdel
browser.searchForServices(ofType: SERVICE_TYPE, inDomain: BM_DOMAIN)
RunLoop.current.run()
The error is that the services which are found in the ServiceBrowserDelegate function are not saved anywhere and therefore are discarded at the end of the function.
I found a working example here:
https://github.com/mattneub/Programming-iOS-Book-Examples/blob/61f0c753a080040e4a74b912e6c18dd97fe8bcaa/bk2ch24p853bonjour/ch37p1101bonjour/ViewController.swift
class ViewController: UIViewController, NetServiceBrowserDelegate, NetServiceDelegate {
var nsb : NetServiceBrowser!
var services = [NetService]()
#IBAction func doButton (_ sender: Any!) {
print("listening for services...")
self.services.removeAll()
self.nsb = NetServiceBrowser()
self.nsb.delegate = self
self.nsb.searchForServices(ofType:"_daap._tcp", inDomain: "")
}
func updateInterface () {
for service in self.services {
if service.port == -1 {
print("service \(service.name) of type \(service.type)" +
" not yet resolved")
service.delegate = self
service.resolve(withTimeout:10)
} else {
print("service \(service.name) of type \(service.type)," +
"port \(service.port), addresses \(service.addresses)")
}
}
}
func netServiceDidResolveAddress(_ sender: NetService) {
self.updateInterface()
}
func netServiceBrowser(_ aNetServiceBrowser: NetServiceBrowser, didFind aNetService: NetService, moreComing: Bool) {
print("adding a service")
self.services.append(aNetService)
if !moreComing {
self.updateInterface()
}
}
func netServiceBrowser(_ aNetServiceBrowser: NetServiceBrowser, didRemove aNetService: NetService, moreComing: Bool) {
if let ix = self.services.index(of:aNetService) {
self.services.remove(at:ix)
print("removing a service")
if !moreComing {
self.updateInterface()
}
}
}
}
I have been working for days trying to figure out how to charge a card and save the card to a customer with Stripe using Swift, with Parse.com Cloud Code as the backend. I integrated the Stripe pod with my project successfully, and I have a token that is created, and prints out in the console to verify its existence. BUT I cannot do anything with it! I have searched everywhere for answers, and cannot figure out why I keep getting error. I think it has to do with the parameters that I am trying to feed to the Cloud Code, but I am unsure. I have read the docs for both Cloud Code and Stripe, and it was to no avail. This is my PaymentViewController.swift:
import UIKit
import Stripe
import PaymentKit
import Parse
import Bolts
class PaymentViewController: UIViewController, PTKViewDelegate {
#IBOutlet weak var saveBtn: UIButton!
var paymentView: PTKView = PTKView()
override func viewDidLoad() {
super.viewDidLoad()
var view : PTKView = PTKView(frame: CGRectMake(15,20,290,55))
paymentView = view
paymentView.delegate = self;
self.view.addSubview(self.paymentView)
saveBtn.enabled = false
}
func paymentView(view: PTKView!, withCard card: PTKCard!, isValid valid: Bool) {
if (valid) {
saveBtn.enabled = true
} else {
saveBtn.enabled = false
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func save(sender: AnyObject) {
var card: STPCard = STPCard()
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: { (tokenId: STPToken?, error: NSError?) -> Void in
if (error != nil) {
println(error)
println("what the..")
} else {
println(tokenId)
PFCloud.callFunctionInBackground("hello", withParameters: nil) {
(response: AnyObject?, error: NSError?) -> Void in
let responseString = response as? String
println(responseString)
}
PFCloud.callFunctionInBackground("createCharge", withParameters: nil, block: { (success: AnyObject?, error: NSError?) -> Void in
if error != nil {
println("error")
}
})
}
})
}
#IBAction func cancel(sender: AnyObject) {
self.dismissViewControllerAnimated(true, completion: nil)
}
}
I have added the "Hello World" example to see if the Cloud Code was set up correctly, and that callFunction does work. My Cloud Code is:
var Stripe = require('stripe');
Stripe.initialize('My_Secret_Key');
Parse.Cloud.define("hello", function(request, response) {
response.success("Hello world!");
});
Parse.Cloud.define("createCharge", function(request, response) {
Stripe.Charges.create({
amount: 100 * 10, // $10 expressed in cents
currency: "usd",
card: "tok_3TnIVhEv9P24T0"
},{
success: function(httpResponse) {
response.success("Purchase made!");
},
error: function(httpResponse) {
response.error("Uh oh, something went wrong");
}
});
});
Any help would be truly appreciated!! I have been working tirelessly to figure this out! The console prints out
Uh oh, something went wrong (Code: 141, Version: 1.7.2)
The error you are seeing Uh oh, something went wrong (Code: 141, Version: 1.7.2) means that your createCharge Parse function returned an error. You may want to log the value of httpResponse to find the exact error from Stripe.
Looking at your code the error is most likely: Invalid Request Error: Cannot use token tok_3TnIVhEv9P24T0 more than once. You can confirm this in the Logs section of your Stripe Dashboard.
I see that you print the token, println(tokenId), you're also going to want to send that to your Parse function and set card equal to the value of the token you just created.
class PaymentViewController: UIViewController, PTKViewDelegate {
#IBOutlet weak var saveBtn: UIButton!
var paymentView: PTKView = PTKView()
override func viewDidLoad() {
super.viewDidLoad()
var view : PTKView = PTKView(frame: CGRectMake(15,20,290,55))
paymentView = view
paymentView.delegate = self;
self.view.addSubview(self.paymentView)
saveBtn.enabled = false
}
func paymentView(view: PTKView!, withCard card: PTKCard!, isValid valid: Bool) {
if (valid) {
saveBtn.enabled = true
} else {
saveBtn.enabled = false
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func save(sender: AnyObject) {
var card: STPCard = STPCard()
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: { (token: STPToken?, error: NSError?) -> Void in
if (error != nil) {
println(error)
println("not working")
} else {
//println(tokenId)
var coin = token!.tokenId
PFCloud.callFunctionInBackground("hello", withParameters: nil) {
(response: AnyObject?, error: NSError?) -> Void in
let responseString = response as? String
println(responseString)
}
var name = PFUser.currentUser()?.username as String!
var customer = PFUser.currentUser()?.objectId as String!
PFCloud.callFunctionInBackground("createCustomer", withParameters: ["coin" : coin, "name": name, "customer": customer], block: { (success: AnyObject?, error: NSError?) -> Void in
if error != nil {
println("create customer not working")
}
})
var customerId = customer!
PFCloud.callFunctionInBackground("createCharge", withParameters: ["customerId" : customerId], block: { (success: AnyObject?, error: NSError?) -> Void in
if error != nil {
println("not working")
}
})
}
})
}
#IBAction func cancel(sender: AnyObject) {
self.dismissViewControllerAnimated(true, completion: nil)
}
}
And My updated cloud code is here:
var Stripe = require('stripe');
Stripe.initialize('sk_test_xxxxxxxxxxxxxx');
Parse.Cloud.define("hello", function(request, response) {
response.success("Hello world!");
});
Parse.Cloud.define("createCustomer", function(request, response) {
Stripe.Customers.create({
card: request.params.coin,
account_balance: -10*100,
metadata: {
name: request.params.name,
customer: request.params.customer, // e.g PFUser object ID
}
}, {
success: function(customer) {
response.success(customer.id);
},
error: function(error) {
response.error("Error:" +error);
}
})
});
Parse.Cloud.define("createCharge", function(request, response) {
Stripe.Charges.create({
amount: 100 * 10, // $10 expressed in cents
currency: "usd",
//card: request.params.coin
customer: request.params.customerId
},{
success: function(httpResponse) {
response.success("Purchase made!");
},
error: function(httpResponse) {
response.error(httpResponse)
response.error("Uh oh, something went wrong");
}
});
});
Ultimately I want to have the create customer in a different viewController.swift file and charge on another section of the app, but for right now I am testing it with them in the same PaymentViewController.swift file
I have a few processes that need to be completed in order when my TableView loads. I would expect that it would wait until the code completed before executing the next line of code, but it seems that's not the case. Is there a way to have these wait until completion before executing the next step?
override func viewDidLoad() {
super.viewDidLoad()
performTask1()
performTask2()
performTask3()
}
Thanks for all the help!
The typical example to make each of these methods take a completionHandler parameter, e.g.:
func perform1(completionHandler: () -> Void) {
doSomethingAsynchronously() {
completionHandler()
}
}
func perform2(completionHandler: () -> Void) {
doSomethingElseAsynchronously() {
completionHandler()
}
}
func perform3(completionHandler: () -> Void) {
doSomethingCompletelyDifferentAsynchronously() {
completionHandler()
}
}
Then you can run them like so:
override func viewDidLoad() {
super.viewDidLoad()
perform1 {
self.perform2 {
self.perform3 {
}
}
}
}