创建ViewModel时,iOS模拟器出现黑屏



当我应该创建ProfileViewModel时,我遇到了一个奇怪的错误。我将ViewModel创建为@StateObject,然后通过.environmentObject()将其传递给其他视图。不幸的是,当我启动模拟器时,只有当创建了这个特定的ViewModel时,我才会有黑屏。当我评论创建它的行时,我会在屏幕上看到内容。

我在这里创建它:

@StateObject private var profileViewModel = ProfileViewModel()

我在这里将其传递给其他视图:

case .profile:
withAnimation(.linear) {
ProfileView()
.environmentObject(authStateManager)
.environmentObject(tabBarStateManager)
.environmentObject(profileViewModel)
}

我的ProfileViewModel看起来像这样:

import UIKit
class ProfileViewModel: ObservableObject {
@Published var profile: Profile = Profile.demoProfile
@Published var orders: [Order] = Order.demoOrders
@Published var returns: [Return] = Return.demoReturns

@Published var oldImage = UIImage(named: "blank_profile_image")!
@Published var image = UIImage(named: "blank_profile_image")!

@Published var shouldPresentOrderRateView: Bool = false
@Published var shouldPresentReturnCreationView: Bool = false

var datesForOrdersViewListSections: [String] {
var ordersShortDates: [String] = []
for order in orders {
ordersShortDates.append(Date.getMonthNameAndYearFrom(date: order.orderDate))
}
return ordersShortDates.uniqued().sorted { firstDate, secondDate in
firstDate.suffix(4) > secondDate.suffix(4)
}
}

var datesForReturnsViewListSections: [String] {
var returnsShortDates: [String] = []
for userReturn in returns {
returnsShortDates.append(Date.getMonthNameAndYearFrom(date: userReturn.returnDate))
}
return returnsShortDates.uniqued().sorted { firstDate, secondDate in
firstDate.suffix(4) > secondDate.suffix(4)
}
}
func uploadPhoto() {
if !image.isEqual(oldImage) {
oldImage = image
}
}

func getOrdersFor(date: String) -> [Order] {
return orders.filter {
Date.getMonthNameAndYearFrom(date: $0.orderDate) == date
}
}

func getReturnsFor(date: String) -> [Return] {
return returns.filter {
Date.getMonthNameAndYearFrom(date: $0.returnDate) == date
}
}

func changeDefaultAddress(address: Address) {
removeAddress(address: address)
profile.otherAddresses.append(profile.address)
profile.address = address
}

func removeAddress(address: Address) {
for (index, otherAddress) in profile.otherAddresses.enumerated() {
if otherAddress == address {
profile.otherAddresses.remove(at: index)
break
}
}
}

func editPersonalData(firstName: String = "", lastName: String = "", emailAddress: String = "") {
if !firstName.isEmpty {
profile.firstName = firstName
}
if !lastName.isEmpty {
profile.lastName = lastName
}
if !emailAddress.isEmpty {
profile.email = emailAddress
}
}

func addNewAddress(address: Address, toBeDefault: Bool = false) {
if toBeDefault {
profile.otherAddresses.append(profile.address)
profile.address = address
} else {
profile.otherAddresses.append(address)
}
}

func editCardData(cardNumber: String, validThru: String, cardholderName: String) {
if profile.creditCard != nil {
profile.creditCard!.cardNumber = cardNumber
profile.creditCard!.validThru = validThru
profile.creditCard!.cardholderName = cardholderName
}
}

func addNewCard(card: CreditCard) {
profile.creditCard = card
}

func changeDefaultPaymentMethod(newDefaultPaymentMethod: PaymentMethod) {
profile.defaultPaymentMethod = newDefaultPaymentMethod
}

func addUserRating(productID: String, rating: Int, review: String?) {
profile.addRatingFor(productID: productID, rating: rating, review: review)
}
}

老实说,我不知道为什么会发生这种事。直到某个时刻,一切都很好。我对未连接到ViewModel的逻辑进行了一些更改,并从xcode package manager安装了KingFisher package。然后我卸载了它,因为我不再需要它。一切都在卸载它之前就开始了。我无法链接任何可能导致它的操作,从那以后我也没有对ProfileViewModel进行过任何更改。

