Swift Firestore using an Array to get document fields - arrays

I am using an array named PosterEmail to search for a document field name "First Name" in my Firestore Database.
Here you can see my database set up.
FirebaseSetup
enter image description here
As you can see my Database is Public then in the document I have the user's email as the document name and in that document I have their information such as their first name, last name, and profile photo url.
I search for the document id using an Array
The PosterEmail array is
PosterEmail = ["chainsawloco#yahoo.com", "allmight#gmail.com", "allmight#gmail.com", "chainsawloco#yahoo.com"]
I am going through my PosterEmail index by setting a variable "profilecount" to 0 and adding 1 to it everytime to go through the PosterArray
let docRef = db.collection("Public").document("\(self.PosterEmail[self.profilecount])")
But it seems that the code above never searches for the Firebase document named after the second item in my Array
The result is just
["Irving ", "Irving ", "Irving ", "Irving "]
The result should end up as [Irving, Allmight, Allmight, Irving]
Is there something I"m doing wrong?
Below is where I call my getPosteInformation() in another method called getDatFromFirestore() (ehhh I know my method name has a typo but I can fix that later)
if let postedBy = document.get("postedBy") as? String {
print("Postby = document.get(postedby = \(postedBy)")
self.PosterEmail.append(postedBy)
if self.PosterEmail.count > 0 {
self.getPosteInformation()
}
}
}
}
}
Below you can see my full code.
func getDatFromFirestore() {
let firestoreDatabase = Firestore.firestore()
firestoreDatabase.collection("Posts").order(by: "Date" , descending : true).getDocuments { (snapshot, error) in
if error != nil {
print(error?.localizedDescription ?? "Connection Error")
} else {
self.userPostImageArray.removeAll(keepingCapacity: false)
self.userCommentArray.removeAll(keepingCapacity: false)
self.userCommentArray.removeAll(keepingCapacity: false)
self.likeArray.removeAll(keepingCapacity: false)
self.PosterEmail.removeAll(keepingCapacity: false)
self.userProfilePhotoArray.removeAll(keepingCapacity: false)
self.PosterFirstNameArray.removeAll(keepingCapacity: false)
self.PosterLastNameArray.removeAll(keepingCapacity: false)
for document in snapshot!.documents {
let documentID = document.documentID
self.documentIDArray.append(documentID)
if let postDescription = document.get("PostDescription") as? String {
self.userPostDescription.append(postDescription)
}
if let imageUrl = document.get("imageUrl") as? String {
self.userPostImageArray.append(imageUrl)
}
if let PostLikes = document.get("Likes") as? Int {
self.likeArray.append(PostLikes)
}
if let postTimeStamp = document.get("Date") as? Timestamp {
let date = postTimeStamp.dateValue()
let formatter = DateFormatter()
formatter.dateFormat = "HH:mm MM/dd/yyyy"
let dateString = formatter.string(from: date)
let timeStampAsString = dateString
self.postDate.append(timeStampAsString)
}
if let postedBy = document.get("postedBy") as? String {
print("Postby = document.get(postedby = \(postedBy)")
self.PosterEmail.append(postedBy)
if self.PosterEmail.count > 0 {
self.getPosteInformation()
}
}
}
}
}
self.VidaFeed.reloadData()
}
func getPosteInformation() {
print("")
print(PosterEmail[profilecount])
print(profilecount)
print("")
print(PosterEmail)
let docRef = db.collection("Public").document("\(self.PosterEmail[self.profilecount])")
docRef.getDocument { (document, error) in
if let document = document, document.exists {
let dataDescription = document.data().map(String.init(describing:)) ?? "nil"
print("Document data: \(dataDescription)")
if self.profilecount < self.PosterEmail.count {
if let PosterFirstName = document.get("First Name") as? String {
self.PosterFirstNameArray.append(PosterFirstName)
print(self.PosterFirstNameArray)
print("\(self.profilecount)")
if self.PosterEmail.count > self.profilecount {
self.profilecount = self.profilecount + 1
}
}
}
} else {
print("Document does not exist")
}
}
}

if let postedBy = document.get("postedBy") as? String {
print("Postby = document.get(postedby = \(postedBy)")
self.PosterEmail.append(postedBy)
self.PosterFirstNameArray.append("")
if self.PosterEmail.count > 0 {
self.getPosteInformation(profCount: self.profileCount)
}
if self.PosterEmail.count > self.profilecount {
self.profilecount = self.profilecount + 1
}
}
And now if you could modify this method like this:
func getPosteInformation(profCount:Int) {
//and inside the async call back instead of the following try
/*if let PosterFirstName = document.get("First Name") as? String {
self.PosterFirstNameArray.append(PosterFirstName)
print(self.PosterFirstNameArray)
print("\(self.profilecount)")
if self.PosterEmail.count > self.profilecount {
self.profilecount = self.profilecount + 1
}
}*/
if let PosterFirstName = document.get("First Name") as? String {
self.PosterFirstNameArray[profCount] = PosterFirstName
print(self.PosterFirstNameArray)
print("\(profCount)")
}
}

