Skip to content

Instantly share code, notes, and snippets.

var valuesA: [Float] = [2, 0.5, 9, 1, 18]
let rowsA = Int32(valuesA.count)
let columnsA = Int32(valuesA.count)
var rowIndicesA = Array(0 ..< rowsA)
var columnStarts = Array(0 ... valuesA.count)
var valuesB: [Float] = [3, 5, 8, 7, 2,
1, 4, 9, 1, 3,
2, 7, 3, 1, 2,
5, 4, 9, 1, 6,
func fetchData<M: Decodable>(target: T, responseClass: M.Type = M.self, completion: @escaping(Result<M, Error>) -> Void) {
let method = Alamofire.HTTPMethod(rawValue: target.methods.rawValue)
let headers = Alamofire.HTTPHeaders(target.headers ?? [:])
let params = buildParams(task: target.task)
AF.request(target.baseUrl + target.path, method: method, parameters: params.0, encoding: params.1, headers: headers)
.validate()
.responseDecodable(of: M.self) { response in
switch response.result {
case .success(let value): completion(.success(value))
case .failure(let error): completion(.failure(error))
import UIKit
class ShadowedSwitch: UISwitch {
override init(frame: CGRect) {
super.init(frame: frame)
configure()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
actor Foo {
private var firstTask: Task<Void, Error>?
func performFirstTask() async throws {
// create unstructured concurrency
let task = Task {
try await … // the work associated with first task
}
private func stream() -> AsyncThrowingStream<SomeData, Error> {
AsyncThrowingStream<SomeData, Error> { continuation in
let streamTask = Task {
do {
while !Task.isCancelled {
guard let message = try await self.task?.receive() else {
throw APIError.genericError
}
Self.logger.trace("\(SocketStrings.streamMessageYielded())")
extension ImageDownloader {
// if you don't care about the order
func downloadInRandomOrder() async -> [Image] {
await withTaskGroup(of: Image.self) { group in
let items = await fetchList()
for item in items {
group.addTask { await self.fetch(imageName: item.imageName) }
}
func foo() async {
await first()
if await second() {
// there several ways to run 3 and 4 in parallel; `async let`, shown here, is good pattern for fixed number of tasks; `TaskGroup` is good for variable number of tasks; both patterns keep you within realm of structured concurrency
async let thirdTask: () = third()
async let fourthTask: () = fourth()
await thirdTask
await fourthTask
} else {
// if 5 & 6 must run sequentially, then await 5 and then await 6
@robertmryan
robertmryan / CollateTasks.swift
Created January 28, 2024 16:02
Two common patterns for performing series of tasks in parallel, but collating the results into either an array or dictionary
extension Sequence where Element: Hashable & Sendable {
func dictionary<T: Sendable>(block: @escaping @Sendable (Element) async -> T) async -> [Element: T] {
await withTaskGroup(of: (Element, T).self) { group in
for id in self {
group.addTask { (id, await block(id)) }
}
return await group.reduce(into: [:]) { $0[$1.0] = $1.1 }
}
}
import SwiftUI
import AsyncAlgorithms
import os.log
private let poi = OSSignposter(subsystem: "MyApp", category: .pointsOfInterest)
typealias AsyncClosure = () async -> Void
struct ExperimentView: View {
@StateObject var viewModel = ExperimentViewModel()
func addSublayers(to view: UIView) {
let radius: CGFloat = 150
let borderWidth: CGFloat = 10
let circleCenterOffset: CGFloat = 120
let startCenter = CGPoint(x: 200, y: 200)
for i in 0..<3 {
let shapeLayer = createShapeLayer()
shapeLayer.path = circleDifference(
center: point(startCenter, xOffset: CGFloat(i) * circleCenterOffset),