Instance method takes long time for type-cheking - swift

I have quite a big project that takes a long time to compile. When I checked compilation times of methods. I found that this method, for example, takes usually more than 200ms to compile. What can I do to improve this?
func processSnapshot(snapshot:DataSnapshot) {
self.numberOfUsers.text = "#Total DB (users): \(snapshot.childrenCount.description)"
for child in snapshot.children {
if let snapshot = child as? DataSnapshot,
let userProfile = UserProfile(snapshot: snapshot) {
if userProfile.picUrl == "" {
numberOfUsersWithOutPicUrl += 1
}
let todayLong = "\(Date())".prefix(10)
if userProfile.createdOnLong.prefix(10) == todayLong {
profileWizardsStartedTotday += 1
if userProfile.weight != "" {
profileWizardsCompletedTotday += 1
}
}
profiles.append(userProfile)
}
}
let numberOfUsersWithOutPicUrlPercent = round(Double(numberOfUsersWithOutPicUrl)*100/Double(numberOfRealUsers))
let sizeOfSnapshotValueInKB:Int = String(describing: snapshot.value).count / 1024
self.userThatAbortedOnBoarding.text = numberOfUsersWithOutPicUrl.description
self.userThatAbortedOnBoardingPercent.text = "\(numberOfUsersWithOutPicUrlPercent)%"
self.userThatStartedOnBoardingToday.text = profileWizardsStartedTotday.description
self.userThatCompletedOnBoardingToday.text = profileWizardsCompletedTotday.description
self.sizeOfSnapshot.text = "\(sizeOfSnapshotValueInKB.description)KB"
}
My UserProfile initializer looks like this:
init?(snapshot: DataSnapshot) {
print("\(snapshot.key) - \(String(describing: snapshot.value))")
guard
let value = snapshot.value as? [String: AnyObject],
let uid = value["uid"] as? String
else {
print("Warning: Userprofile has no UID")
return nil
}
self.uid = uid
self.email = value["email"] as? String ?? ""
self.picUrl = value["picurl"] as? String ?? ""
self.picUrl2 = value["picurl2"] as? String ?? ""
self.picUrl3 = value["picurl3"] as? String ?? ""
self.picUrl4 = value["picurl4"] as? String ?? ""
self.picUrl5 = value["picurl5"] as? String ?? ""
self.picUrl6 = value["picurl6"] as? String ?? ""
self.city = value["city"] as? String ?? ""
self.displayName = value["displayName"] as? String ?? "anonymous"
}

Related

Must be a non-empty string and not contain '.' '#' '$' '[' or ']''

