Invalid user credentials PayPalEnvironmentProduction - paypal

I am using PaypalSDK(2.16.2) for iOS,I can login and pay in PayPalEnvironmentSandbox,when i switch app to PayPalEnvironmentProduction, I get following error in xcode response:
PayPal SDK: Request has failed with error: invalid_user - Incorrect username/password. Please try again。 (401) | PayPal Debug-ID: b2cedad5b6842, b2cedad5b6842 [live, PayPal iOS SDK 2.16.2] | Details: (
{
"error_description" = "Invalid user credentialenter code heres";
}
).
I'm sure my account and password are correct(Android app and web pages can log on),I am unable to understand the reason for invalid credentials?
Code
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
successView.isHidden = true
// Set up payPalConfig
payPalConfig.acceptCreditCards = false
payPalConfig.merchantName = "shopins"
payPalConfig.merchantPrivacyPolicyURL = URL(string: "https://www.paypal.com/webapps/mpp/ua/privacy-full")
payPalConfig.merchantUserAgreementURL = URL(string: "https://www.paypal.com/webapps/mpp/ua/useragreement-full")
payPalConfig.languageOrLocale = Locale.preferredLanguages[0]
payPalConfig.payPalShippingAddressOption = .payPal;
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
PayPalMobile.preconnect(withEnvironment: PayPalEnvironmentProduction)
}
#IBAction func buyClothingAction(_ sender: AnyObject) {
resultText = ""
let item1 = PayPalItem(name: "Old jeans with holes", withQuantity: 2, withPrice: NSDecimalNumber(string: "84.99"), withCurrency: "USD", withSku: "Hip-0037")
let item2 = PayPalItem(name: "Free rainbow patch", withQuantity: 1, withPrice: NSDecimalNumber(string: "0.00"), withCurrency: "USD", withSku: "Hip-00066")
let item3 = PayPalItem(name: "Long-sleeve plaid shirt (mustache not included)", withQuantity: 1, withPrice: NSDecimalNumber(string: "37.99"), withCurrency: "USD", withSku: "Hip-00291")
let items = [item1, item2, item3]
let subtotal = PayPalItem.totalPrice(forItems: items)
let shipping = NSDecimalNumber(string: "5.99")
let tax = NSDecimalNumber(string: "2.50")
let paymentDetails = PayPalPaymentDetails(subtotal: subtotal, withShipping: shipping, withTax: tax)
let total = subtotal.adding(shipping).adding(tax)
let payment = PayPalPayment(amount: total, currencyCode: "USD", shortDescription: "Hipster Clothing", intent: .sale)
payment.items = items
payment.paymentDetails = paymentDetails
if (payment.processable) {
let paymentViewController = PayPalPaymentViewController(payment: payment, configuration: payPalConfig, delegate: self)
present(paymentViewController!, animated: true, completion: nil)
}
}
func payPalPaymentDidCancel(_ paymentViewController: PayPalPaymentViewController) {
resultText = ""
successView.isHidden = true
paymentViewController.dismiss(animated: true, completion: nil)
}
func payPalPaymentViewController(_ paymentViewController: PayPalPaymentViewController, didComplete completedPayment: PayPalPayment) {
paymentViewController.dismiss(animated: true, completion: { () -> Void in
self.resultText = completedPayment.description
self.showSuccess()
})
}
I am very puzzled why PayPalEnvironmentSandbox is no problem but the PayPalEnvironmentProduction can not be used properly

Related

How to write presentationWindow func in PKPaymentAuthorizationControllerDelegate protocol of the PassKit

