Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swift 6.0 support #125

Merged
merged 13 commits into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .github/workflows/swift.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ env:
jobs:
BuildAndTests:
name: Build & Tests
runs-on: macOS-13
runs-on: macOS-14
env:
DEVELOPER_DIR: /Applications/Xcode_15.2.app/Contents/Developer
DEVELOPER_DIR: /Applications/Xcode_16.app/Contents/Developer
XCODE_PROJECT: Nivelir.xcodeproj
IOS_SCHEME: Nivelir iOS
IOS_DESTINATION: OS=17.2,name=iPhone 15
IOS_DESTINATION: OS=18.0,name=iPhone 16
IOS_RESULT_PATH: xcodebuild-ios.xcresult
TVOS_SCHEME: Nivelir tvOS
TVOS_DESTINATION: OS=17.2,name=Apple TV
TVOS_DESTINATION: OS=18.0,name=Apple TV
TVOS_RESULT_PATH: xcodebuild-tvos.xcresult
SKIP_SWIFTLINT: YES
SWIFTLINT_VERSION: 0.52.2
Expand Down Expand Up @@ -52,7 +52,7 @@ jobs:

Cocoapods:
name: Cocoapods
runs-on: macOS-13
runs-on: macOS-14
steps:
- uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1
Expand All @@ -61,13 +61,13 @@ jobs:
gem install bundler
bundle install --without=documentation
- name: Switch Xcode version
run: sudo xcode-select --switch /Applications/Xcode_15.2.app
run: sudo xcode-select --switch /Applications/Xcode_16.app
- name: Linting
run: bundle exec pod lib lint --skip-tests --allow-warnings

SPM:
name: Swift Package Manager
runs-on: macOS-13
runs-on: macOS-14
steps:
- uses: actions/checkout@v3
- name: Build
Expand Down
2 changes: 1 addition & 1 deletion .swift-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5.7
6.0
2 changes: 1 addition & 1 deletion .xcode-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
15.2
16.0
10 changes: 6 additions & 4 deletions Example/NivelirExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1061,7 +1061,7 @@
);
PRODUCT_BUNDLE_IDENTIFIER = "ru.hh.Nivelir-Example";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.7;
SWIFT_VERSION = 6.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
Expand All @@ -1080,7 +1080,7 @@
);
PRODUCT_BUNDLE_IDENTIFIER = "ru.hh.Nivelir-Example";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.7;
SWIFT_VERSION = 6.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
Expand All @@ -1092,6 +1092,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = "Brand Assets";
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = NivelirExample/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
Expand All @@ -1100,7 +1101,7 @@
PRODUCT_BUNDLE_IDENTIFIER = "ru.hh.Nivelir-Example";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = appletvos;
SWIFT_VERSION = 5.7;
SWIFT_VERSION = 6.0;
TARGETED_DEVICE_FAMILY = 3;
};
name = Debug;
Expand All @@ -1112,6 +1113,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = "Brand Assets";
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = NivelirExample/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
Expand All @@ -1120,7 +1122,7 @@
PRODUCT_BUNDLE_IDENTIFIER = "ru.hh.Nivelir-Example";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = appletvos;
SWIFT_VERSION = 5.7;
SWIFT_VERSION = 6.0;
TARGETED_DEVICE_FAMILY = 3;
};
name = Release;
Expand Down
1 change: 1 addition & 0 deletions Example/NivelirExample/Dependencies/Screens.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Foundation
import Nivelir

