How do I add pagination to my swiftui chat app - ios

I am trying to add pagination to my chat app using swiftui and firebase. I want to listen to the newest 20 messages and as soon as the user scrolls to the top, fetch the oldest messages and display them at the top (previous messages).
this is my current code but it doesn't work like it's supposed to.
Also the scrollview will just occasionally not scroll.
func loadMoreMessages(chatID: String){
guard !isLoading, hasMoreMessages else { return }
isLoading = true
COLLECTION_PERSONAL_CHAT.document(chatID).collection("Messages").order(by: "timeStamp", descending: false).start(afterDocument: firstSnapshot!).limit(to: 20).getDocuments { (snapshot, error) in
if let error = error {
print("Error fetching messages: \(error)")
self.isLoading = false
return
}
var messagesToAppend : [Message] = []
let dp = DispatchGroup()
var documents = snapshot!.documents
for document in documents {
dp.enter()
var data = document.data()
let id = data["id"] as? String ?? ""
let type = data["type"] as? String ?? ""
let value = data["value"] as? String ?? ""
let repliedMessageID = data["repliedMessageID"] as? String ?? ""
if type == "repliedMessage"{
dp.enter()
self.fetchReplyMessages(chatID: chatID, messageID: repliedMessageID) { fetchedReplyMessage in
data["repliedMessage"] = fetchedReplyMessage
dp.leave()
}
}
if type == "postMessage"{
dp.enter()
self.fetchPost(postID: value){ fetchedPost in
data["post"] = fetchedPost
dp.leave()
}
}
if type == "pollMessage"{
dp.enter()
self.fetchPoll(pollID: value){ fetchedPoll in
data["poll"] = fetchedPoll
dp.leave()
}
}
if type == "eventMessage"{
dp.enter()
self.fetchEvent(eventID: value){ fetchedEvent in
data["event"] = fetchedEvent
dp.leave()
}
}
dp.leave()
dp.notify(queue: .main, execute:{
self.isLoading = false
self.messages.insert(Message(dictionary: data), at: 0)
print("loaded 1 more message!")
})
}
}
}
func fetchAllMessages(chatID: String, userID: String){
//how to paginate
//1. listen to newest 20 messages [20,19,18,17,...,0]
//2. fetch 20 starting after the 20th
self.messages.removeAll()
self.chatListener = COLLECTION_PERSONAL_CHAT.document(chatID).collection("Messages").order(by: "timeStamp", descending: true).limit(to: 20).addSnapshotListener { snapshot, err in
if err != nil {
print(err!.localizedDescription)
return
}
var messagesToReturn : [Message] = []
let dp = DispatchGroup()
snapshot?.documentChanges.forEach({ doc in
dp.enter()
var data = doc.document.data()
let id = data["id"] as? String ?? ""
let type = data["type"] as? String ?? ""
let value = data["value"] as? String ?? ""
let repliedMessageID = data["repliedMessageID"] as? String ?? ""
if type == "repliedMessage"{
dp.enter()
self.fetchReplyMessages(chatID: chatID, messageID: repliedMessageID) { fetchedReplyMessage in
data["repliedMessage"] = fetchedReplyMessage
dp.leave()
}
}
if type == "postMessage"{
dp.enter()
self.fetchPost(postID: value){ fetchedPost in
data["post"] = fetchedPost
dp.leave()
}
}
if type == "pollMessage"{
dp.enter()
self.fetchPoll(pollID: value){ fetchedPoll in
data["poll"] = fetchedPoll
dp.leave()
}
}
if type == "eventMessage"{
dp.enter()
self.fetchEvent(eventID: value){ fetchedEvent in
data["event"] = fetchedEvent
dp.leave()
}
}
dp.leave()
dp.notify(queue: .main, execute:{
if doc.type == .added {
if !self.messages.contains(where: {$0.id == id}){
self.messages.append(Message(dictionary: data))
}
}else if doc.type == .removed{
self.messages.removeAll(where: {$0.id == id})
}else if let index = self.messages.firstIndex(where: {$0.id == id}) {
self.messages[index] = Message(dictionary: data)
}
})
//end of foreach document changes
})
self.firstSnapshot = snapshot!.documents.first
}
}
ScrollView{
ScrollViewReader { scrollViewProxy in
LazyVStack(spacing: 0){
ForEach(personalChatVM.messages.reversed().indices, id: \.self){ index in
MessageCell(message: personalChatVM.messages[index], selectedMessage: $selectedMessage,
showOverlay: $showOverlay, personalChatVM: personalChatVM).onAppear{
if index == 0{
print("seen top")
}
}
}
VStack{
ForEach(personalChatVM.chat.usersTyping){ user in
HStack{
if user.id == userVM.user?.id ?? " "{
Text("You are typing").foregroundColor(Color("AccentColor")).bold()
}else{
Text("\(user.nickName ?? "") is typing...").foregroundColor(Color("AccentColor")).bold()
}
Spacer()
}.padding(5)
}
}
HStack{Spacer()}.padding(0).id("Empty")
}.padding(.bottom, self.keyboardHeight)
}
}