Please help! I am experiencing an app crash.
public enum memberships {
case noMembership
case paid
case freeTrial
case trialExpired
}
public class DataManager {
private static let uuid = UIDevice.current.identifierForVendor!.uuidString
private static let user = Auth.auth().currentUser
private static let userRef = Database.database().reference().child("Users").child(user?.uid ?? "")
static var currentStatus: memberships? = nil
/**
Get's the current user's info from Firebase
and returns the info as a User object
*/
class func getUser(completion: #escaping (User?) -> ()) {
userRef.observeSingleEvent(of: .value, with: { (snapshot) in
if let value = snapshot.value as? [String: Any] {
// UIPasteboard.general.string = uuid
let uuid = snapshot.key
let name = value["name"] as? String ?? ""
let email = value["email"] as? String ?? ""
let dateJoined = value["dateJoined"] as? String ?? ""
let membershipString = value["membership"] as? String
let alertsStartTime = value["alertsStartTime"] as? String ?? ""
let alertsEndTime = value["alertsEndTime"] as? String ?? ""
let alertsFrequency = value["alertsFrequency"] as? Int ?? 1
let alertsType = value["alertsType"] as? String ?? ""
let isEnable = value["isEnable"] as? Bool ?? true
//Gets users current membership
var membershipStatus: memberships!
if membershipString == "Paid" {
membershipStatus = .paid
}else if membershipString == "NoMembership" {
membershipStatus = .noMembership
}else{
membershipStatus = Utils.getUserMembershipStatus(dateJoined: dateJoined)
}
let user = User(uuid: uuid, name: name, email: email, dateJoined: dateJoined, membership: membershipStatus, alertsStartTime: alertsStartTime, alertsEndTime: alertsEndTime, alertsType: alertsType, alertsFrequency: alertsFrequency, isEnable: isEnable)
completion(user)
}else{
completion(nil)
}
}) { (error) in
print(error.localizedDescription)
completion(nil)
}
}
Your user object is empty. So user?.uid is nil. Which means child(user?.uid ?? "") -> child("").
Firebase does not accept empty strings as key values (It also does not accepts strings which includes '.' '#' '$' '[' or ']'' as keys).
So in your case make sure user is logged or use different key value.

How to Clear Shared Dictionary which is causing saved values not to clear even when I login with other user

How can I clear the shared dictionary on logout in which I am saving login response?
Here is the code I am doing on getting status 1.
if(status == 1)
{
DispatchQueue.main.async {
GAReusableClass.sharedInstance.hideActivityIndicator()
UserDefaults.standard.set(self.DataDict, forKey:MaindataKey)
let Dict = self.mainDict[KData] as! [String: AnyObject]
print("self.DataDict", self.DataDict)
let User_ID = Dict[KUuid]as! String
print(User_ID)
let HMACSECRETKEY = self.deviceToken + "+" + User_ID
kHMACKey = HMACSECRETKEY
let cipher:String = CryptoHelper.encrypt(input:HMACSECRETKEY)!;
print(HMACSECRETKEY)
UserDefaults.standard.setValue(cipher, forKey:HmacKey)
UserDefaults.standard.set(true, forKey: "isLogin")
GAloginUserInfo.shared.saveUserInfo(dict: Dict )
let tabar = self.storyboard?.instantiateViewController(withIdentifier: "GAtHomeTabbarViewController") as! GAtHomeTabbarViewController
self.navigationController?.pushViewController(tabar, animated: true)
}
Here is the shared dictionary which I am using to save the values of login response.
import UIKit
import Firebase
class GAloginUserInfo: NSObject {
var loginUserMobileNo : String?
var loginUserId : String?
var loginUserUuid : String?
var loginUserCountry : String?
var loginUserCountryCode : String?
var loginUserEmail : String?
var loginUserlatitude : String?
var loginUserLongitude : String?
var loginUserName : String?
var loginUserQrcode : String?
var loginUserProfilePic : String?
var isverify : String?
var loginPassword : String?
var dateOfBirth: String?
var earnedPoints:String?
var loginUserGender:String?
var loginUserFollowers:Int = 0
static let shared = GAloginUserInfo()
func saveUserInfo (dict : [String : AnyObject?] ) {
if let loginUserMobileNo = dict["mobile"] as? String {
self.loginUserMobileNo = loginUserMobileNo
}
if let loginUserId = dict["id"] as? String {
self.loginUserId = loginUserId
}
if let loginUserUuid = dict["uuid"] as? String {
self.loginUserUuid = loginUserUuid
print(loginUserUuid)
}
if let loginUserCountry = dict["country"] as? String {
self.loginUserCountry = loginUserCountry
}
if let loginUserCountryCode = dict["country_code"] as? String {
self.loginUserCountryCode = loginUserCountryCode
}
if let loginUserEmail = dict["email"] as? String {
self.loginUserEmail = loginUserEmail
}
if let loginUserProfilePic = dict["profile_pic"] as? String {
self.loginUserProfilePic = loginUserProfilePic
}
if let loginUserLongitude = dict["logitude"] as? String {
self.loginUserLongitude = loginUserLongitude
}
if let loginUserName = dict["name"] as? String {
self.loginUserName = loginUserName
}
if let loginUserQrcode = dict["qr_code"] as? String {
self.loginUserQrcode = loginUserQrcode
}
if let Password = dict["password"] as? String{
self.loginPassword = Password
}
if let dateOfBirth = dict["dob"] as? String{
self.dateOfBirth = dateOfBirth
}
if let earnedPoints = dict["points"] as? String{
let myDouble = Double(earnedPoints)
let doubleStr = String(format: "%.2f", myDouble!)
self.earnedPoints = doubleStr
}
if let loginUserGender = dict["gender"] as? String{
self.loginUserGender = loginUserGender
}
if let loginUserFollowers = dict["followersCount"] as? Int{
self.loginUserFollowers = loginUserFollowers
}
}
}
Actually, the problem is when I log out and log in again with some other user it still shows some values of the previous user. I am clearing the userdefaults on the logout function. but I don't know how to clear this type of shared dictionary.
Use removeObject(forKey:)
to remove the values stored from user defaults in Logout method
UserDefaults.standard.removeObject(forKey: MaindataKey)
UserDefaults.standard.removeObject(forKey: HmacKey)
UserDefaults.standard.set(false, forKey: "isLogin")
Create a method to remove the values from the singleton class like this
extension GAloginUserInfo {
func removeUserInfo() {
self.loginUserMobileNo = nil
self.loginUserId = nil
self.loginUserUuid = nil
self.loginUserCountry = nil
self.loginUserCountryCode = nil
self.loginUserEmail = nil
self.loginUserlatitude = nil
self.loginUserLongitude = nil
self.loginUserName = nil
self.loginUserQrcode = nil
self.loginUserProfilePic = nil
self.isverify = nil
self.loginPassword = nil
self.dateOfBirth = nil
self.earnedPoints = nil
self.loginUserGender = nil
self.loginUserFollowers = 0
}
}
and call this method in logout
GAloginUserInfo.shared.removeUserInfo()

Retrieve firebase data from swift

I'm trying to retrieve data from a Firebase RealTime database, in order to put it on a list which will be used to display data on a TableView.
My problem is that even if I get some data, I haven't enough knowledge to access on arrays and other swift objects. Perhaps, I'm not using the good way to do what I want.
Here is an example of a row on Firebase :
Here is a function written in Swift in which I'm trying to build a list for each row object.
func displayStationsUsingSearch(){
let station = self.stationName
let CP = Int(self.searchedCP!)
// create searchRef or queryRef you name it
let stationsRef = Database.database().reference().child("Stations")
stationsRef.observeSingleEvent(of: .value, with: { (snapshot) in
print(snapshot)
/*if snapshot.value is NSNull {
print("not found")
} else {
// yes we got the user
let id = snapshot.value as! Int
}*/
for child in snapshot.children {
stationsRef.queryOrdered(byChild: "marque")
.queryEqual(toValue: "TOTAL ACCESS")
.observe(.value, with: { snap in
if let dict = snap.value as? [String: AnyObject] {
/*self.stationItem!.nomStation = dict["nomStation"] as! String
self.stationItem!.adresse = dict["adresse"] as! String
self.stationItem!.codePostal = dict["codePostal"] as! String
self.stationItem!.ville = dict["ville"] as! String
self.stationItem!.marque = dict["marque"] as! String
self.stationItem!.pays = dict["pays"] as! String
self.stationItem!.commentaire = dict["commentaire"] as! String
self.stationItem!.coordGPS = dict["coordGPS"] as! String*/
print(dict["nomStation"] as! String)
}
})
}
})
}
The lldb on Xcode workspace displays that :
Printing description of child:
Snap (-LdA6X8CfNY3bsPni31U) {
"DIESEL EXCELLIUM" = 0;
"DIESEL ULTIMATE" = 0;
GAZOLE = 0;
GPL = 0;
SP95 = 0;
"SP95 E10" = 0;
SP98 = 0;
SUPER = 0;
adresse = "RN1 Direction Moisselles";
codePostal = 95570;
commentaire = "";
coordGPS = "";
createdAt = "31/07/2018";
heureDebut = "";
heureFin = "";
id = 0;
marque = ESSO;
modifiedAt = "23/04/2019 18:53";
nomStation = "ESSO Moisselles";
pays = "";
saufJour = "";
services = "";
typeRoute = "";
ville = Moisselles;
}
(lldb)
Could you please help me to retrieve data on a list that I could append to display data on tableview ? Thank you.
Try something like that:
Database.database().reference()
.child("Stations").
observeSingleEvent(of: .value, with: { (snapshot) in
guard let value = snapshot.value as? [String: Any] else {
return
}
var stations = [Station]()
for (key, value) in values {
guard let station = value as? [String: Any],
let adresse = station["adresse"] as? String,
let codePostat = station["codePostat"] as? String else {
continue
}
stations.append(Station(adresse: adresse, codePostat: codePostat))
}
// if you have some completion return retrieved array of stations
completion(stations)
})
struct Station {
private let adresse: String
private let codePostat: String
init(adresse: String, codePostat: String) {
self.adresse = adresse
self.codePostat = codePostat
}
}
You can use a swift Class Instead.
Swift Object:
import Foundation
class FirebaseTransactionData : NSObject{
var customer : FirebaseTransactionDataCustomer!
var driver : FirebaseTransactionDataCustomer!
var status : String!
init(fromDictionary dictionary: [String:Any]){
status = dictionary["status"] as? String
if let customerData = dictionary["customer"] as? [String:Any]{
customer = FirebaseTransactionDataCustomer(fromDictionary: customerData)
}
if let driverData = dictionary["driver"] as? [String:Any]{
driver = FirebaseTransactionDataCustomer(fromDictionary: driverData)
}
}
}
class FirebaseTransactionDataCustomer : NSObject{
var lat : Double!
var longField : Double!
init(fromDictionary dictionary: [String:Any]){
lat = dictionary["lat"] as? Double
longField = dictionary["lng"] as? Double
}
}
Firebase Method
ref.observe(DataEventType.value, with: { (snapshot) in
let value = snapshot.value as? [String:Any]
let datt = FirebaseTransactionData(fromDictionary: value!)
print("snapshot \(datt.status!)")
print("snapshot \(datt.customer.lat!)")
})

Swift 4 Retrieving Data From Firebase Database

func retPost2(){
runNBPOST()
////////////////////////////////////1
var pic = [String]()
var p = Post(userId: "", postId: "", postType: "", description: "", Region: "", City: "", District: "", Street: "", Area: 0, View: "", TotalPrice: 0, Pictures: pic, StreetWidth: 0, PropertyType: "")
////// for to retrive all post
print(retNBPOST())
runNBPOST()
let nbpost = retNBPOST()
for i in 1..<nbpost{
postiiD = "Post(\(i))"
self._REF_BASE.child("Post").child(postiiD).observeSingleEvent(of: .value, with: { (snapshot) in
let value = snapshot.value as? NSDictionary
let UserID2 = value?["UserID"] as? String ?? ""
p.userId = UserID2
})
self._REF_BASE.child("Post").child("\("Post(\(i))")/Adress").observeSingleEvent(of: .value, with: { (snapshot) in
let value = snapshot.value as? NSDictionary
let Region = value?["Region"] as? String ?? ""
p.Region = Region
let City = value?["City"] as? String ?? ""
p.City = City
print(p.City)
let District = value?["District"] as? String ?? ""
p.District = District
let Street = value?["Street"] as? String ?? ""
p.Street = Street
let AdditionalNumber = value?["AdditionalNumber"] as? String ?? ""
p.AdditionalNumber = AdditionalNumber
let PostalCode = value?["PostalCode"] as? String ?? ""
p.PostalCode = PostalCode
let BuldingNo = value?["BuldingNo"] as? String ?? ""
p.BuldingNo = BuldingNo
})
self._REF_BASE.child("Post").child("\(postiiD)/PostInfo").observeSingleEvent(of: .value, with: { (snapshot) in
let value = snapshot.value as? NSDictionary
let postType = value?["PostType"] as? String ?? ""
p.postType = postType
print(p.postType)
let DateOfpost = value?["DateOfpost"] as? String ?? ""
p.dateOfpost = DateOfpost
let EndDateOfPost = value?["EndDateOfPost"] as? String ?? ""
p.endDateOfPost = EndDateOfPost
let NbOfShare = value?["NbOfShare"] as? String ?? ""
p.nbOfShare = Int(NbOfShare)!
let NbOfViews = value?["NbOfViews"] as? String ?? ""
p.nbOfViews = Int(NbOfViews)!
let LastUpdate = value?["LastUpdate"] as? String ?? ""
p.lastUpdate = LastUpdate
let Description = value?["Description"] as? String ?? ""
p.description = Description
let Publisher = value?["Publisher"] as? String ?? ""
p.publisher = Publisher
let ContactTime = value?["ContactTime"] as? String ?? ""
p.contactTime = ContactTime
let Payment = value?["Payment"] as? String ?? ""
p.payment = Payment
let TotalPrice = value?["TotalPrice"] as? String ?? ""
p.TotalPrice = Double(TotalPrice)!
let NearBy = value?["NearBy"] as? String ?? ""
p.NearBy = NearBy
let StreetWidth = value?["StreetWidth"] as? String ?? ""
p.StreetWidth = Double(StreetWidth)!
// let Discount = value?["Discount"] as? String ?? ""
// p.Discount =
})
self._REF_BASE.child("Post").child("\(postiiD)/Property").observeSingleEvent(of: .value, with: { (snapshot) in
let value = snapshot.value as? NSDictionary
let Area = value?["Area"] as? String ?? ""
p.Area = Double(Area)!
print(p.Area)
let View = value?["View"] as? String ?? ""
p.View = View
let FamilyOrSingle = value?["FamilyOrSingle"] as? String ?? ""
p.FamilyOrSingle = FamilyOrSingle
let Level = value?["Level"] as? String ?? ""
p.Level = Int(Level)!
let HouseAge = value?["HouseAge"] as? String ?? ""
p.HouseAge = Int(HouseAge)!
let LandType = value?["LandType"] as? String ?? ""
p.LandType = LandType
let MeterPrice = value?["MeterPrice"] as? String ?? ""
p.MeterPrice = Double(MeterPrice)!
let NbRoom = value?["NbRoom"] as? String ?? ""
p.NbRoom = Int(NbRoom)!
let NbGuestroom = value?["NbGuestroom"] as? String ?? ""
p.NbGuestroom = Int(NbGuestroom)!
let NbBathroom = value?["NbBathroom"] as? String ?? ""
p.NbBathroom = Int(NbBathroom)!
let NbBedroom = value?["NbBedroom"] as? String ?? ""
p.NbBedroom = Int(NbBedroom)!
let NbLivingroom = value?["NbLivingroom"] as? String ?? ""
p.NbLivingroom = Int(NbLivingroom)!
let NbKitchen = value?["NbKitchen"] as? String ?? ""
p.NbKitchen = Int(NbKitchen)!
let PropertyType = value?["PropertyType"] as? String ?? ""
p.PropertyType = PropertyType
let NbApartment = value?["NbApartment"] as? String ?? ""
p.NbApartment = Int(NbApartment)!
})
// complet
self._REF_BASE.child("Post").child("\(postiiD)/Amenities").observeSingleEvent(of: .value, with: { (snapshot) in
let value = snapshot.value as? NSDictionary
let LiftAvailability = value?["LiftAvailability"] as? String ?? ""
let KitchenAvailability = value?["KitchenAvailability"] as? String ?? ""
let FurnitureAvailability = value?["FurnitureAvailability"] as? String ?? ""
let CarageAvailability = value?["CarageAvailability"] as? String ?? ""
let SwimmingPoolAvailability = value?["SwimmingPoolAvailability"] as? String ?? ""
let ParkingAvailability = value?["ParkingAvailability"] as? String
let FiberOpticAvailability = value?["FiberOpticAvailability"] as? String
let FireplaceAvailability = value?["FireplaceAvailability"] as? String
let DiningroomAvailability = value?["DiningroomAvailability"] as? String
let LaundryAvailability = value?["LaundryAvailability"] as? String
let CentralAirAvailability = value?["CentralAirAvailability"] as? String
let BalconyAvailability = value?["BalconyAvailability"] as? String
let MaidRoomAvailability = value?["MaidRoomAvailability"] as? String
let DriverRoomAvailability = value?["DriverRoomAvailability"] as? String
let InternalStairAvailability = value?["InternalStairAvailability"] as? String
let BasementAvailability = value?["BasementAvailability"] as? String
})
arrpost.append(p)
}
}
func updateHomeView(post : Post){
totalPriceLb.text = "\(String(post.TotalPrice)) SR"
areaLb.text = String(post.Area)
AddressLb.text = "\(post.City) \(post.District) \(post.Street)"
imageName.image = UIImage(named: "HomePic.jpg")
if post.PropertyType == "Home" {
bathLb.text = String(post.NbBathroom)
BedLb.text = String(post.NbBedroom)
imageName.image = UIImage(named: "HomePic.jpg")
}else if post.PropertyType == "Apartment" {
bathLb.text = String(post.NbBathroom)
BedLb.text = String(post.NbBedroom)
imageName.image = UIImage(named: "ApartPic.jpg")
}else if post.PropertyType == "Land"{
bathLb.isHidden = true
BedLb.isHidden = true
imageName.image = UIImage(named: "LandPic.jpg")
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
DataService.instance.retPost2()
// tableView.reloadData()
return DataService.instance.arrpost.count
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
}
func tableView
(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "PostCell") as! homecell
let post = DataService.instance.arrpost[indexPath.row]
// let post = DataServiceTemp.instance.getPosts()[indexPath.row]
cell.updateHomeView(post: post)
// tableView.reloadData()
return cell
}
I have a problem in my IOS App. I'm Using Firebase for saving & Retrieving data. All connections are good and the data is retrieved fine or sometimes incomplete.
And My Problem is when I run the app the views, labels, Pictures, etc are shown Empty at first when this components should show the data retrieved from firebase. I don't know what's the problem. Is it time or anything else? So the main problem is the components are shown empty before retrieving the data completely. I want to force the app to not show empty at first but showing the components with data.
I already use all method from google
https://firebase.google.com/docs/database/ios/read-and-write
Make hover UIView above the mainVC with a UIActivityIndicator until response comes from Firebase remove it

How to get and add to Syncano reference to user_profile

as in the title I have problem how adds to syncano reference to user_profile,
If someone could tell me a hint?
So this is my code:
func saveName() {
let Uerextra = userextra()
Uerextra.name = (self.dict.objectForKey("first_name") as? String)!
Uerextra.lastName = (self.dict.objectForKey("last_name") as? String)!
Uerextra.avatarUrl = self.dict.objectForKey("picture")?.objectForKey("data")?.objectForKey("url") as! String
Uerextra.FacebookId = (self.dict.objectForKey("id") as? String)!
Uerextra.saveWithCompletionBlock { error in
if error != nil {
print(error)
}
}
}
And I need 1 extra field with reference to user id.
This is my class:
class userextra : SCDataObject {
var name = ""
var lastName = ""
var avatarUrl = ""
var FacebookId = ""
var user: SCUserProfile! = nil
}
Ok after several attempts I managed to save this reference to Syncano.
This is my code:
func saveName() {
user_profile.please().enumaratePagesWithPredicate(nil, parameters: [SCPleaseParameterPageSize : 25]) {shouldStop, s_data, error in
guard error == nil else {
return
}
if let s_data = s_data as? [user_profile] {
for user in s_data {
let uzytkownik = user
let Uerextra = userextra()
Uerextra.name = (self.dict.objectForKey("first_name") as? String)!
Uerextra.lastName = (self.dict.objectForKey("last_name") as? String)!
Uerextra.avatarUrl = self.dict.objectForKey("picture")?.objectForKey("data")?.objectForKey("url") as! String
Uerextra.FacebookId = (self.dict.objectForKey("id") as? String)!
Uerextra.user = uzytkownik
Uerextra.saveWithCompletionBlock { error in
if error != nil {
print(error)
}
}
}
}
}
}
and user_profile class:
class user_profile: SCUserProfile {
var id = 0
var Name = ""
var Surename = ""
}
Most important is register class in app delegate
SCUser.registerClassWithProfileClass(userextra.self)
SCUser.registerClassWithProfileClass(user_profile.self)