Skip to content

Instantly share code, notes, and snippets.

View ralfebert's full-sized avatar

Ralf Ebert ralfebert

View GitHub Profile
@ralfebert
ralfebert / WidthReaderView.swift
Last active December 2, 2023 08:59
WidthReaderView: Read the width using a GeometryReader background, pass it out using a PreferenceKey, to be able to compute the height of a view based on the available width
import SwiftUI
struct SizePreferenceKey: PreferenceKey {
static let defaultValue: CGSize = .zero
static func reduce(value: inout CGSize, nextValue: () -> CGSize) {
value = nextValue()
}
}
@ralfebert
ralfebert / DocumentStore.swift
Created April 3, 2022 09:57
DocumentStore stores a Codable document in the documents directory of the app.
import Foundation
import os
/**
DocumentStore stores a Codable document in the documents directory of the app.
- Loading and saving happens on the thread you call it on, typically the main thread.
- This should be only used for small documents (recommendation: smaller than 1KB). For larger documents, or if you want features like schema migration, Core Data (or some other database framework for apps like Realm) will be a better fit.
- This is a starting point and not to be used for critical app data: If the document cannot be loaded (f.e. because of an incompatible change of the Document type), the Document will silently be nil and be overwritten on the next save. If the document cannot be saved, it will crash.
*/
import MultipeerConnectivity
import os
import SwiftUI
class ColorModel: NSObject, ObservableObject {
private let serviceType = "example-color"
private let session: MCSession
private let myPeerId = MCPeerID(displayName: UIDevice.current.name)
private let serviceAdvertiser: MCNearbyServiceAdvertiser
@ralfebert
ralfebert / DetectShakeSwiftUI.swift
Created March 1, 2022 19:04
Detect a Shake gesture in SwiftUI
import SwiftUI
/// Detect a Shake gesture in SwiftUI
/// Based on https://stackoverflow.com/a/60085784/128083
struct ShakableViewRepresentable: UIViewControllerRepresentable {
let onShake: () -> ()
class ShakeableViewController: UIViewController {
var onShake: (() -> ())?
func countriesExampleData() -> [Country] {
[
Country(
id: "at",
name: "Austria",
capital: "Vienna",
population: 8_935_112,
drivingSide: .right
),
Country(
actor SyncActor {
var syncRequests = 0
private func sync() async {
// Make sure only one sync is in progress at the same time
// (because of actor re-entrancy another sync could be started while we await for the persistence/network operations)
self.syncRequests += 1
if self.syncRequests > 1 {
// Sync already in progress

FB9624610: Formatting Swift code using an external tool like swiftformat on Save

I am using the splendid command-line tool swiftformat (https://github.com/nicklockwood/SwiftFormat) to format my Swift code.

For my, the perfect integration point for this tool would be on Save in Xcode. In that way the formatting would not interrupt my editing, but I can see/check the changes done by the formatter, but never forget to format a file after editing.

I'd like to suggest a configuration option for Xcode that allows to configure it in such a way that, when I press save (cmd S) it saves the file and then runs a command line utility and reloads the file - or a capability for an Xcode source code editor extension to do such an operation.

One alternative could be to do it at build time which is possible to configure currently using a Build phase (https://github.com/nicklockwood/SwiftFormat#xcode-build-phase), but unfortunately, with this setup one loses all the undo history in Xcode.

import MapKit
extension CLLocationCoordinate2D {
/// Returns the distance between two coordinates in meters.
func distance(to: CLLocationCoordinate2D) -> CLLocationDistance {
MKMapPoint(self).distance(to: MKMapPoint(to))
}
}
@ralfebert
ralfebert / CurrentLocation.swift
Last active April 3, 2022 09:57
CurrentLocation provides the current GPS location via CLLocationManager as ObservableObject
import CoreLocation
import os
/// CurrentLocation provides the current GPS location via CLLocationManager as ObservableObject.
///
/// - Meant to be used for 'when the app is in use', NSLocationWhenInUseUsageDescription needs to be
/// set in Info.plist.
///
/// - This can be used by multiple observers but there should be a single manager object for the "isActive" property.
/// If multiple components want to manage isActive, maybe consider creating multiple instances (often