@MainActor
struct Screens {

let services: Services
Expand Down
3 changes: 3 additions & 0 deletions Example/NivelirExample/Dependencies/Services.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ struct Services {

let window: UIWindow

@MainActor
func screenNavigator() -> ScreenNavigator {
container.shared {
ScreenNavigator(window: window)
}
}

@MainActor
func deeplinkManager() -> DeeplinkManager {
container.shared {
DeeplinkManager(
Expand All @@ -30,6 +32,7 @@ struct Services {
}
}

@MainActor
func profileService() -> ProfileService {
DefaultProfileService(authorizationService: authorizationService())
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Foundation
import Nivelir

@MainActor
protocol ScreenAuthorizeActionScreens {

func showAuthorizationRoute() -> ScreenWindowRoute
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ struct ChatDeeplink {
let roomID: Int
let chatID: Int

@MainActor
func navigate(
screens: Screens,
navigator: ScreenNavigator,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import UIKit
import Nivelir

@MainActor
extension Alert {

static let somethingWentWrong = Self(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ extension SharingActivityType {

extension SharingActivity {

@MainActor
static var openInBrowser: Self {
.custom(SharingOpenInBrowserActivity())
}
Expand Down
4 changes: 2 additions & 2 deletions Example/NivelirExample/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
private var services: Services?
private var screens: Screens?

private func setupNotifications() {
private nonisolated func setupNotifications() {
#if os(iOS)
let notificationCenter = UNUserNotificationCenter.current()

Expand Down Expand Up @@ -148,7 +148,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
}

#if os(iOS)
extension SceneDelegate: UNUserNotificationCenterDelegate {
extension SceneDelegate: @preconcurrency UNUserNotificationCenterDelegate {

func userNotificationCenter(
_ center: UNUserNotificationCenter,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Foundation
import Nivelir

@MainActor
public protocol AuthorizationObserver: ScreenObserver {

func authorizationFinished(isAuthorized: Bool)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ final class AuthorizationViewController: UIViewController, ScreenKeyedContainer

switch result {
case .success:
self.screenNavigator.navigate(
from: self.presenting,
screenNavigator.navigate(
from: presenting,
to: { route in
route
.showHUD(.success, duration: 1.0)
Expand All @@ -73,7 +73,7 @@ final class AuthorizationViewController: UIViewController, ScreenKeyedContainer
)

case .failure:
self.screenNavigator.navigate { route in
screenNavigator.navigate { route in
route.showHUD(.failure, duration: 1.0)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import Foundation

protocol AuthorizationService {
protocol AuthorizationService: Sendable {

var isAuthorized: Bool { get }

@MainActor
func login(
phoneNumber: String,
completion: @escaping (_ result: Result<Void, Error>) -> Void
Expand Down
77 changes: 35 additions & 42 deletions Example/NivelirExample/Services/Profile/DefaultProfileService.swift
Original file line number Diff line number Diff line change
@@ -1,69 +1,62 @@
import UIKit

final class DefaultProfileService: ProfileService {
final class DefaultProfileService: ProfileService, Sendable {

private class UncheckedCGFloat: @unchecked Sendable {
var value: CGFloat = .zero
}

private let authorizationService: AuthorizationService
private let intervalCount = UncheckedCGFloat()

init(authorizationService: AuthorizationService) {
self.authorizationService = authorizationService
}

private func finishSucceedUploading(
timer: Timer,
progress: @escaping (_ ratio: CGFloat) -> Void,
completion: @escaping (_ result: Result<Void, Error>) -> Void
) {
timer.invalidate()
progress(1.0)

DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
completion(.success(Void()))
}
}

private func finishFailedUploading(
timer: Timer,
completion: @escaping (_ result: Result<Void, Error>) -> Void
) {
timer.invalidate()

DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
completion(.failure(ProfileError.unavailable))
}
}

func uploadPhoto(
image: UIImage,
progress: @escaping (_ ratio: CGFloat) -> Void,
completion: @escaping (_ result: Result<Void, Error>) -> Void
progress: @MainActor @Sendable @escaping (_ ratio: CGFloat) -> Void,
completion: @MainActor @Sendable @escaping (_ result: Result<Void, Error>) -> Void
) {
intervalCount.value = .zero
guard authorizationService.isAuthorized else {
return completion(.failure(ProfileError.unauthorized))
}

var intervalCount: CGFloat = .zero
Timer.scheduledTimer(withTimeInterval: 0.05, repeats: true) { [weak self] timer in
guard let self else {
return
}

guard intervalCount.value <= 100 else {
timer.invalidate()

Task { @MainActor in
progress(1.0)
}

Timer.scheduledTimer(withTimeInterval: 0.05, repeats: true) { timer in
guard intervalCount <= 100 else {
return self.finishSucceedUploading(
timer: timer,
progress: progress,
completion: completion
)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
completion(.success(Void()))
}
return
}

let random = Int.random(in: 1...1000)

guard random < 997 || intervalCount < 50 else {
return self.finishFailedUploading(
timer: timer,
completion: completion
)
guard random < 997 || intervalCount.value < 50 else {
timer.invalidate()

DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
completion(.failure(ProfileError.unavailable))
}
return
}

progress(intervalCount * 0.01)
Task { @MainActor in
progress(self.intervalCount.value * 0.01)
}

intervalCount += 1.0
intervalCount.value += 1.0
}
}
}
5 changes: 3 additions & 2 deletions Example/NivelirExample/Services/Profile/ProfileService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import UIKit

protocol ProfileService {

@MainActor
func uploadPhoto(
image: UIImage,
progress: @escaping (_ ratio: CGFloat) -> Void,
completion: @escaping (_ result: Result<Void, Error>) -> Void
progress: @MainActor @Sendable @escaping (_ ratio: CGFloat) -> Void,
completion: @MainActor @Sendable @escaping (_ result: Result<Void, Error>) -> Void
)
}
4 changes: 2 additions & 2 deletions Example/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ EXTERNAL SOURCES:
:path: ".."

SPEC CHECKSUMS:
Nivelir: b98cb72be40810c56abaf245adc195914ac1ea2d
Nivelir: a4b1ba7ecebed46bd55d543adc2de9efed695207
SnapKit: e01d52ebb8ddbc333eefe2132acf85c8227d9c25

PODFILE CHECKSUM: da8b281ef18accce1d0505caaeb1d708354daf4e

COCOAPODS: 1.12.1
COCOAPODS: 1.15.2
Loading
Loading