PayPal Integration with IOS swift - ios

How to get created_time and id after payment success?
i can get confirmation only "completedPayment.confirmation"

Chek this PayPal delegate method
func payPalPaymentViewController(_ paymentViewController: PayPalPaymentViewController, didComplete completedPayment: PayPalPayment)
{
print("PayPal Payment Success !")
paymentViewController.dismiss(animated: true, completion: { () -> Void in
// send completed confirmaion to your server
print("Here is your proof of payment:\n\n\(completedPayment.confirmation)\n\nSend this to your server for confirmation and fulfillment.")
let dict = completedPayment.confirmation
print("dict data is ====%#", dict)
let paymentResultDic = completedPayment.confirmation as NSDictionary
let dicResponse: AnyObject? = paymentResultDic.object(forKey: "response") as AnyObject?
let paycreatetime:String = dicResponse!["create_time"] as! String
let payauid:String = dicResponse!["id"] as! String
let paystate:String = dicResponse!["state"] as! String
let payintent:String = dicResponse!["intent"] as! String
print("id is --->%#",payauid)
print("created time ---%#",paycreatetime)
print("paystate is ----->%#",paystate)
print("payintent is ----->%#",payintent)
})
}

Related

Swift: Trying to set a ui button title using a completion handler

I am trying to use data from firebase to populate buttons on the UI. Everything works as expected except the button title is not updating. Any ideas on how to fix this?
#IBAction func addNewTapped(_ sender: Any) {
readOneDay2(lastMonday(trackerDate), completion: { message in
let lastHourRead = message
print(message)
self.lastHour1.setTitle(lastHourRead, for: UIControl.State.application)
})
}
func readOneDay2 (_ mydate: Date, completion: #escaping (_ message: String) -> Void){
var db: DatabaseReference!
db = Database.database().reference()
var totalComb: Double = 0.0
let userID = Auth.auth().currentUser?.uid
db.child("TimesheetData").child(userID!).observeSingleEvent(of: .value, with: { (snapshot) in
// Get user value
let dict = snapshot.value as? NSDictionary
for (key, value) in dict! {
let myvalue = value as? [String: Any]
let compDate: String = myvalue!["timeSheetDate"]! as! String
if compDate == dateStringer(mydate) {
let sHours: String = myvalue!["hours"]! as! String
let sOverTime: String = myvalue!["overTime"]! as! String
let sDoubleTime: String = myvalue!["doubleTime"]! as! String
let dHours: Double = Double(sHours)!
let dOverTime: Double = Double(sOverTime)!
let dDoubleTime: Double = Double(sDoubleTime)!
totalComb = totalComb + dHours + dOverTime + dDoubleTime
print(key)
}
}
print("First Sum " + String(totalComb))
DispatchQueue.main.async {
completion(String(totalComb))
}
}) { (error) in
print(error.localizedDescription)
}
}
As per #Virender said,
Change UIControl.State.application to UIControl.State.normal
DispatchQueue.main.async {
self.lastHour1.setTitle(lastHourRead, for:.normal)
}

Issues retrieving notificationTypes from Firebase

