Skip to content

Instantly share code, notes, and snippets.

View mattmassicotte's full-sized avatar

Matt Massicotte mattmassicotte

View GitHub Profile
@Wouter01
Wouter01 / EnvironmentObservable.swift
Created August 16, 2023 21:05
SwiftUI EnvironmentObservable
import SwiftUI
import Observation
@propertyWrapper
struct EnvironmentObservable<Value: AnyObject & Observable>: DynamicProperty {
@Environment var wrappedValue: Value
public init(_ objectType: Value.Type) {
_wrappedValue = .init(objectType)
@nicklockwood
nicklockwood / OSKit.swift
Created January 28, 2023 11:32
A lightweight approach to writing cross-platform code in SwiftUI without a lot of conditional compilation blocks
import SwiftUI
enum OSDocumentError: Error {
case unknownFileFormat
}
#if canImport(UIKit)
import UIKit
@roostr
roostr / Watchdog.swift
Last active March 19, 2024 14:40
A watchdog timer for iOS to detect when the main run loop is stalled
//
// Watchdog.swift
//
// The MIT License (MIT)
// Copyright © 2023 Front Pocket Software LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
// documentation files (the “Software”), to deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to the following conditions:
@mattmassicotte
mattmassicotte / AsyncMap.swift
Created June 18, 2022 11:00
Swift asyncMap function
extension Sequence {
func asyncMap<T>(_ transform: @escaping (Element) async -> T) async -> [T] {
return await withTaskGroup(of: T.self) { group in
var transformedElements = [T]()
for element in self {
group.addTask {
return await transform(element)
}
}
@byte-sourcerer
byte-sourcerer / MacEditorTextView.swift
Created October 31, 2021 10:46
An NSTextView wrapped by SwiftUI with TextKit 2
/**
* MacEditorTextView
* Copyright (c) Thiago Holanda 2020-2021
* https://twitter.com/tholanda
*
* MIT license
* Modified by https://github.com/cjwcommuny for TextKit 2
*/
import Combine
@sharplet
sharplet / AnyEventPublisher.swift
Last active February 17, 2024 02:18
PublisherQueue — Serialise the execution of multiple publishers like OperationQueue
import Combine
public enum AnyError: Error {
case never(Never)
case failure(Error)
}
public enum AnyEvent {
case output(Any)
case completion(Subscribers.Completion<AnyError>)
@fabianfett
fabianfett / Change Xcode version in GitHub Actions
Created August 21, 2019 09:37
How to change the Xcode version in GitHub Actions
# Change Xcode version in GitHub Actions
As of today (2019-08-21) I haven't found any documentation on changing Xcode versions when
using GitHub actions. So I checked the applications folder and everything we need is
already there. 🤩
```
> ls -n /Applications/ | grep Xcode*
lrwxr-xr-x 1 0 80 30 Aug 2 19:31 Xcode.app -> /Applications/Xcode_10.2.1.app
drwxr-xr-x 3 501 20 96 Oct 20 2018 Xcode_10.1.app
import Foundation
import CommonCrypto
extension Data {
enum Algorithm {
case md5
case sha1
case sha224
case sha256
case sha384
@drewmccormack
drewmccormack / verifyPaddleSignature.swift
Last active March 13, 2021 20:27
How to verify the Paddle webhook signature in Swift 3 using the Vapor packages CTLS and Crypto (include OpenSSL)
/// Verify the signature passed with the Paddle request parameters.
/// Details here: https://paddle.com/docs/reference-verifying-webhooks
func verifyPaddleSignature(inParameters parameters: [String:String]) throws -> Bool {
guard let signatureString = parameters[PaddleParameter.signature.rawValue],
let signature = Data(base64Encoded: signatureString) else {
return false
}
// Need to gather sorted parameters
var signatureParameters = parameters
@mminer
mminer / MyService.swift
Last active April 23, 2024 23:00
Components of XPC service.
import Foundation
class MyService: NSObject, MyServiceProtocol {
func upperCaseString(_ string: String, withReply reply: @escaping (String) -> Void) {
let response = string.uppercased()
reply(response)
}
}