!!更新: Firebase可能不是问题(在半秒内获取的数据似乎出现在ViewController主屏幕上,尽管连接可能仍有问题;另外,在AddUniversal屏幕上,向Firebase数据库添加新实体会触发相同的延迟,这表明Firebase是问题所在,因为屏幕上没有大小调整或集合视图或许多其他内容)-在ViewController屏幕上,我认为问题可能存在于获取数据和插入collectionView单元(卡片视图)之间的某个地方,根据Brian Voong的垂直调整模型。我将在下面留下原始代码,并在最后留下一些Brian Voong的东西。!!
我尝试过删除加密/解密过程,删除GoogleAppEngine (加密密钥请求)的调用,以及删除图像(仅请求文本;可能小于200kB)。我还尝试了Frank van Puffelen的建议,除了我的“曾经”的侦听器之外,还添加了一个"on“侦听器。毫无办法。这个应用程序将无法使用的客户,如果我不得到它的修复。
示例代码:
//
// MIProcessor.swift
// Bizzy Books
//
// Created by Brad Caldwell on 12/19/17.
// Copyright © 2017 Caldwell Contracting LLC. All rights reserved.
//
import UIKit
import Firebase
final class MIProcessor {
static let sharedMIP = MIProcessor()
private init() {}
public var firstTime: Bool = false
public var mIP: [MultiversalItem] = [MultiversalItem]()
public var sIP: [MultiversalItem] = [MultiversalItem]() // the search mip!
public var mipORsip: Int = Int()
public var mIPUniversals: [UniversalItem] = [UniversalItem]()
public var mIPProjects: [ProjectItem] = [ProjectItem]()
public var mIPEntities: [EntityItem] = [EntityItem]()
public var mIPAccounts: [AccountItem] = [AccountItem]()
public var mIPVehicles: [VehicleItem] = [VehicleItem]()
public var trueYou: String = String()
public var isUserCurrentlySubscribed: Bool = Bool()
private var tHeKeY: Data!
var theUser: User!
var universalsRef: DatabaseReference!
var entitiesRef: DatabaseReference!
var projectsRef: DatabaseReference!
var vehiclesRef: DatabaseReference!
var accountsRef: DatabaseReference!
var keyRef: DatabaseReference!
var obtainBalanceAfter = ObtainBalanceAfter()
var obtainProjectStatus = ObtainProjectStatus()
var balOneAfter: Int = 0
var balTwoAfter: Int = 0
var balsAfter: [Int?] = [Int?]()
var masterSearchArray: [SearchItem] = [SearchItem]()
var authorized: Bool!
var theKeyIsHere: String!
func loadTheMip(completion: @escaping () -> ()) {
mipORsip = 0 // MIP!
//obtainTheKey {
self.universalsRef = Database.database().reference().child("users").child(userUID).child("universals")
self.projectsRef = Database.database().reference().child("users").child(userUID).child("projects")
self.entitiesRef = Database.database().reference().child("users").child(userUID).child("entities")
self.accountsRef = Database.database().reference().child("users").child(userUID).child("accounts")
self.vehiclesRef = Database.database().reference().child("users").child(userUID).child("vehicles")
self.mIPUniversals.removeAll()
self.mIPProjects.removeAll()
self.mIPEntities.removeAll()
self.mIPAccounts.removeAll()
self.mIPVehicles.removeAll()
self.universalsRef.observeSingleEvent(of: .value, with: { (snapshot) in
for item in snapshot.children {
self.mIPUniversals.append(UniversalItem(snapshot: item as! DataSnapshot))
}
self.projectsRef.observeSingleEvent(of: .value, with: { (snapshot) in
for item in snapshot.children {
self.mIPProjects.append(ProjectItem(snapshot: item as! DataSnapshot))
}
self.entitiesRef.observeSingleEvent(of: .value, with: { (snapshot) in
for item in snapshot.children {
self.mIPEntities.append(EntityItem(snapshot: item as! DataSnapshot))
}
self.accountsRef.observeSingleEvent(of: .value, with: { (snapshot) in
for item in snapshot.children {
self.mIPAccounts.append(AccountItem(snapshot: item as! DataSnapshot))
}
self.vehiclesRef.observeSingleEvent(of: .value, with: { (snapshot) in
for item in snapshot.children {
self.mIPVehicles.append(VehicleItem(snapshot: item as! DataSnapshot))
}
let youRef = Database.database().reference().child("users").child(userUID).child("youEntity")
youRef.observeSingleEvent(of: .value, with: { (snapshot) in
if let youKey = snapshot.value as? String {
self.trueYou = youKey
completion()
}
})
})
})
})
})
})
//}
}
此代码在登录过程中从ViewController.swift调用,如下所示:
func checkLoggedIn() {
Auth.auth().addStateDidChangeListener { auth, user in
if user != nil {
// User is signed in.
userUID = (user?.uid)!
self.theUser = user
if user?.photoURL == nil {
}else{
if let imageUrl = NSData(contentsOf: (user?.photoURL)!){
self.profilePic.image = UIImage(data: imageUrl as Data)
} else {
self.profilePic.image = UIImage(named: "bizzybooksbee")
}
}
self.masterRef = Database.database().reference().child("users").child(userUID)
self.projectsRef = Database.database().reference().child("users").child(userUID).child("projects")
self.entitiesRef = Database.database().reference().child("users").child(userUID).child("entities")
self.accountsRef = Database.database().reference().child("users").child(userUID).child("accounts")
self.vehiclesRef = Database.database().reference().child("users").child(userUID).child("vehicles")
self.youEntityRef = Database.database().reference().child("users").child(userUID).child("youEntity")
self.firstTimeRef = Database.database().reference().child("users").child(userUID).child("firstTime")
self.masterRef.observe(.value, with: { (snapshot) in
print("Do NOTTTT ANY thingggggg")
})
self.firstTimeRef.observeSingleEvent(of: .value, with: { (snapshot) in
if snapshot.exists() {
print("Do NOT any THING")
if self.shouldEnterLoop {
self.shouldEnterLoop = false
self.loadTheMIP()
}
} else {
self.initializeIfFirstAppUse()
}
})
print("ONE!")
self.masterRef.observe(.childChanged, with: { (snapshot) in // GENIUS!!!!! This line loads MIP only when an item gets added/changed/deleted (and exactly WHEN an item gets added/changed/deleted) in Firebase database IN REALTIME!!!!
print("TWO!")
if self.shouldEnterLoop {
self.shouldEnterLoop = false
print("THREE!")
if MIProcessor.sharedMIP.mipORsip == 0 {
self.loadTheMIP()
} else {
DispatchQueue.main.async {
MIProcessor.sharedMIP.loadTheMip {
MIProcessor.sharedMIP.obtainTheBalancesAfter()
MIProcessor.sharedMIP.loadTheStatuses()
MIProcessor.sharedMIP.updateTheMIP()
MIProcessor.sharedMIP.updateTheSIP(i: self.thingToBeSearchedInt, name: self.thingToBeSearchedName)
self.cardViewCollectionView.reloadData()//Critical line - this makes or breaks the app :/
}
}
}
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(5), execute: {
self.shouldEnterLoop = true
})
}
})
if MIProcessor.sharedMIP.mIP.count == 0 {
print("FOUR!")
if self.shouldEnterLoop {
self.shouldEnterLoop = false
print("FIVE!")
self.loadTheMIP()
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(5), execute: {
self.shouldEnterLoop = true
})
}
}
} else {
// No user is signed in.
self.login()
}
}
}
Brian Voong collectionView垂直大小的东西...
//Brian Voong inspiration... see if we can get vertical sizing of collectionview cells ie cardviews
extension ViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let i = indexPath.item
var baseHeight: CGFloat = 150
var sentenceOneHeight: CGFloat = 0
var sentenceTwoHeight: CGFloat = 0
var phoneHeight: CGFloat = 0
var emailHeight: CGFloat = 0
var geoHeight: CGFloat = 0
var ssnHeight: CGFloat = 0
var einHeight: CGFloat = 0
var imageHeight: CGFloat = 1
switch MIProcessor.sharedMIP.mipORsip {
case 1: // SIP!
switch MIProcessor.sharedMIP.sIP[i].multiversalType {
case 1: // Project
baseHeight = 130
if let projectItem = MIProcessor.sharedMIP.sIP[i] as? ProjectItem {
if projectItem.projectNotes != "" {
if projectItem.projectNotes.count < 30 {
phoneHeight = 25
} else if projectItem.projectNotes.count < 60 {
phoneHeight = 45
} else {
phoneHeight = 80
}
}
if projectItem.projectTags != "" {
if projectItem.projectTags.count < 30 {
emailHeight = 30
} else if projectItem.projectTags.count < 60 {
emailHeight = 60
} else {
emailHeight = 90
}
}
if projectItem.projectAddressStreet != "" {
sentenceOneHeight = 140
} else {
sentenceOneHeight = 100
}
}
sentenceTwoHeight = 180
case 2: // Entity
baseHeight = 160 //92
if let entityItem = MIProcessor.sharedMIP.sIP[i] as? EntityItem {
if (entityItem.phoneNumber != "") || (entityItem.email != "") || (entityItem.city != "") {
phoneHeight = 118
}
if entityItem.ssn != "" {
ssnHeight = 30
}
if entityItem.ein != "" {
einHeight = 30
}
}
case 3: // Account
baseHeight = 140 //92
if let accountItem = MIProcessor.sharedMIP.sIP[i] as? AccountItem {
if accountItem.phoneNumber != "" {
phoneHeight = 30
}
if accountItem.email != "" {
emailHeight = 38
}
if accountItem.street != "" {
if accountItem.city != "" {
if accountItem.state != "" {
geoHeight = 50
}
}
}
}
case 4: // Vehicle
baseHeight = 140 //92
if let vehicleItem = MIProcessor.sharedMIP.sIP[i] as? VehicleItem {
if vehicleItem.licensePlateNumber != "" {
phoneHeight = 25
}
if vehicleItem.vehicleIdentificationNumber != "" {
emailHeight = 25
}
if vehicleItem.placedInCommissionDate != "" {
geoHeight = 25
}
}
default: // Universal - Ie case 0 the most frequent
var longString = ""
if let universalItem = MIProcessor.sharedMIP.sIP[i] as? UniversalItem {
if universalItem.notes != "" {
if universalItem.notes.count < 30 {
phoneHeight = 25
} else if universalItem.notes.count < 60 {
phoneHeight = 45
} else {
phoneHeight = 80
}
}
imageHeight = (CGFloat(universalItem.picAspectRatio) / 1000) * widthConstraintConstant
switch universalItem.universalItemType {
case 1: // Personal
baseHeight = 100
longString = universalItem.whoName + universalItem.whomName + universalItem.taxReasonName
case 2: // Mixed
baseHeight = 160
switch universalItem.taxReasonId {
case 2: // Labor ie wc
longString = universalItem.whoName + universalItem.whomName + universalItem.personalReasonName + universalItem.taxReasonName + universalItem.workersCompName
case 5: // Vehicle
longString = universalItem.whoName + universalItem.whomName + universalItem.personalReasonName + universalItem.taxReasonName + universalItem.vehicleName
case 6: // AdMeans
longString = universalItem.whoName + universalItem.whomName + universalItem.personalReasonName + universalItem.taxReasonName + universalItem.advertisingMeansName
default: // Nothing important
longString = universalItem.whoName + universalItem.whomName + universalItem.personalReasonName + universalItem.taxReasonName
}
case 3: // Fuel
baseHeight = 70
longString = "At 234566 miles you paid $00.00 to " + universalItem.whomName + " for 00.000 gallons of 87 gas in your " + universalItem.vehicleName
case 4: // Transfer
baseHeight = 150
case 6: // Project Media
baseHeight = 80
default:
baseHeight = 120
switch universalItem.taxReasonId {
case 2: // Labor ie wc
longString = universalItem.whoName + universalItem.whomName + universalItem.taxReasonName + universalItem.workersCompName
case 5: // Vehicle
longString = universalItem.whoName + universalItem.whomName + universalItem.taxReasonName + universalItem.vehicleName
case 6: // AdMeans
longString = universalItem.whoName + universalItem.whomName + universalItem.taxReasonName + universalItem.advertisingMeansName
default: // Nothing important
longString = universalItem.whoName + universalItem.whomName + universalItem.taxReasonName
}
}
}
if longString.count < 15 {
sentenceOneHeight = 80
} else if longString.count < 40 {
sentenceOneHeight = 110
} else if longString.count < 65 {
sentenceOneHeight = 140
} else if longString.count < 80 {
sentenceOneHeight = 170
} else {
sentenceOneHeight = 200
}
}
let totalHeight = baseHeight + sentenceOneHeight + sentenceTwoHeight + phoneHeight + emailHeight + geoHeight + ssnHeight + einHeight + imageHeight
var theWidth: CGFloat = 0
if view.frame.width < 370 { //Protection for tiny iPhones
theWidth = view.frame.width - 20
} else { //Good for most iphones and safe for iPads
theWidth = 350
}
return CGSize(width: theWidth, height: totalHeight)
default: // I.e. case 0 MIP!
switch MIProcessor.sharedMIP.mIP[i].multiversalType {
case 1: // Project
baseHeight = 130
if let projectItem = MIProcessor.sharedMIP.mIP[i] as? ProjectItem {
if projectItem.projectNotes != "" {
if projectItem.projectNotes.count < 30 {
phoneHeight = 25
} else if projectItem.projectNotes.count < 60 {
phoneHeight = 45
} else {
phoneHeight = 80
}
}
if projectItem.projectTags != "" {
if projectItem.projectTags.count < 30 {
emailHeight = 30
} else if projectItem.projectTags.count < 60 {
emailHeight = 60
} else {
emailHeight = 90
}
}
if projectItem.projectAddressStreet != "" {
sentenceOneHeight = 140
} else {
sentenceOneHeight = 100
}
}
sentenceTwoHeight = 180
case 2: // Entity
baseHeight = 160 //92
if let entityItem = MIProcessor.sharedMIP.mIP[i] as? EntityItem {
if (entityItem.phoneNumber != "") || (entityItem.email != "") || (entityItem.city != "") {
phoneHeight = 118
}
if entityItem.ssn != "" {
ssnHeight = 30
}
if entityItem.ein != "" {
einHeight = 30
}
}
case 3: // Account
baseHeight = 140 //92
if let accountItem = MIProcessor.sharedMIP.mIP[i] as? AccountItem {
if accountItem.phoneNumber != "" {
phoneHeight = 30
}
if accountItem.email != "" {
emailHeight = 38
}
if accountItem.street != "" {
if accountItem.city != "" {
if accountItem.state != "" {
geoHeight = 50
}
}
}
}
case 4: // Vehicle
baseHeight = 140 //92
if let vehicleItem = MIProcessor.sharedMIP.mIP[i] as? VehicleItem {
if vehicleItem.licensePlateNumber != "" {
phoneHeight = 25
}
if vehicleItem.vehicleIdentificationNumber != "" {
emailHeight = 25
}
if vehicleItem.placedInCommissionDate != "" {
geoHeight = 25
}
}
default: // Universal - Ie case 0 the most frequent
var longString = ""
if let universalItem = MIProcessor.sharedMIP.mIP[i] as? UniversalItem {
if universalItem.notes != "" {
if universalItem.notes.count < 30 {
phoneHeight = 25
} else if universalItem.notes.count < 60 {
phoneHeight = 45
} else {
phoneHeight = 80
}
}
imageHeight = (CGFloat(universalItem.picAspectRatio) / 1000) * widthConstraintConstant
switch universalItem.universalItemType {
case 1: // Personal
baseHeight = 100
longString = universalItem.whoName + universalItem.whomName + universalItem.taxReasonName
case 2: // Mixed
baseHeight = 160
switch universalItem.taxReasonId {
case 2: // Labor ie wc
longString = universalItem.whoName + universalItem.whomName + universalItem.personalReasonName + universalItem.taxReasonName + universalItem.workersCompName
case 5: // Vehicle
longString = universalItem.whoName + universalItem.whomName + universalItem.personalReasonName + universalItem.taxReasonName + universalItem.vehicleName
case 6: // AdMeans
longString = universalItem.whoName + universalItem.whomName + universalItem.personalReasonName + universalItem.taxReasonName + universalItem.advertisingMeansName
default: // Nothing important
longString = universalItem.whoName + universalItem.whomName + universalItem.personalReasonName + universalItem.taxReasonName
}
case 3: // Fuel
baseHeight = 70
longString = "At 234566 miles you paid $00.00 to " + universalItem.whomName + " for 00.000 gallons of 87 gas in your " + universalItem.vehicleName
case 4: // Transfer
baseHeight = 150
case 6: // Project Media
baseHeight = 80
default:
baseHeight = 120
switch universalItem.taxReasonId {
case 2: // Labor ie wc
longString = universalItem.whoName + universalItem.whomName + universalItem.taxReasonName + universalItem.workersCompName
case 5: // Vehicle
longString = universalItem.whoName + universalItem.whomName + universalItem.taxReasonName + universalItem.vehicleName
case 6: // AdMeans
longString = universalItem.whoName + universalItem.whomName + universalItem.taxReasonName + universalItem.advertisingMeansName
default: // Nothing important
longString = universalItem.whoName + universalItem.whomName + universalItem.taxReasonName
}
}
}
if longString.count < 15 {
sentenceOneHeight = 80
} else if longString.count < 40 {
sentenceOneHeight = 110
} else if longString.count < 65 {
sentenceOneHeight = 140
} else if longString.count < 80 {
sentenceOneHeight = 170
} else {
sentenceOneHeight = 200
}
}
let totalHeight = baseHeight + sentenceOneHeight + sentenceTwoHeight + phoneHeight + emailHeight + geoHeight + ssnHeight + einHeight + imageHeight
var theWidth: CGFloat = 0
if view.frame.width < 370 { //Protection for tiny iPhones
theWidth = view.frame.width - 20
} else { //Good for most iphones and safe for iPads
theWidth = 350
}
return CGSize(width: theWidth, height: totalHeight)
}
}
}
发布于 2019-01-21 18:01:20
我想通了!
从Firebase获取金融交易数据并不是最慢的。
问题是,在获得数据后,我从起始银行余额开始,遍历了用户的所有交易,并进行了调整,以便每个交易都显示当时的银行余额。对于几千个交易,这显然需要大量的时间。
通过将所有银行余额设置为$0.00并将计算放在后台线程中,然后在完成后更新UI,现在只需大约一秒钟即可加载(仍需等待19秒才能更新当前余额):
DispatchQueue.global(qos: .background).async {
// do your job here
MIProcessor.sharedMIP.obtainTheBalancesAfter()
MIProcessor.sharedMIP.updateTheMIP()
DispatchQueue.main.async {
// update ui here
self.cardViewCollectionView.reloadData()
}
}
https://stackoverflow.com/questions/54000791
复制相似问题