I have a bit of a lengthy question, So I apologize in advance I will try to illustrate this to the best of my abilities. I am trying to establish a notifications view controller that calls different types of data from Firebase and sets different notification types.
In the image above, this is how the cells should look when a user sends a notification to firebase. The user associated with that specific notification type as called and posted onto the screen.
In the firebase structure, We see that all of the information Stored is saved under the UID of the user in the first picture and is set under that specific users notification to show who is sending them a notification which is correct. These users names and images show perfectly as well as the image on the right.
The code I use to save this information is below,
fileprivate func saveSwipeToDataBase(didLike: Any) {
let swipeDate = Int(NSDate().timeIntervalSince1970)
guard let uid = Auth.auth().currentUser?.uid else { return }
guard let cardUID = topCardView?.cardViewModel.uid else { return }
let documentData = ["workerId": uid,
"didLike": didLike,
"checked": 0,
"Swipe Date": swipeDate,
"type": SWIPE_INT_VALUE,
"posterId" : cardUID] as [String : Any]
self.postJobNotificationsIntoDatabseWithUID(uid: cardUID, values: documentData as [String : AnyObject])
}
private func postJobNotificationsIntoDatabseWithUID(uid: String, values: [String: AnyObject]) {
let ref = Database.database().reference(fromURL: "https://oddjobs-b131f.firebaseio.com/")
let usersReference = ref.child("notifications").child(uid).childByAutoId()
usersReference.setValue(values, withCompletionBlock: { (err, ref) in
if err != nil {
print("error saving data into firebase")
return
}
})
}
And below is how I retrieve this information and store it onto the Notifications View controller.
func fetchNotifications() {
guard let currentUID = Auth.auth().currentUser?.uid else { return }
NOTIFICATIONS_REF.child(currentUID).observeSingleEvent(of: .value) { (snapshot) in
guard let dictionary = snapshot.value as? Dictionary<String, AnyObject> else { return }
print(dictionary)
for (_, postingRawData) in dictionary {
guard let postingDictionary = postingRawData as? Dictionary<String, AnyObject> else { continue }
guard let uid = postingDictionary["workerId"] as? String else { continue }
Database.fetchUser(with: uid, completion: { (user) in
if let postId = postingDictionary["posterId"] as? String {
Database.fetchPoster(with: postId, completion: {(poster) in
let notification = userNotifications(user: user, poster: poster, dictionary: postingDictionary)
self.notifications.append(notification)
self.handleSortNotification()
})
} else {
let notification = userNotifications(user: user, dictionary: postingDictionary)
self.notifications.append(notification)
self.handleSortNotification()
}
})
}
}
}
Now that I got the correct way to setup up and show out of the way, I will show my enum and how I am distinguishing the different types of calls from firebase.
class userNotifications {
// MARK: - establish notificationTypes
enum NotificationType: Int, Printable {
case swipe
case accepted
case confirmed
case completed
case pay
var description: String {
switch self {
case .swipe: return " swiped on your Job "
case .accepted: return " accepted you to complete the job, "
case .confirmed: return " confirmed the job"
case .completed: return " completed the job"
case .pay: return " pay for completed"
}
}
init(index: Int) {
switch index {
case 0: self = .swipe
case 1: self = .accepted
case 2: self = .confirmed
case 3: self = .completed
case 4: self = .pay
default: self = .swipe
}
}
}
// MARK: - access firebaseData
var creationDate: Date!
var timeDate: Date!
var uid: String!
var fromId: String?
var workerId: String?
var user: User!
var poster: Poster!
var type: Int?
var notificationType: NotificationType!
var didCheck = false
init(user: User? = nil, poster: Poster? = nil, dictionary: Dictionary<String, AnyObject>) {
self.user = user
if let poster = poster {
self.poster = poster
}
if let swipeDate = dictionary["Swipe Date"] as? Double {
self.creationDate = Date(timeIntervalSince1970: swipeDate)
}
if let createDate = dictionary["creationDate"] as? Double {
self.creationDate = Date(timeIntervalSince1970: createDate)
}
if let swipeDate = dictionary["time&date"] as? Double {
self.timeDate = Date(timeIntervalSince1970: swipeDate)
}
if let type = dictionary["type"] as? Int {
self.notificationType = NotificationType(index: type)
}
if let uid = dictionary["uid"] as? String {
self.uid = uid
}
if let fromId = dictionary["fromId"] as? String {
self.fromId = fromId
}
if let workerId = dictionary["workerUID"] as? String {
self.workerId = workerId
}
if let checked = dictionary["checked"] as? Int {
if checked == 0 {
self.didCheck = false
} else {
self.didCheck = true
}
}
}
}
Above is the different types of notifications to be set.
Now, My issue is If I call a different notification type, such as .accepted, the information calls in a very different way.
The image above seems correct, However, the name and image are incorrect. it should be from the user ZacheryWilcox instead of Cjbwjdhbe. the user Cjbwjdhbe is the current user and the user who should be receing a notification from Zacherywilcox. not from itself.
In firebase, the information is saved as
the code I use to save this information is below
var workerUser: User? {
didSet {
let name = workerUser?.name
workerNameLabel.text = name
let workersUID = workerUser?.uid
workerNameLabel.text = name
guard let profileImage = workerUser?.profileImageUrl else { return }
workerImageView.loadImageUsingCacheWithUrlString(profileImage)
}
}
func saveUserData() {
let workUser = self.workerUser
guard let uid = Auth.auth().currentUser?.uid else { return }
let workerId = workUser?.uid
Database.database().reference().child("users").child(uid).observeSingleEvent(of: .value, with: { (snapshot) in
guard let dictionary = snapshot.value as? [String : Any] else { return }
let user = User(dictionary: dictionary as [String : AnyObject])
workUser?.uid = snapshot.key
self.datePicker.datePickerMode = UIDatePicker.Mode.date
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMMM dd yyyy/ hh:mm a"
let selectedDate = dateFormatter.string(from: self.datePicker.date)
let creationDate = Int(NSDate().timeIntervalSince1970)
print(selectedDate)
let docData: [String: Any] = [
"workerId": workerId!,
"time&date": selectedDate,
"posterId" : uid,
"creationDate": creationDate,
"location": user.address!,
"type": 1,
"jobPost": "someUIDString",
"checked": 0,
]
self.postJobNotificationsIntoDatabseWithUID(uid: workerId!, values: docData as [String : AnyObject])
}, withCancel: { (err) in
print("attempting to load information")
})
print("Finished saving user info")
self.dismiss(animated: true, completion: {
print("Dismissal complete")
})
}
private func postJobNotificationsIntoDatabseWithUID(uid: String, values: [String: AnyObject]) {
let ref = Database.database().reference(fromURL: "https://oddjobs-b131f.firebaseio.com/")
let usersReference = ref.child("notifications").child(uid).childByAutoId()
usersReference.setValue(values, withCompletionBlock: { (err, ref) in
if err != nil {
print("error saving data into firebase")
return
}
})
}
When the type .accepted is being used to differentiate what notificationType is being called, the user who sent the notification is not being set correctly and I have no idea what is the reasoning behind this. The correct user that is sending this information over is Zacherywilcox, and that users image and name should be set to the user's notification screen. not the user Cjbe... I was wondering if anyone could help me fix these issues. Thank you in advance. I'm starting to think that the way I am saving the users information when accepting the user is incorrect.
When I am fetchingNotifications(), is it possible that since calling
guard let uid = postingDictionary["workerId"] as? String else { continue }
Database.fetchUser(with: uid, completion: { (user) in
if let postId = postingDictionary["posterId"] as? String {
has an effect on whats going on? if so, Is there a way to differentiate between what notificationType is being called and fetch what notifications has been called with their respective users?
Just update your code to:
func fetchNotifications() {
guard let currentUID = Auth.auth().currentUser?.uid else { return }
NOTIFICATIONS_REF.child(currentUID).observeSingleEvent(of: .value) { (snapshot) in
guard let dictionary = snapshot.value as? Dictionary<String, AnyObject> else { return }
print(dictionary)
let notificationId = snapshot.key
for (_, postingRawData) in dictionary {
guard let postingDictionary = postingRawData as? Dictionary<String, AnyObject> else { continue }
guard let type = postingDictionary["type"] as? Int else { continue }
guard let uid = (type == userNotifications.NotificationType.accepted.rawValue) ? postingDictionary["fromId"] as? String : postingDictionary["workerId"] as? String else { continue }
Database.fetchUser(with: uid, completion: { (user) in
if let postId = postingDictionary["fromId"] as? String {
Database.fetchPoster(with: postId, completion: {(poster) in
let notification = userNotifications(user: user, poster: poster, dictionary: postingDictionary)
self.notifications.append(notification)
self.handleSortNotification()
})
} else {
let notification = userNotifications(user: user, dictionary: postingDictionary)
self.notifications.append(notification)
self.handleSortNotification()
}
// NOTIFICATIONS_REF.child(currentUID).child(notificationId).child("checked").setValue(1)
})
}
}
}
This will solve your problem.

Issue in getting payload data from notification in iOS

I'm getting a notification from server side and I'm trying to get data from it, My payload is this:
[AnyHashable("title"): New message received, AnyHashable("gcm.notification.data"): {"FilePath":null,"IsAttachment":false,"UserName":"Muhammad Hassan","User":null,"StrUnPublishDate":null,"Message":"Eggshells","UserImage":"http:\/\/gigjobsadmin.arhamsoft.com\/Content\/User\/36\/16-04-2019 11-460.jpg","User1":null,"ToUserID":null,"ToUserId":132,"SenderId":null,"IsRead":false,"Code":null,"StrPublishDate":null,"StrDateTime":null,"Type":null,"Active":null,"StrCreatedDate":null,"ThreadId":46,"Search":null,"FromUserId":36,"CreatedDate":"2019-06-10T23:00:43.5972809Z","Id":1109,"BatchCount":0}, AnyHashable("gcm.message_id"): 0:1560171729408562%3724072637240726, AnyHashable("data"): {"FilePath":null,"IsAttachment":false,"UserName":"Muhammad Hassan","User":null,"StrUnPublishDate":null,"Message":"Eggshells","UserImage":"http:\/\/gigjobsadmin.arhamsoft.com\/Content\/User\/36\/16-04-2019 11-460.jpg","User1":null,"ToUserID":null,"ToUserId":132,"SenderId":null,"IsRead":false,"Code":null,"StrPublishDate":null,"StrDateTime":null,"Type":null,"Active":null,"StrCreatedDate":null,"ThreadId":46,"Search":null,"FromUserId":36,"CreatedDate":"2019-06-10T23:00:43.5972809Z","Id":1109,"BatchCount":0}, AnyHashable("body"): Eggshells, AnyHashable("badge"): 1, AnyHashable("google.c.a.e"): 1, AnyHashable("aps"): {
alert = {
body = Eggshells;
title = "New message received";
};
badge = 1;
category = ".MainActivity";
"content-available" = 1;
}]
When i get aps from it, it works fine but when i try to gata from "data" key it shows me nil. This is how am i getting values,
let delegate = UIApplication.shared.delegate as! AppDelegate
let userInfo = delegate.userInfo
print(userInfo!)
let data = userInfo!["data"] as? NSDictionary
let message = data!["Message"] as? String
let userImage = data!["UserImage"] as? String
let fromUserId = data!["FromUserId"] as? Int
let createdDate = data!["CreatedDate"] as? String
guard
let aps = userInfo![AnyHashable("aps")] as? NSDictionary,
let alert = aps["alert"] as? NSDictionary,
let body = alert["body"] as? String,
let title = alert["title"] as? String
else {
// handle any error here
return
}
guard let badge = userInfo![AnyHashable("badge")] as? Int
else
{
return
}
The value for key data is a JSON String, not a dictionary. You have to deserialize it separately
struct NotificationData : Decodable {
let message : String
let userImage : URL
let fromUserId : Int
let createdDate : String
private enum CodingKeys: String, CodingKey { case message = "Message", userImage = "UserImage", fromUserId = "FromUserId", createdDate = "CreatedDate" }
}
let delegate = UIApplication.shared.delegate as! AppDelegate
guard let userInfo = delegate.userInfo as? [String:Any],
let notificationString = userInfo["data"] as? String else { return }
let data = Data(notificationString.utf8)
do {
let result = try JSONDecoder().decode(NotificationData.self, from: data)
let message = result.message
let userImage = result.userImage
let fromUserId = result.fromUserId
let createdDate = result.createdDate
} catch { print(error) }
Replace
let data = userInfo!["data"] as? NSDictionary
To
if let data = userInfo!["data"] as? [AnyHashable, Any]{
print(data)
}

App Crashes When Observing Real Time Chat Data with Firebase-iOS

I am currently learning Swift and I decided to make an iOS messaging app using Firebase. I am using JSQMessageViewController as my chat template and everything is working fine except for the fact that the app crashes when two users talking to each other are in the chat room at the same time. I am getting this error near the bottom of the function below: "Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)"
Here is my code for observing and retrieving message data. I call this everytime the view appears:
private func observeMessages() {
messageRef = ref.child("ChatRooms").child(chatRoomId!).child("Messages")
let messageQuery = messageRef.queryLimited(toLast:25)
newMessageRefHandle = messageQuery.observe(.childAdded, with: { (snapshot) in
let messageData = snapshot.value as! Dictionary<String, AnyObject>
if let data = snapshot.value as? [String: AnyObject],
let id = data["sender_id"] as? String,
let name = data["name"] as? String,
let text = data["text"] as? String,
let time = data["time"] as? TimeInterval,
!text.isEmpty
{
if id != uid! {
let updateRead = ref.child("ChatRooms").child(self.chatRoomId!).child("Messages").child(snapshot.key)
updateRead.updateChildValues(["status":"read"])
}
if let message = JSQMessage(senderId: id, senderDisplayName: name, date: Date(timeIntervalSince1970: time), text: text)
{
self.messages.append(message)
self.finishReceivingMessage()
}
}else if let id = messageData["senderId"] as! String!,
let photoURL = messageData["photoURL"] as! String! { // 1
if let mediaItem = JSQPhotoMediaItem(maskAsOutgoing: id == self.senderId) {
self.addPhotoMessage(withId: id, key: snapshot.key, mediaItem: mediaItem)
if photoURL.hasPrefix("gs://") {
self.fetchImageDataAtURL(photoURL, forMediaItem: mediaItem, clearsPhotoMessageMapOnSuccessForKey: nil)
}
}
}else {
print("Error! Could not decode message data")
}
})
updatedMessageRefHandle = messageRef.observe(.childChanged, with: { (snapshot) in
let key = snapshot.key
//I am getting an error on this line
let messageData = snapshot.value as! Dictionary<String, String>
if let photoURL = messageData["photoURL"] as String! {
// The photo has been updated.
if let mediaItem = self.photoMessageMap[key] {
self.fetchImageDataAtURL(photoURL, forMediaItem: mediaItem, clearsPhotoMessageMapOnSuccessForKey: key)
}
}
})
}
Curious to what I might be doing wrong here. All help is appreciated!

How to navigate to another viewcontroller after getting response from the server

I am trying to login through the swift.
I am getting the proper data in the form of json and able to extract the data, but when I try to print the success message in the terminal then I need to press the login button twice.
#IBAction func loginButton(sender: UIButton) {
//test.text = usernameText.text
let user = usernameText.text!
let pass = passwordText.text!
let a = "http://www.example.com/app/login.php?username="
let b = "&password="
let c = a + user + b + pass
let url = NSURL(string: "\(c)")!
let task = NSURLSession.sharedSession().dataTaskWithURL(url) { (data, response, error) -> Void in
if let urlContent = data {
do {
let jsonResult: NSDictionary = try NSJSONSerialization.JSONObjectWithData(urlContent, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary
if let custdetails : [NSDictionary] = jsonResult["data"] as? [NSDictionary] {
for person: NSDictionary in custdetails {
//for (name,value) in person {
// print("\(name) , \(value)")
//print(person.valueForKey("CustId")!)
//}
let userid:String = person.valueForKey("CustId") as! String
print(userid)
//NSUserDefaults.standardUserDefaults().setBool(true, forKey: "IsUserLoggedIn")
NSUserDefaults().setString(userid, forKey: "userName")
NSUserDefaults.standardUserDefaults().synchronize()
self.dismissViewControllerAnimated(true, completion: nil)
self.message = jsonResult["message"] as! String
}
}
} catch {
print("JSON serialization failed")
}
}
}
task.resume()
print(message)
//navingation code
}
I have printed the userid when I get from the json
SO when I click on the login button I can see the id in the console, but cant see the message which I have printed on the second last line
When I again click on the login button then message is printed and the id is also printed again which means my code runs second time.
Thanks for helping me in advance
Any help will be appreciated.
You need to dispatch_async your JSON results. You can read up more here. You can also use AlamoFire or SwiftyJSON to help you with this. These are very good JSON tools. You can google them.
First, declare your userid variable outside of the JSON response. Preferably at the first line of your method. Then update your codes as below.
for person: NSDictionary in custdetails {
userid = person.valueForKey("CustId") as! String
} dispatch_async(dispatch_get_main_queue(),{
print(userid)
if(userid != ""){
self.dismissViewControllerAnimated(true, completion: nil)
self.message = jsonResult["message"] as! String
}
})

Resources