[AltStoreCore] Adds NSManagedObjectContext.performAsync() to wrap iOS 15+ async perform()

Allows us to use Swift Concurrency with Core Data pre-iOS 15.
This commit is contained in:
Riley Testut
2023-04-04 14:06:13 -05:00
committed by Magesh K
parent 779887e582
commit fc99fb32a4
2 changed files with 64 additions and 0 deletions

View File

@@ -374,6 +374,7 @@
D5E1E7C128077DE90016FC96 /* FetchTrustedSourcesOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5E1E7C028077DE90016FC96 /* FetchTrustedSourcesOperation.swift */; };
D5E3FB9828FDFAD90034B72C /* NSError+AltStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF6C336124197D700034FD24 /* NSError+AltStore.swift */; };
D5F2F6A92720B7C20081CCF5 /* PatchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5F2F6A82720B7C20081CCF5 /* PatchViewController.swift */; };
D5F48B4829CCF21B002B52A4 /* AltStore+Async.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5F48B4729CCF21B002B52A4 /* AltStore+Async.swift */; };
D5F5AF2E28FDD2EC00C938F5 /* TestErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5F5AF2D28FDD2EC00C938F5 /* TestErrors.swift */; };
D5F5AF7D28ECEA990067C736 /* ErrorDetailsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5F5AF7C28ECEA990067C736 /* ErrorDetailsViewController.swift */; };
D5F99A1828D11DB500476A16 /* AltStore10ToAltStore11.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = D5F99A1728D11DB500476A16 /* AltStore10ToAltStore11.xcmappingmodel */; };
@@ -916,6 +917,7 @@
D5DB145828F9DC1000A8F606 /* ALTLocalizedError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ALTLocalizedError.swift; sourceTree = "<group>"; };
D5E1E7C028077DE90016FC96 /* FetchTrustedSourcesOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FetchTrustedSourcesOperation.swift; sourceTree = "<group>"; };
D5F2F6A82720B7C20081CCF5 /* PatchViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PatchViewController.swift; sourceTree = "<group>"; };
D5F48B4729CCF21B002B52A4 /* AltStore+Async.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AltStore+Async.swift"; sourceTree = "<group>"; };
D5F5AF2D28FDD2EC00C938F5 /* TestErrors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestErrors.swift; sourceTree = "<group>"; };
D5F5AF7C28ECEA990067C736 /* ErrorDetailsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorDetailsViewController.swift; sourceTree = "<group>"; };
D5F99A1728D11DB500476A16 /* AltStore10ToAltStore11.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = AltStore10ToAltStore11.xcmappingmodel; sourceTree = "<group>"; };
@@ -2589,6 +2591,7 @@
D5F99A1828D11DB500476A16 /* AltStore10ToAltStore11.xcmappingmodel in Sources */,
BF66EEE92501AED0007EE018 /* JSONDecoder+Properties.swift in Sources */,
BF66EEEB2501AED0007EE018 /* UIApplication+AppExtension.swift in Sources */,
D5F48B4829CCF21B002B52A4 /* AltStore+Async.swift in Sources */,
BF66EED92501AECA007EE018 /* Team.swift in Sources */,
BF66EED12501AECA007EE018 /* AltStore3ToAltStore4.xcmappingmodel in Sources */,
BFAECC5C2501B0A400528F27 /* CFNotificationName+AltStore.m in Sources */,

View File

@@ -0,0 +1,61 @@
//
// AltStore+Async.swift
// AltStoreCore
//
// Created by Riley Testut on 3/23/23.
// Copyright © 2023 Riley Testut. All rights reserved.
//
import UIKit
import CoreData
public extension NSManagedObjectContext
{
// Non-Throwing
func performAsync<T>(_ closure: @escaping () -> T) async -> T
{
let result: T
if #available(iOS 15, *)
{
result = await self.perform(schedule: .immediate) {
closure()
}
}
else
{
result = await withCheckedContinuation { (continuation: CheckedContinuation<T, Never>) in
self.perform {
let result = closure()
continuation.resume(returning: result)
}
}
}
return result
}
// Throwing
func performAsync<T>(_ closure: @escaping () throws -> T) async throws -> T
{
let result: T
if #available(iOS 15, *)
{
result = try await self.perform(schedule: .immediate) {
try closure()
}
}
else
{
result = try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<T, Error>) in
self.perform {
let result = Result { try closure() }
continuation.resume(with: result)
}
}
}
return result
}
}