May I please ask how can I write the presentationWindow function in the PKPaymentAuthorizationControllerDelegate protocol of the PassKit?
I wrote as below, it worked in iOS when the presentationWindow function is optional, so I did not write it at all, but in Mac catalyst, it must included, so it does not work when I wrote this, may I please ask what is wrong? Thank you very much for your time!
func presentationWindow(for controller: PKPaymentAuthorizationController) -> UIWindow? {
let paymentWindow:UIWindow=UIWindow(frame: CGRect(x: 0,y: 0,width: 200,height: 200))
return paymentWindow
}
and startPayment function I wrote:
func startPayment(completion: #escaping PaymentCompletionHandler) {
let amount = PKPaymentSummaryItem(label: "Ammount", amount: NSDecimalNumber(string: price), type: .final)
let tax = PKPaymentSummaryItem(label: "Tax", amount: NSDecimalNumber(string: "1.12"), type: .final)
let total = PKPaymentSummaryItem(label: "ToTal", amount: NSDecimalNumber(string: "10.00"), type: .pending)
paymentSummaryItems = [amount, tax, total];
completionHandler = completion
// Create our payment request
let paymentRequest = PKPaymentRequest()
paymentRequest.paymentSummaryItems = paymentSummaryItems
paymentRequest.merchantIdentifier = "merchant.com.YOURDOMAIN.YOURAPPNAME"
paymentRequest.merchantCapabilities = .capability3DS
paymentRequest.countryCode = "US"
paymentRequest.currencyCode = "USD"
paymentRequest.requiredShippingContactFields = [.phoneNumber, .emailAddress]
paymentRequest.supportedNetworks = PaymentHandler.supportedNetworks
// Display our payment request
paymentController = PKPaymentAuthorizationController(paymentRequest: paymentRequest)
paymentController?.delegate = self
//self.presentationWindow(for: paymentController!)
paymentController?.present(completion: { (presented: Bool) in
if presented {
NSLog("Presented payment controller")
} else {
NSLog("Failed to present payment controller")
self.completionHandler!(false)
}
})
}

Google Spreadsheets APIS, confused

