Skip to content

Instantly share code, notes, and snippets.

@robertmryan
robertmryan / URLSession+AsyncAwaitCompatibility.swift
Created December 31, 2023 23:06
An async-await interface for URLSession with support for iOS 13 and later; unnecessary if minimum target is iOS 15 or later
//
// URLSession+AsyncAwaitCompatibility.swift
//
// Copyright © Robert M. Ryan. All Rights Reserved.
import Foundation
import os.log
private let log = OSLog(category: "URLSession+AsyncAwaitCompatibility")
class ViewController: UIViewController {
private var task: Task<Void, Never>?
override func viewDidLoad() {
super.viewDidLoad()
let task = Task {
do {
try await self.test()
} catch is CancellationError { // this is another way to check for `CancellationError`
// at the very least, something like:
enum ApiError: Error {
case httpError(URLResponse, Data)
}
func getRandomFood() async throws -> Food {
guard let url = URL(string: "https://random-data-api.com/api/food/random_food") else { fatalError("Missing URL") }
let urlRequest = URLRequest(url: url)
let (data, response) = try await URLSession.shared.data(for: urlRequest)
actor SerialTasksIgnoresAnyError<Success: Sendable> {
private var previousTask: Task<Success, Error>?
private let priority: TaskPriority?
init(priority: TaskPriority? = nil) {
self.priority = priority
}
func add(block: @Sendable @escaping () async throws -> Success) async throws -> Success {
let task = Task(priority: priority) { [previousTask] in
// ideally; it’s not `markBookAsOpen`’s job to bridge to Swift concurrency, but rather the caller‘s
func markBookAsOpen() async {
await self.worker.logOpened(id: self.bookId)
}
// worst case scenario; if you really must launch unstructured concurrency, give this an optional completion handler
func markBookAsOpen(completion: (() -> Void)? = nil) {
Task {
enum ContentType: Codable {
case phone
case email
case unknown(String)
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let string = try container.decode(String.self)
switch string {
case Self.phone.key: self = .phone
@robertmryan
robertmryan / LocationsManager.swift
Last active December 25, 2022 16:38
AsyncSequence/AsyncStream for CLLocationManager
//
// LocationsManager.swift
// MyApp
//
// Created by Robert Ryan on 12/24/22.
//
import Foundation
import CoreLocation
class ViewController: UIViewController {
@IBOutlet var label: UILabel!
private weak var timer: Timer?
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
startTimer()
}
func benchmark() {
let string = String(repeating: "This is it. ", count: 10000)
let i1 = 19000
let i2 = 19020
// time computation
func tc(computation: (Int, Int) -> Void) {
let startTime = DispatchTime.now()
for i in 0..<100 {
computation(i1 + i, i2 + i)
func search() async throws -> BusinessSearchResult {
var components = URLComponents(string: "https://api.yelp.com/v3/businesses/search")
components?.queryItems = [
URLQueryItem(name: "term", value: "theater"),
URLQueryItem(name: "location", value: "NYC")
]
guard let url = components?.url else { throw URLError(.badURL) }