В моем приложении есть функция покупки в интернет-магазине, использующая платежный адрес. У меня также есть список адресов для выставления счетов, и нажмите на ячейку адреса в списке, чтобы перейти на страницу редактирования адреса. Но после того, как я запустил функцию покупки, отредактировал адрес и вернусь на страницу списка адресов для выставления счетов, приложение перестанет работать. (Если я отредактирую адрес без покупки, все будет хорошо)
Ошибка показывает:
Terminating app due to uncaught exception 'RLMException', reason: 'Object has been deleted or invalidated.'
И
libc++abi.dylib: terminating with uncaught exception of type NSException
А также в AppDelegate.swift ,
"Thread 1: signal SIGABRT"
Ошибка показа в этой строке:
class AppDelegate: UIResponder, UIApplicationDelegate {
Вот код списка адресов для выставления счетов (который содержит много ячеек с адресами для выставления счетов). Нажмите на ячейку, чтобы перейти к функции редактирования адреса:
import Foundation
import PKHUD
class ManageBillingAddressVC: _BaseViewController {
@objc var billingAddress: [UserBillingAddress] = [] { //= Address.getAllAddressLists()
didSet {
emptyView.isHidden = billingAddress.count != 0
}
}
let viewModel = BillingAddressViewModel()
@IBOutlet weak var tblBillingAddress: UITableView!
@IBOutlet weak var emptyView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
setUpNavBarWithAttributes(navtitle: "Manage Billing Address", setStatusBarStyle: .default, isTransparent: false, tintColor: .white, titleColor: Color.Tuna.instance(), titleFont: FontBook.AdobePro.navSize(), isBackHidden: false, isShadowIncluded: true, rightBarButton: [showGoldPlusBtn()])
viewModelCallBack()
initTableViews()
observeAdressUpdateNotification()
}
@objc func viewModelCallBack() {
viewModel.beforeApiCall = {
HUD.show(.systemActivity)
}
viewModel.afterApiCall = {
HUD.hide()
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.setNavigationBarHidden(false, animated: true)
fetchBillingAddress()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.navigationController?.setNavigationBarHidden(true, animated: true)
}
@objc func updateDeliveryAddressTable() {
fetchBillingAddress()
}
@objc func fetchBillingAddress() {
viewModel.getBillingAddress(success: {
self.billingAddress.removeAll()
for address in $0{
if address.crm_address_order != "postal_address"{
self.billingAddress.append(address)
}
}
self.tblBillingAddress.reloadData()
}) {
self.showAlert($0)
}
}
@objc func observeAdressUpdateNotification() {
NotificationCenter.default.addObserver(self, selector: #selector(updateDeliveryAddressTable), name: Constants.billingAddress, object: nil)
}
override func rightBarButtonClicked() {
viewModel.getBillingAddress(success: {
self.billingAddress.removeAll()
for address in $0{
if address.crm_address_order != "postal_address"{
self.billingAddress.append(address)
}
}
if self.billingAddress.count >= 3{
self.showAlert("Addresses are limited to a maximum of 3")
}else{
self.pushViewControllerWithSlideUpEffect(vc: UIStoryboard.AddBillingAddress())
}
self.tblBillingAddress.reloadData()
}) {
self.showAlert($0)
}
}
@objc func initTableViews() {
tblBillingAddress.register(UINib(nibName : "BillingAddressCell", bundle : nil), forCellReuseIdentifier: "BillingAddressCell")
tblBillingAddress.dataSource = self
tblBillingAddress.delegate = self
tblBillingAddress.separatorStyle = .none
tblBillingAddress.contentInset = UIEdgeInsetsMake(20, 0, 20, 0)
tblBillingAddress.rowHeight = UITableViewAutomaticDimension
tblBillingAddress.estimatedRowHeight = 165 //108
}
deinit {
NotificationCenter.default.removeObserver(self)
}
}
extension ManageBillingAddressVC: DeliveryAddressCellDelegate {
@objc func didSelectBillingAddress(address: UserBillingAddress, index: Int) {
guard let vc = UIStoryboard.AddBillingAddress() as? AddBillingAddressVC else { return }
vc.billingAddress = address
pushViewControllerWithSlideUpEffect(vc: vc)
}
}
extension ManageBillingAddressVC: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return billingAddress.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "BillingAddressCell" ) as! BillingAddressCell
cell.delegate = self
cell.billingAddress = billingAddress[indexPath.row]
//cell.address = billingAddress[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: false)
}
}
Вот моя ячейка платежного адреса в коде списка адресов:
import UIKit
class BillingAddressCell: DeliveryAddresCell {
@objc var billingAddress: UserBillingAddress? {
didSet {
billingAddress.flatMap {
lblName.text = "\($0.salutation ?? ""). \($0.firstname ?? "") \($0.lastname ?? "")"
lblAddress.text = $0.street?.first
lblPhoneNo.text = $0.telephone
lblUnitNo.text = $0.unit_number
lblStateCountry.text = "\($0.region?.first?.region ?? ""), \($0.postcode ?? "")"
if let id = $0.country_id, let countryID = Int(id) {
lblCountry.text = CountryList.getCountryName(id: countryID)
}
}
}
}
override func btnEditTapped(_ sender: UIButton) {
delegate?.didSelectBillingAddress(address: billingAddress!, index: tag)
}
}
Вот функция для получения / обновления адреса выставления счета:
class UserBillingAddress: UserBillingAddressInformation {
@objc var id : String?
@objc var customerID: String?
required convenience init?(map: Map){
self.init()
}
override func mapping(map: Map){
super.mapping(map: map)
id <- map["id"]
customerID <- map["customer_id"]
}
}
Вот код того, что произошло после нажатия кнопки «Оформить заказ» в процессе покупки:
@IBAction func btnCheckoutTapped(_ sender: UIButton) {
guard let card = defaultCreditCard, let address = defaultAddress else { return }
baseViewModel.checkCartLimit(success: { checkLimit in
if let limitErrors = checkLimit.limit_errors {
if limitErrors.count > 0 {
self.baseViewModel.handleCheckLimitError?(checkLimit)
} else {
guard let processingVC = UIStoryboard.ProcessingOrderVC() as? ProcessingOrderVC else { return }
// present processing view
processingVC.modalPresentationStyle = .overCurrentContext
processingVC.defaultAddress = address
processingVC.defaultCreditCard = card
processingVC.isSkyDollarPurchaseForMembership = self.isSkyDollarPurchaseForMembership
processingVC.isMembershipProduct = self.isMembershipProduct
processingVC.isFullSkyDollarPurchase = self.isFullSkyDollarPurchase
self.present(processingVC, animated: true)
}
} else {
guard let processingVC = UIStoryboard.ProcessingOrderVC() as? ProcessingOrderVC else { return }
// present processing view
processingVC.modalPresentationStyle = .overCurrentContext
processingVC.defaultAddress = address
processingVC.defaultCreditCard = card
processingVC.isSkyDollarPurchaseForMembership = self.isSkyDollarPurchaseForMembership
processingVC.isMembershipProduct = self.isMembershipProduct
self.present(processingVC, animated: true)
}
}, failure: { (errorMessage) in
self.showAlert(errorMessage)
})
}
А вот код для обработки покупки после нажатия на кнопку оформления заказа:
import UIKit
class ProcessingOrderVC: UIViewController {
@IBOutlet weak var orderProcessingStackView: UIStackView!
@IBOutlet weak var orderProcessErrorStackView: UIStackView!
@IBOutlet weak var btnOkay: UIButton!
@IBOutlet weak var lblError: UILabel!
@objc var isMembershipProduct : Bool = false
@objc var isSkyDollarPurchaseForMembership : Bool = false
@objc var isFullSkyDollarPurchase: Bool = false
let checkoutViewModel = CheckoutStep2ViewModel()
@objc var defaultAddress = Address()
@objc var defaultCreditCard = CreditCardData()
override func viewDidLoad() {
super.viewDidLoad()
let attributedTitle = NSAttributedString(string: "TRY AGAIN", attributes: [NSAttributedStringKey.kern: 1.3, NSAttributedStringKey.font : FontBook.Bold.of(size: 13.0), NSAttributedStringKey.foregroundColor: UIColor.white])
btnOkay?.setAttributedTitle(attributedTitle, for: .normal)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if isSkyDollarPurchaseForMembership{
self.checkoutViewModel.placeOrderWithSkyDollarForMembership(address: defaultAddress, success: { orderID in
(UIStoryboard.CheckoutStep3VC() as? CheckoutStep3VC).flatMap {
$0.orderID = orderID
$0.hero.modalAnimationType = .fade
self.present($0, animated: false, completion: nil)
}
}) { (error) in
self.showError()
}
}else{
self.checkoutViewModel.placeOrder(address: defaultAddress, card: defaultCreditCard, isFullSkyDollarPurchase: isFullSkyDollarPurchase, success: { orderID in
(UIStoryboard.CheckoutStep3VC() as? CheckoutStep3VC).flatMap {
$0.orderID = orderID
$0.hero.modalAnimationType = .fade
self.present($0, animated: false, completion: nil)
}
}) { (error) in
self.showError()
}
}
}
@IBAction func btnCloseTapped(_ sender: UIButton) {
self.dismiss(animated: true, completion: nil)
}
@IBAction func btnOkayTapped(_ sender: UIButton) {
self.dismiss(animated: true, completion: nil)
}
@objc func showError() {
orderProcessErrorStackView.isHidden = false
orderProcessingStackView.isHidden = true
}
}
Вот переменная defaultAddress и адрес класса:
@objc var defaultAddress = Address()
class Address : Object, Mappable{
@objc dynamic var id: Int = 0
@objc dynamic var customerId: Int = 0
@objc dynamic var region: Region? = nil
@objc dynamic var region_id: Int = 0
@objc dynamic var countryId: String = ""
let streets = List<Street>()
@objc dynamic var telephone: String = ""
@objc dynamic var postcode: String = ""
@objc dynamic var city: String = ""
@objc dynamic var prefix: String = ""
@objc dynamic var company: String = ""
@objc dynamic var firstname: String = ""
@objc dynamic var lastname: String = ""
@objc dynamic var defaultShipping: Bool = false
@objc dynamic var defaultBilling: Bool = false
var addressAttributes = List<AddressAttributes>()
required convenience init?(map: Map){
self.init()
}
По праву процесс покупки не обновит адрес, но если я не совершу покупку, то при редактировании адреса не возникнет ошибки. Ошибка происходит только после совершения покупки. Я действительно не знаю, что случилось. Кто-нибудь может подсказать в чем может быть проблема?
Я новичок в iOS, поэтому, пожалуйста, уточните, как решить проблему. Большое спасибо!