I had this working before but now it seems to have stopped. I am trying to run various googlesheets APIS such as read/write/create. I have installed the appropriate cocoa pods:
platform :ios, '10.0'
target 'Safety_App-Prototype' do
use_frameworks!
pod 'GoogleAnalytics'
pod 'GoogleAPIClientForREST/Sheets'
pod 'GoogleAPIClientForREST/Drive'
pod 'GoogleSignIn'
pod 'SVProgressHUD'
pod 'Firebase/Core'
pod 'Firebase/Analytics'
pod 'Firebase/Auth'
pod 'Firebase/Firestore'
end
I have created a google developer console project and included all relevant information into my app. (this includes the URL type under projects -> info tab as well as in my app delegate shown below:
//
// AppDelegate.swift
// Created by Michael Szabo on 2021-01-28.
//
import UIKit
import GoogleSignIn
#main
class AppDelegate: UIResponder, UIApplicationDelegate, GIDSignInDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
GIDSignIn.sharedInstance().clientID = "FORMYEYESONLY.apps.googleusercontent.com"
GIDSignIn.sharedInstance().delegate = self
return true
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
return GIDSignIn.sharedInstance().handle(url as URL?,
sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String,
annotation: options[UIApplication.OpenURLOptionsKey.annotation])
}
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) {
if let error = error {
if (error as NSError).code == GIDSignInErrorCode.hasNoAuthInKeychain.rawValue {
print("The user has not signed in before or they have since signed out.")
} else {
print("\(error.localizedDescription)")
}
return
}
// Perform any operations on signed in user here.
let userId = user.userID // For client-side use only!
let idToken = user.authentication.idToken // Safe to send to the server
let fullName = user.profile.name
let givenName = user.profile.givenName
let familyName = user.profile.familyName
let email = user.profile.email
// ...
print(fullName)
}
func sign(_ signIn: GIDSignIn!, didDisconnectWith user: GIDGoogleUser!, withError error: Error!) {
// Perform any operations when the user disconnects from app here.
print("User has disconnected")
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
}
I have added a google signing button which allows me to sign in and asks for permission to read/write to sheets and added functions in my script to create/read/write to sheets as seen below:
// Created by Michael Szabo on 2021-02-21.
//
import GoogleAPIClientForREST
import GoogleSignIn
import UIKit
class JHA_pg1: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate, UITextFieldDelegate, GIDSignInUIDelegate, GIDSignInDelegate {
var rowstart:NSNumber = 0
var rowend:NSNumber = 0
var columnstart:NSNumber = 0
var columnend:NSNumber = 0
var red:NSNumber = 1
var blue:NSNumber = 1
var green:NSNumber = 1
var range1 = ""
var text1 = ""
var text2 = ""
var text3 = ""
var bordertype = "SOLID"
var borderthick:NSNumber = 3
var inbortype = "NONE"
var inborthick:NSNumber = 0
var spreadsheetId = ""
#IBOutlet weak var BeginAssessment: UIButton! //SubmitButton
let today = Date()
let formatter1 = DateFormatter()
let formatter = DateFormatter()
var date = String()
var buttontitle = String()
let defaults = UserDefaults.standard
private let scopes = [kGTLRAuthScopeSheetsSpreadsheets]
private let service = GTLRSheetsService()
//=========================================================================================================
//=========================================================================================================
override func viewDidLoad() {
super.viewDidLoad()
//=========================================================================================================
// Configure Google Sign-in.
GIDSignIn.sharedInstance().delegate = self
GIDSignIn.sharedInstance().uiDelegate = self
GIDSignIn.sharedInstance().scopes = scopes
GIDSignIn.sharedInstance().signInSilently()
}
//=========================================================================================================
//=========================================================================================================
//Submit Function
#IBAction func BeginAssessment(_ sender: Any) {
if(GIDSignIn.sharedInstance()?.currentUser != nil)
{
print("loggedIn")
}
else
{
print("not loggedIn")
}
spreadsheetId = "SOME ID"
rowstart = 0
rowend = 5
columnstart = 0
columnend = 7
unmergecell()
CreateSpreadSheet()
print(spreadsheetId)
}
//========================================================================================================
//Write To Sheet Function
func write() {
let range = range1
let updateValues = [[text1,text2,text3]]
let valueRange = GTLRSheets_ValueRange() // GTLRSheets_ValueRange holds the updated values and other params
valueRange.majorDimension = "ROWS" // Indicates horizontal row insert
valueRange.range = range
valueRange.values = updateValues
let query = GTLRSheetsQuery_SpreadsheetsValuesAppend.query(withObject: valueRange, spreadsheetId: spreadsheetId, range: range)
query.valueInputOption = "USER_ENTERED"
service.executeQuery(query) { ticket, object, error in}
}
//========================================================================================================
//Unmerge Cell Function
func unmergecell() {
let request = GTLRSheets_Request.init()
let test = GTLRSheets_GridRange.init()
test.startRowIndex = rowstart
test.endRowIndex = rowend
test.startColumnIndex = columnstart
test.endColumnIndex = columnend
request.unmergeCells = GTLRSheets_UnmergeCellsRequest.init()
request.unmergeCells?.range = test
let batchUpdate = GTLRSheets_BatchUpdateSpreadsheetRequest.init()
batchUpdate.requests = [request]
let createQuery = GTLRSheetsQuery_SpreadsheetsBatchUpdate.query(withObject: batchUpdate, spreadsheetId: spreadsheetId)
service.executeQuery(createQuery) { (ticket, result, NSError) in
}
}
}
//========================================================================================================
//Create Spreadsheet Function
func CreateSpreadSheet()
{
print("==============================================")
print("Createsheet Function")
let newSheet = GTLRSheets_Spreadsheet.init()
let properties = GTLRSheets_SpreadsheetProperties.init()
properties.title = "Daily JHA Form - "+date
newSheet.properties = properties
let query = GTLRSheetsQuery_SpreadsheetsCreate.query(withObject:newSheet)
query.fields = "spreadsheetId"
query.completionBlock = { (ticket, result, NSError) in
if let error = NSError {
print("error!!!!!!!!!!!!!!!!!!!!!!!!!!")
print(error)
}
else {
let response = result as! GTLRSheets_Spreadsheet
let identifier = response.spreadsheetId
self.spreadsheetId = identifier!
GlobalVariable1.sheetID = self.spreadsheetId
print(self.spreadsheetId)
}
}
service.executeQuery(query, completionHandler: nil)
}
//=========================================================================================================
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) {
if let error = error {
if (error as NSError).code == GIDSignInErrorCode.hasNoAuthInKeychain.rawValue {
print("The user has not signed in before or they have since signed out.")
} else {
print("\(error.localizedDescription)")
}
return
}
// Perform any operations on signed in user here.
let userId = user.userID // For client-side use only!
let idToken = user.authentication.idToken // Safe to send to the server
let fullName = user.profile.name
let givenName = user.profile.givenName
let familyName = user.profile.familyName
let email = user.profile.email
// ...
print(fullName)
}
//=========================================================================================================
// Display (in the UITextView) the names and majors of students in a sample
// spreadsheet:
//https://docs.google.com/spreadsheets/d/e/2PACX-1vTxKKu-0BwyOPq9HTYH237jGlMrf3q8kLwe5R2eH2dbkGqNbk3D7L9_MKxpO4b3g9cy09w2davohJzq/pubhtml
func listMajors() {
let range = "A1:Q"
let query = GTLRSheetsQuery_SpreadsheetsValuesGet
.query(withSpreadsheetId: spreadsheetId, range:range)
service.executeQuery(query) { (ticket, result, error) in
if let error = error {
self.showAlert(title: "Error", message: error.localizedDescription)
return
}
guard let result = result as? GTLRSheets_ValueRange else {
return
}
let rows = result.values!
if rows.isEmpty {
// self.output.text = "No data found."
return
}
// self.output.text = "Number of rows in sheet: \(rows.count)"
}
}
// Process the response and display output
func displayResultWithTicket(ticket: GTLRServiceTicket,
finishedWithObject result : GTLRSheets_ValueRange,
error : NSError?) {
if let error = error {
showAlert(title: "Error", message: error.localizedDescription)
return
}
var majorsString = ""
let rows = result.values!
if rows.isEmpty {
// output.text = "No data found."
return
}
majorsString += "Name, Major:\n"
for row in rows {
let name = row[0]
let major = row[4]
majorsString += "\(name), \(major)\n"
}
// output.text = majorsString
}
// Helper for showing an alert
func showAlert(title : String, message: String) {
let alert = UIAlertController(
title: title,
message: message,
preferredStyle: UIAlertController.Style.alert
)
let ok = UIAlertAction(
title: "OK",
style: UIAlertAction.Style.default,
handler: nil
)
alert.addAction(ok)
present(alert, animated: true, completion: nil)
}
}
struct GlobalVariable1
{
static var sheetID = ""
}
extension UIViewController {
func hideKeyboardWhenTappedAround() {
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard))
tap.cancelsTouchesInView = false
view.addGestureRecognizer(tap)
}
#objc func dismissKeyboard() {
view.endEditing(true)
}
}
HOWEVER I get the following error:
Optional(Error Domain=com.google.GTLRErrorObjectDomain Code=401 "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project." UserInfo={GTLRStructuredError=GTLRErrorObject 0x600001182310: {errors:[1] message:"Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project." code:401 status:"UNAUTHENTICATED"}, NSLocalizedDescription=Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.})"
What am I doing wrong?
Looking to the error generated by your code, and the scopes you try to require, it seems they are not enough. Indeed you set only:
private let scopes = [kGTLRAuthScopeSheetsSpreadsheets]
According to this google official doc about scopes you can find more details about all the scopes.
In the middle part of your code you read profile informations and these info could be readed adding scopes about google sign in:
profile
email
It appears that I was missing an instruction in my functions being called. I also had to update a bit of my code for newer pod file "pod 'GoogleSignIn', '~> 5.0.2'" The instructions for this migration can be found here:
https://developers.google.com/identity/sign-in/ios/quick-migration-guide
The portion of code I needed to add to my functions is a simple line which can be seen here:
service.authorizer = GIDSignIn.sharedInstance().currentUser.authentication.fetcherAuthorizer()
I hope this helps someone else out (pass it on.)
Thank you.