Related

Location of append operator causing issues

I am trying to append an object ViewingPost to an array of these objects. It works when I do what is shown here:
for (_,post) in snap {
let posst = ViewingPost()
if let totLikes = post["likes"] as? Int, let pathToImage = post["pathToImage"] as? String, let postID = post["postID"] as? String {
let postNum = "post" + postID
posst.pathToImage = pathToImage
posst.postID = postID
posst.likes = totLikes
self.posts.append(posst)
for key in 1 ... arr.count {
let isEq = arr[key - 1] == postNum
print(isEq)
if isEq {
ref.child(formattedDateD).child(postNum).observeSingleEvent(of: .value, with: { (snapsh) in
let snapshP = snapsh.value as! Int
})
}
}
}
}
Though when I move the part in which it appends the object to the array to where I want it to be, it stops working:
for (_,post) in snap {
let posst = ViewingPost()
if let totLikes = post["likes"] as? Int, let pathToImage = post["pathToImage"] as? String, let postID = post["postID"] as? String {
let postNum = "post" + postID
for key in 1 ... arr.count {
let isEq = arr[key - 1] == postNum
print(isEq)
if isEq {
ref.child(formattedDateD).child(postNum).observeSingleEvent(of: .value, with: { (snapsh) in
let snapshP = snapsh.value as! Int
posst.pathToImage = pathToImage
posst.postID = postID
posst.likes = totLikes
self.posts.append(posst)
})
}
}
}
}
Can someone please help?

complex json data array in array in static tableview (for detail)

