Skip to content

Instantly share code, notes, and snippets.

func onMainDo<T>(_ firstMainBlock: @escaping () -> Void, onBackgroundDo backgroundBlock: @escaping () -> T, thenOnMainDo mainBlock: @escaping (T) -> Void) {
DispatchQueue.main.async {
firstMainBlock()
DispatchQueue.global(qos: .background).async {
let result = backgroundBlock()
DispatchQueue.main.async {
mainBlock(result)
}
}
}
func startApp() {
onMainDo({
self.activityIndicator.startAnimating()
}, onBackgroundDo: {
let storage = PersistentSecureStorage.shared()
guard let savedToken == storage.token {
return .goToAuth
}
let tokenIsValid = authService.isValidToken(savedToken)
if !tokenIsValid {
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let vc = StarsViewTestVC()
window!.rootViewController = vc
return true
}
extension URLSession {
func sendSynchronousRequest(request: URLRequest) -> (Data?, URLResponse?, Error?) {
let semaphore = DispatchSemaphore(value: 0)
var result: (data: Data?, response: URLResponse?, error: Error?)
let task = self.dataTask(with: request) {
result = (data: $0, response: $1, error: $2)
semaphore.signal()
}
task.resume()
let service = SyncronousThingsService()
onMainDo({
self.activityIndicator.startAnimating()
}, onBackgroundDo: {
return service.getThings()
}, thenOnMainDo: {
self.activityIndicator.stopAnimating()
self.updateUI(with: $0)
})
protocol ThingsService {
func getThings(onCompletion callback: (Result<[Thing]>) -> Void)
func add(onCompletion callback: (Result<Bool>) -> Void)
}
class FakeThingsService: ThingsService {
private(set) var things: [Thing]
init(things: [Thing]) {
self.things = things
class ServicesTest: XCTestCase {
let service = ProfileService()
setup() {
// handle authentication if needed
// let authService = ...
// let authMethod = ...
// authService.auth(authMethod)
}
protocol ThingsService {
func getThings() -> Result<[Thing]>
func add(thing: Thing) -> Result<Bool>
}
class FakeThingsService: ThingsService {
private(set) var things: [Thing]
init(things: [Thing]) {
self.things = things
}
class ThingsService {
func getThings() -> Result<[Thing]> {
do {
let response = try sendHttpRequestSynchronously(url)
let data = try getData(from: response)
let things = try doParsing(data)
return .success(things)
} catch error {
return .failure(error)
}
class ThingsService {
func getThings(onCompletion callback: @escaping (Result<[Thing]>) -> Void) {
sendHttpRequestAsynchronously(url) { response in
DispatchQueue.main.async {
do {
let data = try getData(from: response)
let things = try doParsing(data)
callback(.success(things)))
} catch error {
callback(.failure(error))