Skip to content

Commit

Permalink
Fix Error Display for ViewControllers and Enhance Performance
Browse files Browse the repository at this point in the history
- Resolved the issue of displaying errors only for ViewControllers by adding an error publisher.
- Improved performance by replacing the @published property with PassthroughSubject.
  • Loading branch information
helloItsHEssam committed Nov 6, 2023
1 parent f86c65d commit c7234b3
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 20 deletions.
2 changes: 1 addition & 1 deletion Domain/Sources/Domain/Error/PersonBankAccountError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public enum PersonBankAccountError: Error {
case cannotFetchFavoritePersonAccounts
case unexpectedError

var errorDescription: String? {
public var errorDescription: String? {
switch self {
case .cannotSavePersonAccountToFavorites:
return "Failed to save person accounts to favorites"
Expand Down
12 changes: 12 additions & 0 deletions TransferList.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
DEFF1DEA2AF93B1200673B8C /* Router.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEFF1DE92AF93B1200673B8C /* Router.swift */; };
DEFF1DEC2AF93E2F00673B8C /* HeaderInformationCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEFF1DEB2AF93E2F00673B8C /* HeaderInformationCell.swift */; };
DEFF1DEE2AF949FC00673B8C /* AddRemoveFavoriteCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEFF1DED2AF949FC00673B8C /* AddRemoveFavoriteCell.swift */; };
DEFF1DF12AF969F600673B8C /* UIViewController+Alert.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEFF1DF02AF969F600673B8C /* UIViewController+Alert.swift */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand Down Expand Up @@ -71,6 +72,7 @@
DEFF1DE92AF93B1200673B8C /* Router.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Router.swift; sourceTree = "<group>"; };
DEFF1DEB2AF93E2F00673B8C /* HeaderInformationCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeaderInformationCell.swift; sourceTree = "<group>"; };
DEFF1DED2AF949FC00673B8C /* AddRemoveFavoriteCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddRemoveFavoriteCell.swift; sourceTree = "<group>"; };
DEFF1DF02AF969F600673B8C /* UIViewController+Alert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Alert.swift"; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -207,6 +209,7 @@
DEFF1DC52AF8EAC700673B8C /* Extra */ = {
isa = PBXGroup;
children = (
DEFF1DEF2AF969EB00673B8C /* Extension */,
DEFF1DC62AF8EACB00673B8C /* Core */,
);
path = Extra;
Expand Down Expand Up @@ -269,6 +272,14 @@
path = Cell;
sourceTree = "<group>";
};
DEFF1DEF2AF969EB00673B8C /* Extension */ = {
isa = PBXGroup;
children = (
DEFF1DF02AF969F600673B8C /* UIViewController+Alert.swift */,
);
path = Extension;
sourceTree = "<group>";
};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
Expand Down Expand Up @@ -364,6 +375,7 @@
DEFF1DE12AF9356200673B8C /* DetailAccountDataSource.swift in Sources */,
DEFF1DEE2AF949FC00673B8C /* AddRemoveFavoriteCell.swift in Sources */,
DEFF1DD52AF9122D00673B8C /* ViewState.swift in Sources */,
DEFF1DF12AF969F600673B8C /* UIViewController+Alert.swift in Sources */,
DEFF1DD92AF92DB500673B8C /* AccountCell.swift in Sources */,
DEBE4AC32AF6C3B000A58501 /* AppDelegate.swift in Sources */,
DEBE4AC52AF6C3B000A58501 /* SceneDelegate.swift in Sources */,
Expand Down
19 changes: 19 additions & 0 deletions TransferList/Extra/Extension/UIViewController+Alert.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// UIViewController+Alert.swift
// TransferList
//
// Created by Hessam Mahdiabadi on 11/6/23.
//

import UIKit

extension UIViewController {

func showAlert(title: String, message: String) {
let dialogMessage = UIAlertController(title: title, message: message, preferredStyle: .alert)
let ok = UIAlertAction(title: "OK", style: .default)

dialogMessage.addAction(ok)
self.present(dialogMessage, animated: true, completion: nil)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,14 @@ class DetailAccountViewConroller: BaseCollectionViewController {
}

private func observeDidChangeData() {
viewModel.$viewState
.compactMap { $0 }
viewModel.errorForSavingOrRemoving
.drop(while: {
$0 == .loading || $0 == .result
})
.compactMap { String(describing: $0) }
.sink { [weak self] errorMessage in
guard let self else { return }
print(errorMessage)
self.showAlert(title: "Error", message: errorMessage)
}
.store(in: &subscriptions)

Expand Down
17 changes: 14 additions & 3 deletions TransferList/Presentation/HomeScene/View/HomeViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,14 @@ class HomeViewController: BaseCollectionViewController {
}

private func observeDidChangeData() {
viewModel.$dataUpdated
.compactMap { $0 }
viewModel.dataUpdated
.sink { [weak self] data in
self?.refresher.endRefreshing()
self?.dataSource.updateData(data)
}
.store(in: &subscriptions)

viewModel.$changeView
viewModel.changeView
.compactMap { $0 }
.sink { [weak self] route in
guard case let .detail(account) = route else {
Expand All @@ -75,6 +74,18 @@ class HomeViewController: BaseCollectionViewController {
.sink { [weak self] account in
self?.dataSource.updateAccount(account: account)
}.store(in: &subscriptions)

viewModel.$viewState
.compactMap { $0 }
.drop(while: {
$0 == .loading || $0 == .result
})
.compactMap { String(describing: $0) }
.sink { [weak self] errorMessage in
guard let self else { return }
self.showAlert(title: "Error", message: errorMessage)
}
.store(in: &subscriptions)
}

private func navigateToDetailViewController(withAccount account: PersonBankAccount) {
Expand Down
9 changes: 6 additions & 3 deletions TransferList/Presentation/HomeScene/View/Main.storyboard
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17150" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="21701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Y6W-OH-hqX">
<device id="retina6_12" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17122"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21679"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
Expand All @@ -12,14 +14,15 @@
<objects>
<viewController id="Y6W-OH-hqX" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="5EZ-qb-Rvc">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<viewLayoutGuide key="safeArea" id="vDu-zF-Fre"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Ief-a0-LHa" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="138" y="5"/>
</scene>
</scenes>
<resources>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ import Domain
class TransferViewModel {

@Published var viewState: ViewState!
@Published var dataUpdated: DataTransfer<PersonBankAccount>!
@Published var changeView: Router!
var dataUpdated = PassthroughSubject<DataTransfer<PersonBankAccount>, Never>()
var errorForSavingOrRemoving = PassthroughSubject<ViewState, Never>()
var changeView = PassthroughSubject<Router, Never>()
var favoriteStatusUpdated = PassthroughSubject<PersonBankAccount, Never>()
private let useCase: PersonBankAccountUseCase
private var subscriptions = Set<AnyCancellable>()
Expand Down Expand Up @@ -49,7 +50,7 @@ class TransferViewModel {
dataFromServer.append(contentsOf: accounts)
}

dataUpdated = dataFromServer
dataUpdated.send(dataFromServer)
}

public func fetchFavoriteList() {
Expand All @@ -61,7 +62,7 @@ class TransferViewModel {
self.dataFromLocal = .init(list: accounts,
mode: .initial,
section: .favoriteBankAcconts)
self.dataUpdated = self.dataFromLocal
self.dataUpdated.send(self.dataFromLocal)
})
.store(in: &subscriptions)
}
Expand All @@ -78,15 +79,15 @@ class TransferViewModel {
case .finished: break

case .failure(let error):
updateViewState(newState: .error(message: error.localizedDescription))
self.updateViewState(newState: .error(message: error.errorDescription ?? "Unexpected error"))
break
}

} receiveValue: { [weak self] accounts in
guard let self else { return }
self.updateAccounts(appendAccounts: accounts)
self.paginationMode.moveToNextOffset()
updateViewState(newState: .result)
self.updateViewState(newState: .result)
}
.store(in: &subscriptions)
}
Expand All @@ -111,7 +112,7 @@ class TransferViewModel {
}

public func accountSelected(_ account: PersonBankAccount) {
changeView = .detail(account: account)
changeView.send(.detail(account: account))
}

public func removeFromFavorite(account: PersonBankAccount) {
Expand All @@ -123,7 +124,8 @@ class TransferViewModel {
switch completion {
case .finished: break
case .failure(let error):
self.updateViewState(newState: .error(message: error.localizedDescription))
let viewError = ViewState.error(message: error.errorDescription ?? "Unexpected error")
self.errorForSavingOrRemoving.send(viewError)
break
}

Expand All @@ -141,11 +143,12 @@ class TransferViewModel {
switch completion {
case .finished: break
case .failure(let error):
self.updateViewState(newState: .error(message: error.localizedDescription))
let viewError = ViewState.error(message: error.errorDescription ?? "Unexpected error")
self.errorForSavingOrRemoving.send(viewError)
break
}

} receiveValue: { [weak self] account in
} receiveValue: { [weak self] account in
self?.favoriteStatusUpdated.send(account)
}.store(in: &subscriptions)
}
Expand Down

0 comments on commit c7234b3

Please sign in to comment.