firebase upload after checkout

This is shopping app after user select the products send to cart then checkout after fill the fields and press Checkout (Pay) send the details of the products to my firebase database please any one can help me I use json as my load products on tableview cell
I know I don't have payment serves but on this fields of payment information will be name , phone number, and location
[{
"name": "EGG",
"price": "3.00",
"image": "http://partiklezoo.com/Egg/u0001.jpg",
"description": "one Egg",
"category": "Food",
"uid": "u0001"
},]
Code
import UIKit
class CheckoutViewController: DetailViewController, UITableViewDataSource, UITableViewDelegate, UIPickerViewDataSource, UIPickerViewDelegate {
#IBOutlet var cardNumber: UITextField!
#IBOutlet var cardExpiryMonth: UITextField!
#IBOutlet var cardExpiryYear: UITextField!
#IBOutlet var cardCvv: UITextField!
#IBOutlet var pickerPickupPoint: UIPickerView!
#IBOutlet var tableViewOrderDetails: UITableView!
#IBOutlet var labelTotalPrice: UILabel!
var model = SingletonManager.model
override func viewDidLoad() {
super.viewDidLoad()
self.configureCheckout()
self.tableViewOrderDetails.dataSource = self
self.tableViewOrderDetails.delegate = self
self.pickerPickupPoint.dataSource = self
self.pickerPickupPoint.delegate = self
//Looks for single or multiple taps.
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(CheckoutViewController.dismissKeyboard))
view.addGestureRecognizer(tap)
}
#objc func dismissKeyboard() {
//Causes the view (or one of its embedded text fields) to resign the first responder status.
self.view.endEditing(true)
}
func configureCheckout() {
pickerPickupPoint.selectedRow(inComponent: 0)
labelTotalPrice.text = "$" + String(format: "%.2f", model.calculateCartTotal())
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return model.cart.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = model.products[Int(model.cart[indexPath.row][0])].name
cell.detailTextLabel?.text = String(Int(model.cart[indexPath.row][1])) + " x $" + String(format: "%.2f", model.cart[indexPath.row][4])
return cell
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return model.pickUpLocations.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return model.pickUpLocations[row]["street"]! + ", " + model.pickUpLocations[row]["suburb"]!
}
#IBAction func payNow(_ sender: Any) {
var error = ""
if self.model.cart.count == 0 {
error = "Your cart is empty."
}
else if (self.cardNumber.text?.isEmpty)! {
error = "Please enter your card number."
}
else if (self.cardExpiryMonth.text?.isEmpty)! {
error = "Please enter the expiry month of your card."
}
else if (self.cardExpiryYear.text?.isEmpty)! {
error = "Please enter the expiry year of your card."
}
else if (self.cardCvv.text?.isEmpty)!{
error = "Please enter the CVV number of your card."
}
if error.isEmpty {
showAlertMsg("Confirm Purchase", message: "Pay " + labelTotalPrice.text!, style: UIAlertControllerStyle.actionSheet)
}
else {
showAlertMsg("Error", message: error, style: UIAlertControllerStyle.alert)
}
}
var alertController: UIAlertController?
func showAlertMsg(_ title: String, message: String, style: UIAlertControllerStyle) {
self.alertController = UIAlertController(title: title, message: message, preferredStyle: style)
if style == UIAlertControllerStyle.actionSheet {
alertController?.addAction(UIAlertAction(title: "Pay", style: .default, handler: { _ in
self.checkout()
}))
alertController?.addAction(UIAlertAction(title: "Cancel", style: .cancel))
} else {
alertController?.addAction(UIAlertAction(title: "Okay", style: .default))
}
self.present(self.alertController!, animated: true, completion: nil)
}
func checkout() {
var success = true
for count in 0...self.model.cart.count - 1 {
let product = self.model.products[Int(self.model.cart[count][0])]
let quantity = Int(self.model.cart[count][1])
let total = self.model.cart[count][4]
let material = self.model.cart[count][3] == 0.0 ? "pla" : "abs"
let painting = self.model.cart[count][2] == 0.0 ? "false" : "true"
let temp = self.model.purchase(product: product, quantity: quantity, total: total, material: material, painting: painting)
if !temp {
success = false
}
}
if !success {
let error = "Oops! Something went wrong. Please try again later."
showAlertMsg("Error", message: error, style: UIAlertControllerStyle.alert)
} else {
print("Success! Checkout complete.")
self.cardNumber.text = ""
self.cardExpiryMonth.text = ""
self.cardExpiryYear.text = ""
self.cardCvv.text = ""
self.labelTotalPrice.text = "$0.00"
self.model.clearCart()
self.tableViewOrderDetails.reloadData()
self.performSegue(withIdentifier: "Thankyou", sender: self)
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let confirmationVc = (segue.destination as! UINavigationController).topViewController as! ConfirmationViewController
confirmationVc.location = self.model.pickUpLocations[self.pickerPickupPoint.selectedRow(inComponent: 0)]
}
}
this is my objective
Class Model: NSObject, CLLocationManagerDelegate {
var segueArray = [String]()
var seguesDictionary = Dictionary<String, UIImage>()
var products = [Product]()
var storedProducts = [NSManagedObject]()
var cart = [[Double]]()
var storedCart = [NSManagedObject]()
var pickUpLocations = [[String: String]]()
let locationManager = CLLocationManager()
override init() {
super.init()
segueArray.append("Home")
segueArray.append("List")
segueArray.append("Search")
segueArray.append("Cart")
segueArray.append("Finder")
segueArray.append("Checkout")
seguesDictionary["Home"] = UIImage(named: "home")
seguesDictionary["List"] = UIImage(named: "list")
seguesDictionary["Search"] = UIImage(named: "search")
seguesDictionary["Cart"] = UIImage(named: "cart")
seguesDictionary["Finder"] = UIImage(named: "finder")
seguesDictionary["Checkout"] = UIImage(named: "checkout")
self.loadProducts()
self.refreshProducts()
self.loadCart()
self.configureLocManager()
}
func loadProducts() {
let managedContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Products")
do {
let results = try managedContext.fetch(fetchRequest)
storedProducts = results as! [NSManagedObject]
if storedProducts.count > 0 {
for index in 0...storedProducts.count - 1 {
let binaryData = storedProducts[index].value(forKey: "image") as! Data
let image = UIImage(data: binaryData)
let name = storedProducts[index].value(forKey: "name") as! String
let price = storedProducts[index].value(forKey: "price") as! Double
let details = storedProducts[index].value(forKey: "details") as! String
let category = storedProducts[index].value(forKey: "category") as! String
let uid = storedProducts[index].value(forKey: "uid") as! String
let loadedProduct = Product(name: name, price: price, image: image!, details: details, category: category, uid: uid)
products.append(loadedProduct)
}
}
}
catch let error as NSError
{
print("Could not load. \(error), \(error.userInfo)")
}
}
func refreshProducts() {
let url = NSURL(string: "http://partiklezoo.com/3dprinting/")
let config = URLSessionConfiguration.default
config.isDiscretionary = true
let session = URLSession(configuration: config)
let task = session.dataTask(with: url! as URL, completionHandler:
{(data, response, error) in
let json = JSON(data: data!)
for count in 0...json.count - 1
{
let newProduct = Product()
newProduct.name = json[count]["name"].string
newProduct.price = Double(json[count]["price"].string!)
newProduct.details = json[count]["description"].string
newProduct.category = json[count]["category"].string
newProduct.uid = json[count]["uid"].string
let imgURL = json[count]["image"].string!
self.addItemToList(newProduct, imageURL: imgURL)
}
})
task.resume()
}
func checkForProduct(_ searchItem: Product) -> Int {
var targetIndex = -1
if products.count > 0 {
for index in 0...products.count - 1 {
if products[index].uid == searchItem.uid {
targetIndex = index
}
}
}
return targetIndex
}
func addItemToList(_ newProduct: Product!, imageURL: String) {
if checkForProduct(newProduct) == -1 {
let managedContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let picture = UIImageJPEGRepresentation(loadImage(imageURL), 1)
let entity = NSEntityDescription.entity(forEntityName: "Products", in: managedContext)
let productToAdd = NSManagedObject(entity: entity!, insertInto: managedContext)
productToAdd.setValue(newProduct.category, forKey: "category")
productToAdd.setValue(newProduct.details, forKey: "details")
productToAdd.setValue(picture, forKey: "image")
productToAdd.setValue(newProduct.name, forKey: "name")
productToAdd.setValue(newProduct.price, forKey: "price")
productToAdd.setValue(newProduct.uid, forKey: "uid")
do
{
try managedContext.save()
}
catch let error as NSError
{
print("Could not save. \(error), \(error.userInfo)")
}
storedProducts.append(productToAdd)
newProduct.image = UIImage(data: picture!)
products.append(newProduct)
}
}
func loadCart() {
let managedContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Cart")
do {
let results = try managedContext.fetch(fetchRequest)
storedCart = results as! [NSManagedObject]
if storedCart.count > 0 {
for index in 0...storedCart.count - 1 {
let product = storedCart[index].value(forKey: "product") as! Double
let quantity = storedCart[index].value(forKey: "quantity") as! Double
let finish = storedCart[index].value(forKey: "finish") as! Double
let material = storedCart[index].value(forKey: "material") as! Double
let totalPrice = storedCart[index].value(forKey: "total") as! Double
let temp = [product, quantity, finish, material, totalPrice]
cart.append(temp)
}
}
}
catch let error as NSError
{
print("Could not load. \(error), \(error.userInfo)")
}
}
func addToCart(product: Product, quantity: Double, finish: Double, material: Double, totalPrice: Double) {
let managedContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "Cart", in: managedContext)
let productToAdd = NSManagedObject(entity: entity!, insertInto: managedContext)
productToAdd.setValue(checkForProduct(product), forKey: "product")
productToAdd.setValue(quantity, forKey: "quantity")
productToAdd.setValue(finish, forKey: "finish")
productToAdd.setValue(material, forKey: "material")
productToAdd.setValue(totalPrice, forKey: "total")
do
{
try managedContext.save()
}
catch let error as NSError
{
print("Could not save. \(error), \(error.userInfo)")
}
let temp = [Double(checkForProduct(product)), quantity, finish, material, totalPrice]
storedCart.append(productToAdd)
cart.append(temp)
}
I am not sure I understand the question but from the comments I believe the OP is asking for example code to put into an action button to write date to Firebase. So here it is.
(note: please see comments as the OP didn't clarify what he was after so it's not clear if this is an answer or not)
Start with initialzing Firebase in your view controller
class ViewController: UIViewController {
var ref: DatabaseReference!
override func viewDidLoad() {
super.viewDidLoad()
self.ref = Database.database().reference()
then lets have a button press write two cars to firebase in a 'car_list' node
#IBAction func button0Action(_ sender: Any) {
let itemDict0 = [
"Name": "Car",
"price": "2000"]
let itemDict1 = [
"Name": "Car",
"price": "3000"]
let carRef = self.ref.child("car_list")
carRef.childByAutoId().setValue(itemDict0)
carRef.childByAutoId().setValue(itemDict1)
}
and the result in Firebase looks like this
car_list
-LKYuRKpLL_JXsDGsYWY
Name: "Car"
Price: "2000"
-LKYuRKpLL_JXsDGsYWZ
Name: "Car"
Price: "3000"
EDIT: I had intially set this up like a grocery list per the data in the question but per a comment from the OP they want to make it cars and prices, so that's how it is now.

Edit Button Difficulties using Swift

I'm new to the coding world. I'm trying to incorporate an edit button. I got the button to show up while the user swipes to the right but I'm having trouble getting the edit button to work. When pressed, it should bring up the table were the user first input the data but with the information already placed in the fields.
For example: user fills in the artist, album and release date, the edit button should take them back to where they first put in the information but with the info already in place.
Here's the code I used for the edit button:
override func tableView(_ tableView: UITableView,
leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?
{
let modifyAction = UIContextualAction(style: .normal, title: "Update", handler: { (ac:UIContextualAction, view:UIView, success:(Bool) -> Void) in
print("Update action ...")
success(true)
})
modifyAction.title = "Edit"
modifyAction.backgroundColor = .blue
return UISwipeActionsConfiguration(actions: [modifyAction])
}
And here's the code for adding the content:
#IBOutlet var artisttextfield: UITextField!
#IBOutlet var albumtextfield: UITextField!
#IBOutlet var releasedatePicker: UIDatePicker!
override func viewDidLoad() {
super.viewDidLoad()
releasedatePicker.minimumDate = Date()
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func saveTapped( _ sender: UIBarButtonItem) {
let artist = artisttextfield.text ?? ""
let album = albumtextfield.text ?? ""
let releasedate = releasedatePicker.date
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let newRelease = Release_Date(context: context)
newRelease.artist = artist
newRelease.album = album
newRelease.release_date = releasedate as NSDate?
newRelease.release_dateId = UUID().uuidString
if let uniqueId = newRelease.release_dateId {
print("The freshreleaseId is \(uniqueId)")
}
do {
try context.save()
let message = "\(artist)'s new album \(album) releases Today!"
let content = UNMutableNotificationContent()
content.body = message
content.sound = UNNotificationSound.default()
var dateComponents = Calendar.current.dateComponents([.month, .day],
from: releasedate)
dateComponents.hour = 09
dateComponents.minute = 00
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents,
repeats: true)
if let identifier = newRelease.release_dateId {
let request = UNNotificationRequest(identifier: identifier,
content: content, trigger: trigger)
let center = UNUserNotificationCenter.current()
center.add(request, withCompletionHandler: nil)
}
} catch let error {
print("Could not save because of \(error).")
}
dismiss(animated: true, completion: nil)
print("Added a Release Date!")
print("Artist: \(newRelease.artist)")
print("Album: \(newRelease.album)")
print("Release Date: \(newRelease.release_date)")
}
#IBAction func cancelTapped(_ sender: UIBarButtonItem) {
dismiss(animated: true, completion: nil)
}
Here's viewWillAppear
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let fetchRequest = Release_Date.fetchRequest() as NSFetchRequest<Release_Date>
let sortDescriptor1 = NSSortDescriptor(key: "album", ascending: true)
let sortDescriptor2 = NSSortDescriptor(key: "artist", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor1, sortDescriptor2]
do {
freshreleases = try context.fetch(fetchRequest)
} catch let error {
print("Could not fetch because of error: \(error).")
}
tableView.reloadData()
}

