Skip to content

Commit fa2ebbc

Browse files
authored
Feature/swnetworkclient package (#129)
* Вынес APIService в новый пакет SWNetworkClient + добавил ворнинги на лишние вьюмодели * Поднял версию билда до 2 * Небольшой рефактор и обновление неймингов
1 parent 19cf3a9 commit fa2ebbc

37 files changed

+1491
-1415
lines changed

SwiftUI-WorkoutApp.xcodeproj/project.pbxproj

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
6758463F2965B7F2000BA5E0 /* ImageDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6758463E2965B7F2000BA5E0 /* ImageDetailView.swift */; };
3535
6758B92A281D8FD7001D83D8 /* SportsGroundDetailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6758B929281D8FD7001D83D8 /* SportsGroundDetailViewModel.swift */; };
3636
6758B92C281D9283001D83D8 /* EventFormViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6758B92B281D9283001D83D8 /* EventFormViewModel.swift */; };
37-
6758B936281E5EA9001D83D8 /* APIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6758B935281E5EA9001D83D8 /* APIService.swift */; };
3837
675A370A2854810B00DAE071 /* Utils in Frameworks */ = {isa = PBXBuildFile; productRef = 675A37092854810B00DAE071 /* Utils */; };
3938
675E5618297D21D400B4981A /* Array+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 675E5617297D21D400B4981A /* Array+.swift */; };
4039
675EC64F2814126800C2E229 /* TextEntryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 675EC64E2814126800C2E229 /* TextEntryView.swift */; };
@@ -52,6 +51,7 @@
5251
6773111A2965FFAA003CD13A /* PreviewContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 677311192965FFAA003CD13A /* PreviewContent.swift */; };
5352
67891E36283E945100B10802 /* SportsGroundFormViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67891E35283E945100B10802 /* SportsGroundFormViewModel.swift */; };
5453
67891E38283E947B00B10802 /* SportsGroundFormView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67891E37283E947B00B10802 /* SportsGroundFormView.swift */; };
54+
678E3B1C2ACDEFFA00977EEC /* SWNetworkClient in Frameworks */ = {isa = PBXBuildFile; productRef = 678E3B1B2ACDEFFA00977EEC /* SWNetworkClient */; };
5555
6798AA3E280AEDC900DB76F1 /* SwiftUI_WorkoutAppApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6798AA3D280AEDC900DB76F1 /* SwiftUI_WorkoutAppApp.swift */; };
5656
6798AA40280AEDC900DB76F1 /* RootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6798AA3F280AEDC900DB76F1 /* RootView.swift */; };
5757
6798AA42280AEDCA00DB76F1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6798AA41280AEDCA00DB76F1 /* Assets.xcassets */; };
@@ -72,11 +72,9 @@
7272
679F3B072969D4E200BB3590 /* IncognitoUserButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 679F3B062969D4E200BB3590 /* IncognitoUserButton.swift */; };
7373
67A079F22A758E7D005EAF70 /* PickedPhotoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67A079F12A758E7D005EAF70 /* PickedPhotoView.swift */; };
7474
67A64A242AC83A0F00CBDD5F /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 67A64A232AC83A0F00CBDD5F /* Localizable.xcstrings */; };
75-
67A6FEF529E1DD0F002DCBA1 /* DeviceOSVersionChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67A6FEF429E1DD0F002DCBA1 /* DeviceOSVersionChecker.swift */; };
7675
67A9C90828427DEA005D6A36 /* SportsGroundFilterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67A9C90728427DEA005D6A36 /* SportsGroundFilterView.swift */; };
7776
67B371712A63FF6F000FF143 /* AppThemeScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67B371702A63FF6F000FF143 /* AppThemeScreen.swift */; };
7877
67B371732A640079000FF143 /* AppThemeService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67B371722A640079000FF143 /* AppThemeService.swift */; };
79-
67B65DAD289E860E00FBAFCB /* ErrorFilterService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67B65DAC289E860E00FBAFCB /* ErrorFilterService.swift */; };
8078
67B78712281D654C008B104F /* DefaultsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67B78711281D654C008B104F /* DefaultsService.swift */; };
8179
67B78714281D74F3008B104F /* EditAccountViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67B78713281D74F3008B104F /* EditAccountViewModel.swift */; };
8280
67B78716281D8006008B104F /* SportsGroundsMapViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67B78715281D8006008B104F /* SportsGroundsMapViewModel.swift */; };
@@ -145,7 +143,6 @@
145143
6758463E2965B7F2000BA5E0 /* ImageDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageDetailView.swift; sourceTree = "<group>"; };
146144
6758B929281D8FD7001D83D8 /* SportsGroundDetailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SportsGroundDetailViewModel.swift; sourceTree = "<group>"; };
147145
6758B92B281D9283001D83D8 /* EventFormViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventFormViewModel.swift; sourceTree = "<group>"; };
148-
6758B935281E5EA9001D83D8 /* APIService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIService.swift; sourceTree = "<group>"; };
149146
675A3707285480E600DAE071 /* Utils */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Utils; path = "SwiftUI-WorkoutApp/Utils"; sourceTree = "<group>"; };
150147
675E5617297D21D400B4981A /* Array+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+.swift"; sourceTree = "<group>"; };
151148
675EC64E2814126800C2E229 /* TextEntryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextEntryView.swift; sourceTree = "<group>"; };
@@ -164,6 +161,7 @@
164161
677311192965FFAA003CD13A /* PreviewContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewContent.swift; sourceTree = "<group>"; };
165162
67891E35283E945100B10802 /* SportsGroundFormViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SportsGroundFormViewModel.swift; sourceTree = "<group>"; };
166163
67891E37283E947B00B10802 /* SportsGroundFormView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SportsGroundFormView.swift; sourceTree = "<group>"; };
164+
678E3B1A2ACDEA9D00977EEC /* SWNetworkClient */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = SWNetworkClient; path = "SwiftUI-WorkoutApp/SWNetworkClient"; sourceTree = "<group>"; };
167165
6798AA3A280AEDC900DB76F1 /* WorkoutApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WorkoutApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
168166
6798AA3D280AEDC900DB76F1 /* SwiftUI_WorkoutAppApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUI_WorkoutAppApp.swift; sourceTree = "<group>"; };
169167
6798AA3F280AEDC900DB76F1 /* RootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootView.swift; sourceTree = "<group>"; };
@@ -185,11 +183,9 @@
185183
679F3B062969D4E200BB3590 /* IncognitoUserButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IncognitoUserButton.swift; sourceTree = "<group>"; };
186184
67A079F12A758E7D005EAF70 /* PickedPhotoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickedPhotoView.swift; sourceTree = "<group>"; };
187185
67A64A232AC83A0F00CBDD5F /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = "<group>"; };
188-
67A6FEF429E1DD0F002DCBA1 /* DeviceOSVersionChecker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceOSVersionChecker.swift; sourceTree = "<group>"; };
189186
67A9C90728427DEA005D6A36 /* SportsGroundFilterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SportsGroundFilterView.swift; sourceTree = "<group>"; };
190187
67B371702A63FF6F000FF143 /* AppThemeScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppThemeScreen.swift; sourceTree = "<group>"; };
191188
67B371722A640079000FF143 /* AppThemeService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppThemeService.swift; sourceTree = "<group>"; };
192-
67B65DAC289E860E00FBAFCB /* ErrorFilterService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorFilterService.swift; sourceTree = "<group>"; };
193189
67B78711281D654C008B104F /* DefaultsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultsService.swift; sourceTree = "<group>"; };
194190
67B78713281D74F3008B104F /* EditAccountViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditAccountViewModel.swift; sourceTree = "<group>"; };
195191
67B78715281D8006008B104F /* SportsGroundsMapViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SportsGroundsMapViewModel.swift; sourceTree = "<group>"; };
@@ -229,6 +225,7 @@
229225
isa = PBXFrameworksBuildPhase;
230226
buildActionMask = 2147483647;
231227
files = (
228+
678E3B1C2ACDEFFA00977EEC /* SWNetworkClient in Frameworks */,
232229
670431512964544D0090CAC3 /* FeedbackSender in Frameworks */,
233230
67FE5585297BF82000DC52BF /* ShortAddressService in Frameworks */,
234231
671CD13929A2904200645678 /* SWModels in Frameworks */,
@@ -462,6 +459,7 @@
462459
6798AA31280AEDC900DB76F1 = {
463460
isa = PBXGroup;
464461
children = (
462+
678E3B1A2ACDEA9D00977EEC /* SWNetworkClient */,
465463
6734D39229BC693D0000B5B1 /* DesignSystem */,
466464
671CD13729A28CB800645678 /* SWModels */,
467465
67FE5583297BF78500DC52BF /* ShortAddressService */,
@@ -538,11 +536,8 @@
538536
6798AA62280B1A5A00DB76F1 /* Services */ = {
539537
isa = PBXGroup;
540538
children = (
541-
6758B935281E5EA9001D83D8 /* APIService.swift */,
542539
67B78711281D654C008B104F /* DefaultsService.swift */,
543-
67B65DAC289E860E00FBAFCB /* ErrorFilterService.swift */,
544540
679F3B02296841DD00BB3590 /* URLOpener.swift */,
545-
67A6FEF429E1DD0F002DCBA1 /* DeviceOSVersionChecker.swift */,
546541
67B371722A640079000FF143 /* AppThemeService.swift */,
547542
);
548543
path = Services;
@@ -745,6 +740,7 @@
745740
67FE5584297BF82000DC52BF /* ShortAddressService */,
746741
671CD13829A2904200645678 /* SWModels */,
747742
6734D39329BC69580000B5B1 /* DesignSystem */,
743+
678E3B1B2ACDEFFA00977EEC /* SWNetworkClient */,
748744
);
749745
productName = "SwiftUI-WorkoutApp";
750746
productReference = 6798AA3A280AEDC900DB76F1 /* WorkoutApp.app */;
@@ -888,7 +884,6 @@
888884
6798AA40280AEDC900DB76F1 /* RootView.swift in Sources */,
889885
675EC64F2814126800C2E229 /* TextEntryView.swift in Sources */,
890886
674D0623282A9896007E75C6 /* SearchUsersView.swift in Sources */,
891-
67B65DAD289E860E00FBAFCB /* ErrorFilterService.swift in Sources */,
892887
6747575628113419002F0A24 /* ChangePasswordView.swift in Sources */,
893888
67515699283FEC3100501346 /* PickedImagesGrid.swift in Sources */,
894889
676B3AFA283507E900DB4ADA /* EventDetailsViewModel.swift in Sources */,
@@ -916,11 +911,9 @@
916911
67B78714281D74F3008B104F /* EditAccountViewModel.swift in Sources */,
917912
6762775B283A87AD009C203F /* JournalCell.swift in Sources */,
918913
6798AA84280C0F7D00DB76F1 /* EditAccountScreen.swift in Sources */,
919-
67A6FEF529E1DD0F002DCBA1 /* DeviceOSVersionChecker.swift in Sources */,
920914
6798AA73280B43FE00DB76F1 /* LoginView.swift in Sources */,
921915
6758463B2965B0F6000BA5E0 /* UIImage+Identifiable.swift in Sources */,
922916
67D9169628396C1E0098D3CB /* SendMessageView.swift in Sources */,
923-
6758B936281E5EA9001D83D8 /* APIService.swift in Sources */,
924917
6747575928128603002F0A24 /* SportsGroundDetailView.swift in Sources */,
925918
675EC6572815433600C2E229 /* UsersListView.swift in Sources */,
926919
675EC65F2815532800C2E229 /* EventFormView.swift in Sources */,
@@ -1165,7 +1158,7 @@
11651158
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
11661159
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
11671160
CODE_SIGN_STYLE = Automatic;
1168-
CURRENT_PROJECT_VERSION = 1;
1161+
CURRENT_PROJECT_VERSION = 2;
11691162
DEVELOPMENT_ASSET_PATHS = "SwiftUI-WorkoutApp/Preview\\ Content/PreviewContent.swift SwiftUI-WorkoutApp/Preview\\ Content";
11701163
DEVELOPMENT_TEAM = CR68PP2Z3F;
11711164
ENABLE_PREVIEWS = YES;
@@ -1201,7 +1194,7 @@
12011194
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
12021195
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
12031196
CODE_SIGN_STYLE = Automatic;
1204-
CURRENT_PROJECT_VERSION = 1;
1197+
CURRENT_PROJECT_VERSION = 2;
12051198
DEVELOPMENT_ASSET_PATHS = "SwiftUI-WorkoutApp/Preview\\ Content/PreviewContent.swift SwiftUI-WorkoutApp/Preview\\ Content";
12061199
DEVELOPMENT_TEAM = CR68PP2Z3F;
12071200
ENABLE_PREVIEWS = YES;
@@ -1317,6 +1310,10 @@
13171310
isa = XCSwiftPackageProductDependency;
13181311
productName = Utils;
13191312
};
1313+
678E3B1B2ACDEFFA00977EEC /* SWNetworkClient */ = {
1314+
isa = XCSwiftPackageProductDependency;
1315+
productName = SWNetworkClient;
1316+
};
13201317
67CB32D0297BE0F8009380DF /* NetworkStatus */ = {
13211318
isa = XCSwiftPackageProductDependency;
13221319
package = 67CB32CF297BE0F8009380DF /* XCRemoteSwiftPackageReference "NetworkStatus" */;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import Foundation
2+
3+
public enum AppColorTheme: String, CaseIterable, Identifiable {
4+
public var id: String { rawValue }
5+
case dark = "Темная тема"
6+
case light = "Светлая тема"
7+
case system = "Как в системе"
8+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import Foundation
2+
3+
@MainActor
4+
public protocol DefaultsProtocol: AnyObject {
5+
var appLanguage: AppLanguage { get }
6+
var appTheme: AppColorTheme { get }
7+
var mainUserInfo: UserResponse? { get }
8+
var mainUserCountryID: Int { get }
9+
var mainUserCityID: Int { get }
10+
var needUpdateUser: Bool { get }
11+
var isAuthorized: Bool { get }
12+
var friendRequestsList: [UserResponse] { get }
13+
var friendsIdsList: [Int] { get }
14+
var blacklistedUsers: [UserResponse] { get }
15+
var unreadMessagesCount: Int { get }
16+
func setAppLanguage(_ language: String)
17+
func setAppTheme(_ theme: AppColorTheme)
18+
func saveAuthData(_ info: AuthData) throws
19+
func basicAuthInfo() throws -> AuthData
20+
func setUserNeedUpdate(_ newValue: Bool)
21+
func saveUserInfo(_ info: UserResponse) throws
22+
func saveFriendsIds(_ ids: [Int]) throws
23+
func saveFriendRequests(_ array: [UserResponse]) throws
24+
func saveUnreadMessagesCount(_ count: Int)
25+
func saveBlacklist(_ array: [UserResponse]) throws
26+
func setHasJournals(_ hasJournals: Bool)
27+
func setHasSportsGrounds(_ isAddedGround: Bool)
28+
func triggerLogout()
29+
}

SwiftUI-WorkoutApp/Services/DeviceOSVersionChecker.swift renamed to SwiftUI-WorkoutApp/SWModels/Sources/SWModels/DeviceOSVersionChecker.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ import Foundation
66
deprecated: 16,
77
message: "refreshable работает в ScrollView на iOS 16, можно убрать неактуальную кнопку обновления"
88
)
9-
enum DeviceOSVersionChecker {
9+
public enum DeviceOSVersionChecker {
1010
/// Установлена ли iOS 16 на девайсе
1111
///
1212
/// До iOS 16 `ScrollView` не поддерживает `refreshable`
13-
static var iOS16Available: Bool {
13+
public static var iOS16Available: Bool {
1414
if #available(iOS 16, *) {
1515
true
1616
} else {
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.DS_Store
2+
/.build
3+
/Packages
4+
xcuserdata/
5+
DerivedData/
6+
.swiftpm/configuration/registries.json
7+
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
8+
.netrc
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// swift-tools-version: 5.9
2+
// The swift-tools-version declares the minimum version of Swift required to build this package.
3+
4+
import PackageDescription
5+
6+
let package = Package(
7+
name: "SWNetworkClient",
8+
platforms: [.iOS(.v15)],
9+
products: [
10+
.library(
11+
name: "SWNetworkClient",
12+
targets: ["SWNetworkClient"]
13+
),
14+
],
15+
dependencies: [
16+
.package(path: "../SWModels")
17+
],
18+
targets: [
19+
.target(
20+
name: "SWNetworkClient",
21+
dependencies: ["SWModels"]
22+
)
23+
]
24+
)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# SWNetworkClient
2+
3+
Набор инструментов для общения с сервером `https://workout.su/api/v3`
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import Foundation
2+
import SWModels
3+
4+
extension SWClient {
5+
enum APIError: Error, LocalizedError {
6+
case noData
7+
case noResponse
8+
case badRequest
9+
case invalidCredentials
10+
case notFound
11+
case payloadTooLarge
12+
case serverError
13+
case invalidUserID
14+
case customError(String)
15+
16+
init(_ error: ErrorResponse) {
17+
if let message = error.message, error.realCode != 401 {
18+
self = .customError(message)
19+
} else if let array = error.errors {
20+
let message = array.joined(separator: ",\n")
21+
self = .customError(message)
22+
} else {
23+
self.init(with: error.realCode)
24+
}
25+
}
26+
27+
init(with code: Int?) {
28+
switch code {
29+
case 400: self = .badRequest
30+
case 401: self = .invalidCredentials
31+
case 404: self = .notFound
32+
case 413: self = .payloadTooLarge
33+
case 500: self = .serverError
34+
default: self = .noResponse
35+
}
36+
}
37+
38+
var errorDescription: String? {
39+
switch self {
40+
case .noData:
41+
"Сервер не прислал данные для обработки ответа"
42+
case .noResponse:
43+
"Сервер не отвечает"
44+
case .badRequest:
45+
"Запрос содержит ошибку"
46+
case .invalidCredentials:
47+
"Некорректное имя пользователя или пароль"
48+
case .notFound:
49+
"Запрашиваемый ресурс не найден"
50+
case .payloadTooLarge:
51+
"Объем данных для загрузки на сервер превышает лимит"
52+
case .serverError:
53+
"Внутренняя ошибка сервера"
54+
case .invalidUserID:
55+
"Некорректный идентификатор пользователя"
56+
case let .customError(error):
57+
error
58+
}
59+
}
60+
}
61+
}

0 commit comments

Comments
 (0)