Related

I have 2 view controllers with same logic but one of them is not working

I have 2 view models TransferViewModel which has the respective TransferViewController for making Local Transactions from a model LocalTransactionRequest and i have BankTransferViewModel which has a model BankTransactionsRequest, the first one is working but the second one is not, both view controllers are supposed to perform segue to another view controller ConfirmViewController, but the second one (BankTransferViewController) is not working
[This one is TransferViewController][1]
private func setupViewModel() {
viewModel.isTransfer = isTransfer
viewModel.loan = loan
viewModel.getBalance()
transferButton.rx.tap.asObservable().subscribe(onNext: { [weak self] _ in
guard let strongSelf = self else { return }
if let isVerified = UserManager.shared.get()?.IsVerified.value, isVerified{
strongSelf.viewModel.phoneNumberText.accept(strongSelf.phoneNumberTextField.text ?? "")
strongSelf.viewModel.amountText.accept(strongSelf.amountTextField.text ?? "")
strongSelf.viewModel.transfer()
}else{
strongSelf.showVerificationAlert()
}
}).disposed(by: disposeBag)
viewModel.accountInfo.asObservable().subscribe(onNext: { [weak self] accountInfo in
if let account = accountInfo{
guard let strongSelf = self else { return }
strongSelf.accountInfo = account
let request = LocalTransactionRequest(Identification: UserManager.shared.identification ?? "", Amount: Double(strongSelf.amountTextField.text!)!, ReceiverPhoneNumber: strongSelf.phoneNumberTextField.text!, IDBankAccount: UserManager.shared.defaultBankAccountId ?? -1, IsFromTransfer: strongSelf.isTransfer, Description: strongSelf.descriptionTF.text!)
strongSelf.transferRequest.accept(request)
strongSelf.performSegue(withIdentifier: "segue_toConfirmTransfer", sender: account)
}
}).disposed(by: disposeBag)
}
[This one is BankTransferViewController][2]
private func setupViewModel(){
viewModel.isTransfer = isTransfer
viewModel.getBalance()
transferButton.rx.tap.asObservable().subscribe(onNext: { [weak self] _ in
guard let strongSelf = self else { return }
if let isVerified = UserManager.shared.get()?.IsVerified.value, isVerified{
strongSelf.viewModel.bankNumberText.accept(strongSelf.bankNumberTextField.text ?? "")
strongSelf.viewModel.firstName.accept(strongSelf.firstNameTextField.text ?? "")
strongSelf.viewModel.lastName.accept(strongSelf.lastNameTextField.text ?? "")
strongSelf.viewModel.amountText.accept(strongSelf.amountTextField.text ?? "")
strongSelf.viewModel.descriptionText.accept(strongSelf.descriptionTF.text ?? "")
strongSelf.viewModel.transferNational()
}else{
strongSelf.showVerificationAlert()
}
}).disposed(by: disposeBag)
viewModel.transferRequest.asObservable().subscribe(onNext: { [weak self] bankRequest in
if let bank = bankRequest{
guard let strongSelf = self else { return }
strongSelf.bankTransferRequest = bank
let request = BankTransactionRequest(Identification: UserManager.shared.identification ?? "", ReceiverBankAccount: strongSelf.bankNumberTextField.text!, ReceiverFirst: strongSelf.firstNameTextField.text!, ReceiverLast: strongSelf.lastNameTextField.text!, Amount: Double(strongSelf.amountTextField.text!)!, Description: strongSelf.descriptionTF.text!)
strongSelf.nationalTransferRequest.accept(request)
DispatchQueue.main.async {
strongSelf.performSegue(withIdentifier: "segue_toConfirmTransfer", sender: bank)
}
}
}).disposed(by: disposeBag)
}
This is view model of BankTransferViewController
import RxCocoa
import RxSwift
class BankTransferViewModel: BaseViewModel {
private let transferUseCase: TransferUseCase
var accountInfo: BehaviorRelay<AccountExistModel?> = BehaviorRelay(value: nil)
var balance: BehaviorRelay<BalanceModel?> = BehaviorRelay(value: nil)
var bankNumberText: BehaviorRelay<String> = BehaviorRelay(value: "")
var firstName: BehaviorRelay<String> = BehaviorRelay(value: "")
var lastName: BehaviorRelay<String> = BehaviorRelay(value: "")
var amountText: BehaviorRelay<String> = BehaviorRelay(value: "")
var descriptionText: BehaviorRelay<String> = BehaviorRelay(value: "")
var transferRequest: BehaviorRelay<BankTransactionRequest?> = BehaviorRelay(value: nil)
var accountExist = PublishSubject<Bool>()
var hasMoney = PublishSubject<Bool>()
var invalidBankNumber = PublishSubject<Bool>()
var accountCannotRecieve = PublishSubject<Bool>()
var isTransfer : Bool = true
var transferPressed: AnyObserver<Void> {
return AnyObserver { [weak self] event in
switch event {
case .next:
guard let strongSelf = self else {
return
}
strongSelf.checkValidation()
default:
break
}
}
}
init(transferUseCase: TransferUseCase) {
self.transferUseCase = transferUseCase
}
func transferNational() {
self.checkValidation()
}
private func checkValidation() {
guard let balance = self.balance.value else {
state.onNext(.error(error: RepoError(with: "Dështoi verifikimi i disponueshmërisë financiare. Ju lusim të provoni më vonë.")))
return
}
if bankNumberText.value == ""{
state.onNext(.error(error: RepoError(with: "Plotëso fushën për numrin e bankës të pranuesit.")))
return
}
if bankNumberText.value.count < 6{
state.onNext(.error(error: RepoError(with:"Ju lutemi, shtypni një numër valid të gjirollogarisë")))
return
}
guard let doubleAmount = Double(amountText.value), doubleAmount > 0 else {
state.onNext(.error(error: RepoError(with: "Shuma jo e rregullt")))
return
}
if amountText.value == ""{
state.onNext(.error(error: RepoError(with: "Shuma jo e
saktë.")))
return
}
if balance.Balance < doubleAmount{
state.onNext(.error(error: RepoError(with: "Nuk keni fonde të mjaftueshme për realizimin e transaksionit.")))
return
}
if bankNumberText.value != "" && amountText.value != "" && (balance.Balance >= doubleAmount) {
// checkAccountExist()
}
}
func checkModulus16(accountNumber: String) -> Bool {
if accountNumber.isEmpty{
return false
}
let newValue = accountNumber.dropLast(2)
let mod = Int64(newValue + "00")! % 97
let result = 98 - mod
let derivedData = newValue + "" + (result < 10 ? "0\(result)" : "\(result)")
return Int64(derivedData) == Int64(accountNumber)
}
func showError(with message: String ) {
state.onNext(.error(error: RepoError(with: message)))
}
func getBalance(){
let params = ["Identification": UserManager.shared.identification ?? "" ] as ApiJson
transferUseCase.getBalance(with: params) {[weak self] (balance, error) in
guard let strongSelf = self else { return }
if let error = error {
strongSelf.state.onNext(.error(error: error))
strongSelf.accountExist.onNext(false)
}else if let balance = balance{
UserManager.shared.userBonus = balance.BonusAmount
strongSelf.state.onNext(.content)
strongSelf.balance.accept(balance)
strongSelf.accountExist.onNext(true)
UserManager.shared.updateBalance(with: balance)
}
}
}
//MARK: - baseViewModel
override func tryAgain() {
self.getBalance()
}
}
Make sure the following points are valid for your performSegue to work in BankTransferViewController:
The BankTransferViewController has a segue pointing to ConfirmViewController.
The identifier in your performSegue(withIdentifier: yourIdentifier, sender: yourModel) is the exact same identifier as the segue in storyboard that is connecting the two view controllers.
Since you are using it inside the viewModel.transferRequest.asObservable().subscribe(onNext: code, make sure you are emmiting a value to viewModel.transferRequest somewhere in the code. Otherwise, performSegue will never get called.
Since you have this check if let bank = bankRequest{ before using performSegue, make sure the transferRequest value you emmit is not nil.

getting 0 values inside my array from getdocument which insdie getdocuments

iam working with firestore i have two structs
one called history
aother called cart
simply hisory struct is
struct UserOrderHistoryModel {
var id : String? = ""
var dateOrderCreated : String? = ""
var cartArray : [CartItemModel]
}
struct CartItemModel {
var id : String? = ""
var restaurantImageUrl : String
var restaurantTitle : String
var menuItemImageUrl : String
var menuItemTitle : String
var countOfMenuItemSelected : Int
}
what i am trying to do is load history so i use getdocument to get the id and the date
i wanted to get order collection which inside history document
so i use another getdocuments inside the first one
func loadUserOrderHistory(completion : #escaping (_ error :Error? ,_ userHistoryArray : [UserOrderHistoryModel]?) -> ()) {
var historyArray = [UserOrderHistoryModel]()
let userHistoryRef = USERS.document(UserConfigurations.currentUserID!).collection("history")
userHistoryRef.getDocuments { (snapShots, error) in
if error != nil {
completion(error , nil)
}else {
historyArray.removeAll()
for document in snapShots!.documents {
let historyId = document.documentID
let historyData = document.data()
let historyDate = historyData["date_order_created"] as? Timestamp ?? nil
let historyDateToString = String(describing: historyDate?.dateValue())
var orderArray = [CartItemModel]()
self.loadUserHistoryOrders(histroyDocumentReference: userHistoryRef.document(historyId), completion: { (error, cartArray) in
if error != nil {
print(error!)
}else {
orderArray = cartArray!
}
})
let userHistory = UserOrderHistoryModel(id: historyId, dateOrderCreated: historyDateToString , cartArray: self.orderArray)
historyArray.append(userHistory)
}
completion(nil , historyArray)
}
}
}
private func loadUserHistoryOrders( histroyDocumentReference : DocumentReference, completion : #escaping (_ error : Error? ,_ historyOrders : [CartItemModel]? ) -> ()) {
var cartArray = [CartItemModel]()
histroyDocumentReference.collection("orders").getDocuments { (snapShot, error) in
if error != nil {
completion(error,nil)
}else {
for document in snapShot!.documents {
let id = document.documentID
let cartDictionary = document.data()
let restaurantImageUrl = cartDictionary["restaurant_imageurl"] as? String ?? "none"
let restaurantName = cartDictionary["restaurant_title"] as? String ?? "none"
let menuItemImageUrl = cartDictionary["menuItem_imageurl"] as? String ?? "none"
let menuItemName = cartDictionary["menuItem_title"] as? String ?? "none"
let count = cartDictionary["number_of_selected_menuitem"] as? Int ?? 0
let cart = CartItemModel(id: id, restaurantImageUrl: restaurantImageUrl, restaurantTitle: restaurantName, menuItemImageUrl: menuItemImageUrl, menuItemTitle: menuItemName, countOfMenuItemSelected: count)
cartArray.append(cart)
}
completion(nil , cartArray)
}
}
}
so orderArray inside second getdocumnet which i put it inside another function called loadUserHistoryOrders
i debugged the code and found that
once i get to end of the this function orderArray is back to 0 values
here is the pics of my firestore
url of pics : https://drive.google.com/open?id=1NX8NIUN2Yb9m3_7A8EnZgAxWe8xuhNDh
Update :
i solved the problem by adding completion of loadUserOrderHistory inside the call of the second method loadUserHistoryOrders
func loadUserOrderHistory(completion : #escaping (_ error :Error? ,_ userHistoryArray : [UserOrderHistoryModel]?) -> ()) {
var historyArray = [UserOrderHistoryModel]()
let userHistoryRef = USERS.document(UserConfigurations.currentUserID!).collection("history")
userHistoryRef.getDocuments { (snapShots, error) in
if error != nil {
completion(error , nil)
}else {
historyArray.removeAll()
for document in snapShots!.documents {
let historyId = document.documentID
let historyData = document.data()
let historyDate = historyData["date_order_created"] as? Timestamp ?? nil
let historyDateToString = String(describing: historyDate?.dateValue())
var orderArray = [CartItemModel]()
self.loadUserHistoryOrders(histroyDocumentReference: userHistoryRef.document(historyId), completion: { (error, cartArray) in
if error != nil {
print(error!)
}else {
orderArray = cartArray!
let userHistory = UserOrderHistoryModel(id: historyId, dateOrderCreated: historyDateToString , cartArray: self.orderArray)
historyArray.append(userHistory)
completion(nil , historyArray)
}
})
}
}
}
}

Display last message in chat with firestore

How I can get and display last message in my chat?
For test, I created four users with test messages. Now I can display only last message for all users. I mark red color.
Also I use firebase to save messages and create channels.
Struct in firebase look like this:
- Chats
- channel id
- document data (then be stored ID and NAME of channel)
- collection thread
- documents data (then be stored MESSAGES)
My struct in channel:
struct Channel {
let id: String?
let name: String
init(name: String) {
id = nil
self.name = name
}
init?(document: DocumentSnapshot) {
let data = document.data()!
guard let name = data["name"] as? String else {
return nil
id = document.documentID
self.name = name
}
}
extension Channel: DatabaseRepresentation {
var representation: [String : Any] {
var rep = ["name": name]
if let id = id {
rep["id"] = id
}
return rep
}
}
And my struct message, I use MessageKit:
struct Message: MessageType {
let id: String?
let content: String
let sentDate: Date
let sender: SenderType
var kind: MessageKind {
if let image = image {
return .photo(ImageMediaItem.init(image: image))
} else {
return .text(content)
}
}
var messageId: String {
return id ?? UUID().uuidString
}
var image: UIImage? = nil
var downloadURL: URL? = nil
init(profile: Profile, content: String) {
sender = Sender(id: profile.id, displayName: profile.name)
self.content = content
sentDate = Date()
id = nil
}
init?(document: QueryDocumentSnapshot) {
let data = document.data()
guard let sentDate = (data["created"] as? Timestamp)?.dateValue() else {
return nil
}
guard let senderID = data["senderID"] as? String else {
return nil
}
guard let senderName = data["senderName"] as? String else {
return nil
}
id = document.documentID
self.sentDate = sentDate
sender = Sender(id: senderID, displayName: senderName)
if let content = data["content"] as? String {
self.content = content
downloadURL = nil
} else if let urlString = data["url"] as? String, let url = URL(string: urlString) {
downloadURL = url
content = ""
} else {
return nil
}
}
}
extension Message: DatabaseRepresentation {
var representation: [String : Any] {
var rep: [String : Any] = [
"created": sentDate,
"senderID": sender.senderId,
"senderName": sender.displayName
]
if let url = downloadURL {
rep["url"] = url.absoluteString
} else {
rep["content"] = content
}
return rep
}
}
For load my chennels I use code below:
fileprivate func observeQuery() {
guard let query = query else { return }
listener = query.addSnapshotListener { (snapshot, error) in
guard let snapshot = snapshot else {
print("Error listening for channel updates: \(error?.localizedDescription ?? "No error")")
return
}
snapshot.documentChanges.forEach { (change) in
self.handleDocumentChange(change)
}
}
}
private func handleDocumentChange(_ change: DocumentChange) {
guard let channel = Channel(document: change.document) else {
return
}
switch change.type {
case .added:
addChannelToTable(channel)
case .modified:
updateChannelInTable(channel)
case .removed:
removeChannelFromTable(channel)
}
}
private func addChannelToTable(_ channel: Channel) {
guard !channels.contains(channel) else {
return
}
channels.append(channel)
channels.sort()
guard let index = channels.index(of: channel) else {
return
}
tableView.insertRows(at: [IndexPath(row: index, section: 0)], with: .automatic)
}
private func updateChannelInTable(_ channel: Channel) {
guard let index = channels.index(of: channel) else {
return
}
channels[index] = channel
tableView.reloadRows(at: [IndexPath(row: index, section: 0)], with: .automatic)
}
private func removeChannelFromTable(_ channel: Channel) {
guard let index = channels.index(of: channel) else {
return
}
channels.remove(at: index)
tableView.deleteRows(at: [IndexPath(row: index, section: 0)], with: .automatic)
}
I think need update my Channel struct. But how to do it?
And how to correct load and display last message from firebase?
If need more info pls tell me, I will update my question.
If the question is how to get only the last message from Firestore, you need to define how to determine what the last message is. That's usually done via a timestamp - the latest timestamp will be the last message.
The structure in the question is a little unclear so let me provide a simple example.
messages //collection
document_0 //documentID auto-generated
msg: "Last Message"
timestamp: "20191201"
document_1
msg: "First message"
timestamp: "20190801"
document_2
msg: "A message in the middle"
timestamp: "20191001"
As you can see, no matter what order they are written to Firestore, it's clear that the one with the latest timestamp (20191201 ) is the last message.
To get the last message we need a query that does two things:
1) Query the messages node, sort descending, which will put the last message 'at the top'
2) Limit the query to 1, which will get that message.
func readLastMessage() {
let ref = Firestore.firestore().collection("messages").order(by: "timestamp", descending: true).limit(to: 1)
ref.getDocuments(completion: { querySnapshot, error in
guard let snapshot = querySnapshot else {
print("Error fetching snapshots: \(error!)")
return
}
if let doc = snapshot.documents.first {
let docID = doc.documentID
let msg = doc.get("msg")
print(docID, msg)
}
})
}
and the output
Last Message
The above code gets the last message but could be expanded upon by adding an observer instead of getDocuments in the same fashion that will notify the app when there's a new last message.

DatabaseReference.observe is not called in swift4

I am trying to fetch the data from firebase. I am calling a function which has a databaseReference but it is not calling up.Basically this function is also called from databaseRefernce only of another function.
Here is my code:
func prepareCoursesFromCourseNodewithAllCoursesList(allCourseList: [Any]){
var courseDetailsNode = String()
var courseCount = allCourseList.count
weak var weakSelf = self
var courseId = String()
var localCoursesAndCardDictionary = [AnyHashable: Any]()
for singleCourse in allCourseList as! [[String:Any]] {
if singleCourse["elementId"] != nil {
courseId = "\(String(describing: singleCourse["elementId"]!))"
}else{
if singleCourse["currentCourseId"] != nil {
courseId = "\(String(describing: singleCourse["currentCourseId"]!))"
}
}
if singleCourse["parentNodeName"] != nil {
if singleCourse["parentNodeName"] as! String == "course" {
//this is course
courseDetailsNode = IMERCOURSE_URL
}
else {
//this is course Collection
courseDetailsNode = IMERCOURSECOLLECTION_URL
}
}
var reference = DatabaseReference()
let courseURL = "\(FIREBASE_URL)\(courseDetailsNode.replacingOccurrences(of: "{Id}", with: courseId))"
reference = Database.database().reference(fromURL: courseURL)
self.addIntoListFirebaseRef(firebaseRef: ref)
reference.observe(DataEventType.value, with: { (snapShot:DataSnapshot) in
courseCount -= 1
if snapShot.value != nil {
let singleCourseDictionary = snapShot.value as? [String: Any]
localCoursesAndCardDictionary[courseId] = singleCourseDictionary
self.settingUserDetailsViewData()
(Constants.sharedTools() as AnyObject).hideProgressIndicator()
}
}
}, withCancel: { (error:Error) in
})
}
}
}
this prepareCoursesFromCourseNodewithAllCoursesList(allCourseList: [Any]) is called from another databaseRefernce.ObserveEevnt
value.

Return statement in nested if function

I have been struggling with something for a while.
How can I return something in a nested if function?
The function below has the task of finding out if the userProfile has a verified card or not, if verified == 1 (true) then return true, else return false.
func userHasVerfifiedCard() -> Bool{
let userDocument = users.documentWithID(Meteor.userID!)
if let card = userDocument.valueForKey("profile")!["card"] {
print("has card")
if let verified = card!["verified"] as? Int {
print("card.verified as Int")
if verified == 1{
print("card.verified == 1")
lastFourCreditCardLbl.text = card!["last4"] as? String
return true
}else {
return false
}
}
}
your method won't return anything, if if let card won't work. But it must return a bool in any case.
func userHasVerfifiedCard() -> Bool {
let userDocument = users.documentWithID(Meteor.userID!)
if let card = userDocument.valueForKey("profile")!["card"] {
print("has card")
if let verified = card!["verified"] as? Int {
print("card.verified as Int")
if verified == 1 {
print("card.verified == 1")
lastFourCreditCardLbl.text = card!["last4"] as? String
return true
}
}
}
return false
}
Try this and let me know if it's helps..!
func userHasVerfifiedCard() -> Bool{
let userDocument = users.documentWithID(Meteor.userID!)
if let card = userDocument.valueForKey("profile")!["card"], verified = card!["verified"] as? Int where verified == 1 {
return true
} else {
return false
}
}

Resources