UNLocationNotificationTrigger is not working

UNLocationNotificationTrigger is not working.
Even ,CLLocationManager didEnterRegion() is working.
I have added both locationManager.startMonitoring(for:region) and locationManager.startUpdatingLocation()
Even I tried by removing locationManager.startUpdatingLocation().But not working
func startMonitoring(list:List) {
if !CLLocationManager.isMonitoringAvailable(for: CLCircularRegion.self) {
return
}
self.list = list
let region = self.region(list: list)
self.locationBasedNotification(list: list, flag: true, region: region as! CLCircularRegion)
locationManager.startMonitoring(for:region)
locationManager.startUpdatingLocation()
}
func stopMonitoring(list:List) {
self.list = list
for region in locationManager.monitoredRegions {
let circularRegion = region as? CLCircularRegion
if circularRegion?.identifier == list.identifier {
self.locationBasedNotification(list: list, flag: false, region: circularRegion!)
locationManager.stopMonitoring(for: circularRegion!)
// monitoredRegions.removeValueForKey(region.identifier)
}
}
}
func locationBasedNotification(list:List,flag:Bool,region:CLCircularRegion) {
var trigger : UNLocationNotificationTrigger!
if flag == true {
self.locationIdentifier = "location"+String(list.seqNo)
let categoryIdentifier = "locationmyCategory"+String(list.seqNo)
let textIdentifier = "locationtext"+String(list.seqNo)
let action = UNNotificationAction(identifier: self.locationIdentifier!, title: "You, have entered \(list.storeName)", options: [])
let category = UNNotificationCategory(identifier: categoryIdentifier, actions: [action], intentIdentifiers: [], options: [])
UNUserNotificationCenter.current().setNotificationCategories([category])
trigger = UNLocationNotificationTrigger(region: region, repeats: true)
let content = UNMutableNotificationContent.init()
content.title = list.storeName
content.body = "They are \(list.totalItems) in Shopping List"
content.sound = UNNotificationSound.default()
content.categoryIdentifier = categoryIdentifier
let request = UNNotificationRequest(identifier: textIdentifier, content: content, trigger: trigger)
UNUserNotificationCenter.current().delegate = self
UNUserNotificationCenter.current().add(request) {(error) in
if let error = error {
print("Uh oh! We had an error: \(error)")
}
}
} else {
UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: ["locationIdentifier"+String(list.seqNo)])
}
}
please provide me input on this