import UIKit
struct Base : Codable {
let genres : [Genres]?
let name : String?
let overview : String?
}
struct Genres : Codable {
let id : Int?
let name : String?
}
func fillSelectedShowDetails() {
let selectedURL = URL(string: " ")
guard let downloadedURL = selectedURL else {return}
URLSession.shared.dataTask(with: downloadedURL) { (data, urlResponse, error) in
guard let data = data, error == nil, urlResponse != nil else {
print("something went wrong in selectedURL")
return
}
print("Downloaded selectedURL")
do {
let decoder = JSONDecoder()
let decodedResults = try decoder.decode(Base.self, from: data)
self.detailedTV = decodedResults
DispatchQueue.main.async {
self.showNameLabel.text = decodedResults.name
self.overwievLabel.text = decodedResults.overview
if self.detailedTV?.genres?.count == 2 {
self.genreLabel.text = decodedResults.genres?[1].name
} else {
self.genreLabel.text = decodedResults.genres?[0].name
}
print(decodedResults.genres)
}
} catch {
print("something wrong after downloaded in selectedURL\(error)")
}
}.resume()
}
I need every genre name and write it to text. How can I do that?
If your goal is to create a single string from all of the values for the name property then use map and joined:
let genreNames = decodedResults.genres?.compactMap { $0.name }.joined(separator: ",") ?? """
self.genreLabel.text = genreNames

Parsing JSON array to label

I am trying to parse the JSON below (actual data is 20x the format listed)
{
message = "";
result = (
{
Ask = "4.8e-05";
BaseVolume = "32.61025363";
Bid = "4.695e-05";
Created = "2017-06-06T01:22:35.727";
High = "5.44e-05";
Last = "4.69e-05";
Low = "4.683e-05";
MarketName = "BTC-1ST";
OpenBuyOrders = 293;
OpenSellOrders = 4186;
PrevDay = "4.76e-05";
TimeStamp = "2018-02-20T00:00:31.863";
Volume = "662575.93818332";
},
This is the code that I have right now. It successfully prints the value "Last" to the console but when I incorporate the Dispatch.Queue, I get a Thread 1: signal SIGBRT not printing the value to the label.
let myJson = try JSONSerialization.jsonObject(with: content) as! [String:Any]
if let info = myJson["result"] as! [[String:Any]]?
{
for i in 0..<20 {
if i == 1
{
if let dict = info[i] as? [String:Any]
{
if let price = dict["Last"]
{
print(price)
//DispatchQueue.main.async
//{
// self.label1.text = price as String
//}
}
}
}
Any help is greatly appreciated!
Most likely your self.label1 outlet isn't connected. Fix that connection.
You should also update the if let that gets the value for the "Last" key as follows:
if let price = dict["Last"] as? String{
print(price)
DispatchQueue.main.async {
self.label1.text = price
}
}
There is some other cleanup you can do as well:
if let myJson = try JSONSerialization.jsonObject(with: content) as? [String:Any] {
if let info = myJson["result"] as? [[String:Any]] {
for (index, dict) in info.enumerated() {
if index == 1 {
if let price = dict["Last"] as? String {
print(price)
DispatchQueue.main.async {
self.label1.text = price
}
} // else no "Last" or not a String
}
}
} // else "result" doesn't contain expected array of dictionary
} // else content isn't a valid JSON dictionary
Avoid all of those forced casts. Especially avoid force casting to an optional.
JSON doesn't use the = sign or the semicolon. Change every = to a colon and every semicolon to a comma, so that
Ask = "4.8e-05";
BaseVolume = "32.61025363";
Bid = "4.695e-05";
Becomes
Ask: "4.8e-05",
BaseVolume: "32.61025363",
Bid: "4.695e-05",

Appending Array Inside Function

I am trying to append values to an array inside a function and call that updated array in another function but it is not printing the new appended values.
I am using firebase and getting a snapshot of the database, sorting it, finding value of keys, and appending to hDates
var hDates:Array = [""]
getHistoryPGE() { hDates in
print(hDates)
self.hDates = [hDates]
}
func getHistoryPGE(completion: #escaping (String)->()) {
let userID = Auth.auth().currentUser?.uid
let ref = Database.database().reference().child("users").child(userID!)
ref.child("PostGameEval").observe(.value, with: { (snapshot) in
if let dict = snapshot.value as? [String : [String: [String: Any]]] {
let keys = Array(dict.keys)
var num : Int = 7
for i in 0..<keys.count {
if let innerDict = dict[keys[i]] {
let innerKeys = Array((innerDict).keys)
let sortedInnerKeys = innerKeys.sorted(by: { $0 > $1} )
while (sortedInnerKeys.count < num){
num -= 1
}
for j in 0..<num {
if let tempDict = innerDict[sortedInnerKeys[j]] {
print(tempDict["1abA"] as! String)
}
}
}
}
}})
}
func calendar(_ calendar: FSCalendar, numberOfEventsFor date: Date) -> Int {
let dateString = self.dateFormatter.string(from: date)
if self.hDates.contains(dateString) {
return 1
}
return 0
}

How to compare a variable String() to a string in swift?

I have a class in which I need to check a URL for json data compile that in an array and see if the latest content is an article/project/survey. My code compiles but it compare the strings to see if its an article/project/survey. Not sure what im doing wrong?
my code is
class LocalNotificationsManager {
var articleSurveyOrProject = String()
func checkForNewContent() {
let url = "https://cdn.contentful.com/spaces/maz0qqmvcx21/entries?access_token=ae8163cb8390af28cd3d7e28aba405bac8284f9fe4375a605782170aef2b0b48";
var jsonData:NSData?
let url = "https://cdn.contentful.com/spaces/maz0qqmvcx21/entries?access_token=ae8163cb8390af28cd3d7e28aba405bac8284f9fe4375a605782170aef2b0b48";
var jsonData:NSData?
var latestContentDates = [String]()
do{
jsonData = try NSData(contentsOfURL: NSURL(string: url)!, options: NSDataReadingOptions.DataReadingUncached)
let jsonObject:AnyObject? = try NSJSONSerialization.JSONObjectWithData(jsonData!, options: NSJSONReadingOptions.AllowFragments)
if let itemArray = jsonObject?.objectForKey("items") as? NSArray{
for item in itemArray{
if let sysItem = item.objectForKey("sys"){
//this is createdAt
if let createdAt = sysItem.objectForKey("createdAt") as? String{
print("createdAt:\(createdAt)")
latestContentDates.append(createdAt)
}
if let contentTypeItem = sysItem.objectForKey("contentType")!.objectForKey("sys"){
//this is id
if let id = contentTypeItem.objectForKey("id") as? String{
content.append(id)
}
}
}
}
}
}catch let err as NSError{
print("err:\(err)")
}
let articleSurveyOrProject = content[0]
print("articleSurveyOrProject:\(articleSurveyOrProject)")
sendLocalNotification()
}
func sendLocalNotification() {
if (articleSurveyOrProject == "article") {
print(Article)
} else if (articleSurveyOrProject == "survey") {
print("Survey")
} else if (articleSurveyOrProject == "project")
{
print("Project")
} else {
print("Oops! something went wrong it didnt get any values")
}
}
}
Note: Im working in swift2
The problem is this line:
let articleSurveyOrProject = content[0]
Delete let.

Resources