我已经试过了:

  1. 重新启动xcode和我的mac
  2. 正在清理派生数据文件夹
  3. 放弃(使用GIT(我对代码所做的任何更改

Xcode控制台显示没有输出,没有错误,一切都建立了良好的

事实上,我现在发现我的应用程序不想显示任何内容,因为ProfileViewModel:的两个属性

@Published var orders: [Order] = Order.demoOrders
@Published var returns: [Return] = Return.demoReturns

当这两个结构都被注释掉时,一切都会按预期进行。

上述结构:Order

import Foundation
struct Order {
var id: String = UUID().uuidString
var orderDate: Date = Date()
var estimatedDeliveryDate: Date
var client: Profile
var shoppingCart: Cart
var shippingMethod: ShippingMethod
var shippingAddress: Address
var paymentMethod: PaymentMethod = .creditCard
var invoice: Bool
var totalCost: Double
var status: OrderStatus = .placed

init(client: Profile, shoppingCart: Cart, shippingMethod: ShippingMethod, shippingAddress: Address, paymentMethod: PaymentMethod = .creditCard, invoice: Bool = false) {
self.client = client
self.shoppingCart = shoppingCart
self.shippingMethod = shippingMethod
self.shippingAddress = shippingAddress
self.paymentMethod = paymentMethod
self.invoice = invoice

self.estimatedDeliveryDate = calculateEstimatedDeliveryDate(orderDate: Date())

self.totalCost = shoppingCart.products.keys.map { $0.price }.reduce(0, +)
}
}
extension Order: Equatable, Hashable {
static func == (lhs: Order, rhs: Order) -> Bool {
return lhs.id == rhs.id
}

func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
}
extension Order: CustomStringConvertible {
var description: String {
"(id)nOrder Date: (Date.getDayMonthYearFrom(date: orderDate))nEstimated Delivery Date: (Date.getDayMonthYearFrom(date: estimatedDeliveryDate))nShipping Method: (shippingMethod.rawValue)nPayment Method: (paymentMethod.rawValue)nTotal Cost: (totalCost)nStatus: (status)"
}
}
extension Order {
static let demoOrders: [Order] = [Order(client: Profile.demoProfile,
shoppingCart: Cart.demoCart,
shippingMethod: .pickup,
shippingAddress: Address.demoAddress),
Order(client: Profile.demoProfile,
shoppingCart: Cart.demoCart,
shippingMethod: .parcel,
shippingAddress: Address.demoAddress),
Order(client: Profile.demoProfile,
shoppingCart: Cart.demoCart,
shippingMethod: .parcel,
shippingAddress: Address.demoAddress),
Order(client: Profile.demoProfile,
shoppingCart: Cart.demoCart,
shippingMethod: .parcel,
shippingAddress: Address.demoAddress)]
}

Return:

import Foundation
struct Return {
var id: String = UUID().uuidString
var returnDate: Date = Date()
var clientID: String
var orderID: String
var products: [Product]
var returnPrice: Double
var returnMethod: ShippingMethod
var status: ReturnStatus = .reported

var bankAccountNumber: String = ""
var bankAccountOwnerName: String = ""
var bankAccountOwnerStreetAndHouseNumber: String = ""
var bankAccountOwnerPostalCode: String = ""
var bankAccountOwnerCity: String = ""
var bankAccountOwnerCountry: String = ""
}
enum ReturnStatus: String {
case reported = "Reported"
case sent = "Sent"
case delivered = "Delivered"
case moneyReturned = "Money returned"
case closed = "Closed"
}
extension Return: Equatable, Hashable {
static func == (lhs: Return, rhs: Return) -> Bool {
return lhs.id == rhs.id
}

func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
}
extension Return: CustomStringConvertible {
var description: String {
"(id)nReturn Date: (Date.getDayMonthYearFrom(date: returnDate))nClient ID: (clientID)nOrder ID: (orderID)nReturn Price: (returnPrice)nReturn Method: (returnMethod.rawValue)nStatus: (status.rawValue)"
}
}
extension Return {
static let demoReturns: [Return] = [Return(id: UUID().uuidString,
returnDate: Date(),
clientID: Profile.demoProfile.id,
orderID: Order.demoOrders[0].id,
products: Product.demoProducts,
returnPrice: Order.demoOrders[0].totalCost,
returnMethod: Order.demoOrders[0].shippingMethod,
status: .reported),
Return(id: UUID().uuidString,
returnDate: Date(),
clientID: Profile.demoProfile.id,
orderID: Order.demoOrders[1].id,
products: Product.demoProducts,
returnPrice: Order.demoOrders[1].totalCost,
returnMethod: Order.demoOrders[1].shippingMethod,
status: .reported)]
}

我尝试从这些结构中删除单个属性,如Profile、Cart或Products,但问题仍然存在。

这是我用Swift见过的最奇怪的bug。当我发现问题与有关时

@Published var orders: [Order] = Order.demoOrders
@Published var returns: [Return] = Return.demoReturns

ProfileViewModel中构建的结构,然后我尝试从orders开始从头开始创建它们,比如:

@Published var orders: [Order] = [Order(client: Profile(firstName: "",
lastName: "",
username: "",
birthDate: Date(),
email: "",
address: Address(streetName: "",
      streetNumber: "",
      apartmentNumber: "",
      zipCode: "",
      city: "",
      country: "")),
shoppingCart: Cart(),
shippingMethod: .courier,
shippingAddress: Address(streetName: "",
streetNumber: "",
apartmentNumber: "",
zipCode: "",
city: "",
country: ""))]

突然间,一切都开始工作了,所以我又回到了:

@Published var orders: [Order] = Order.demoOrders
@Published var returns: [Return] = Return.demoReturns

再也没有黑屏了!不知道到底是什么原因造成的。

找到解决方案。事实证明,我的一个函数,用于计算演示订单的预计交付日期,在应用程序开始时创建了无限循环,因此屏幕上没有显示任何内容,也无法打印任何内容。

func calculateEstimatedDeliveryDate(orderDate: Date) -> Date {
var dayComponent = DateComponents()
dayComponent.day = 2
var estimatedDeliveryDate = Calendar.current.date(byAdding: dayComponent, to: Date())

dayComponent.day = 1
while Calendar.current.isDateInWeekend(estimatedDeliveryDate!) {
estimatedDeliveryDate = Calendar.current.date(byAdding: dayComponent, to: Date())
}

return estimatedDeliveryDate!
}

当我创建无限循环时,问题就在这一行:

estimatedDeliveryDate = Calendar.current.date(byAdding: dayComponent, to: Date())

将当前日期增加一天,并再次检查是否为周末。如果做得好,应该是:

estimatedDeliveryDate = Calendar.current.date(byAdding: dayComponent, to: estimatedDeliveryDate!)

第一个时间问题发生在周四,一天后就消失了,当时可以计算出应用程序不会陷入无限循环——肯定是周五,因为我们将在当前日期的基础上增加两天,并检查下一天是否是周末。这不是一个周末,所以应用程序";自身解锁";。同样的情况是周四晚上第二次出现问题,我通过发现它的来源来解决它,而无需等待。

最新更新