Skip to content

Instantly share code, notes, and snippets.

@yannxou
yannxou / CopyFileStorageContent.sh
Created July 1, 2024 09:40
Xcode build phase pre-action to copy File.app content for UI testing
LOGFILE="$HOME/Desktop/xcode-pre-action.txt";
# echo "TARGET_DEVICE_IDENTIFIER=$TARGET_DEVICE_IDENTIFIER" >> $LOGFILE;
FILES_PATH="$(xcrun simctl listapps $TARGET_DEVICE_IDENTIFIER | grep LocalStorage | awk -F'"' '{print $4}' | sed -e "s/^file:\/\///")/File Provider Storage"
# echo "FILES_PATH=$FILES_PATH" >> $LOGFILE;
INPUT_FOLDER="$SRCROOT/E2ETests/Resources/File Provider Storage";
# echo "INPUT_FOLDER=$INPUT_FOLDER" >> $LOGFILE;
echo "Copying File Provider Storage files to simulator...";
cp -R "$INPUT_FOLDER/" "$FILES_PATH/"
@yannxou
yannxou / Loggerformatting.swift
Created June 7, 2024 10:17
Xcode Logger formatting with optional parameters
// https://developer.apple.com/wwdc20/10168
let statisticsLogger = Logger (subsystem: "com.example.Fruta", category: "statistics")
// Log statistics about communication with a server.
func logStatistics(taskID: UUID, giftCardID: String, serverID: Int, seconds: Double) {
statisticsLogger.log("\(taskID) \(giftCardID, align: .left(columns: GiftCard.maxIDLength)) \(serverID) \(seconds, format: .fixed(precision: 2))")
@yannxou
yannxou / DebugLoggerOnly.swift
Created June 7, 2024 09:54
xcode disable logging in production
func customLog(_ category: String) -> OSLog {
#if DEBUG
return OSLog(subsystem: Bundle.main.bundleIdentifier!, category: category)
#else
return OSLog.disabled
#endif
}
@yannxou
yannxou / zalgo.swift
Created May 21, 2024 09:51
Zalgo text generator
// Zalgo text: https://en.wikipedia.org/wiki/Zalgo_text
func zalgo(_ string: String, intensity: Int = 5) -> String {
let combiningDiacriticMarks = 0x0300...0x036f
let latinAlphabetUppercase = 0x0041...0x005a
let latinAlphabetLowercase = 0x0061...0x007a
var output: [UnicodeScalar] = []
for scalar in string.unicodeScalars {
output.append(scalar)
guard (latinAlphabetUppercase).contains(numericCast(scalar.value)) ||
# Safely clean up SwiftUI Preview data located in:
# ~/Library/Developer/Xcode/UserData/Previews
xcrun simctl --set previews delete all
@yannxou
yannxou / ProcessInfo+SwiftUIPreview.swift
Created April 5, 2024 11:07
Swift: Detect code running in SwiftUI preview
extension ProcessInfo {
var isSwiftUIPreview: Bool {
environment["XCODE_RUNNING_FOR_PREVIEWS"] == "1"
}
// or:
static func isOnPreview() -> Bool {
return processInfo.processName == "XCPreviewAgent"
@yannxou
yannxou / OneShotSubscription.swift
Last active April 2, 2024 09:36
Combine: One-shot subscriptions
// Credit: https://www.apeth.com/UnderstandingCombine/subscribers/subscribersoneshot.html
var cancellable: AnyCancellable?
cancellable = pub.sink(receiveCompletion: {_ in
cancellable?.cancel()
}) { image in
self.imageView.image = image
}
// Or just subscribe to the Subscribers.Sink:
@yannxou
yannxou / ScrollToModifier.swift
Created September 28, 2023 12:58
SwiftUI: ScrollToModifier
import SwiftUI
public struct ScrollToModifier<T: Hashable>: ViewModifier {
@Binding var id: T?
public func body(content: Content) -> some View {
ScrollViewReader { proxy in
content
.onChange(of: id) { newValue in
if let id {
scrollTo(id: id, using: proxy)
@yannxou
yannxou / ActorReentrancy.swift
Last active September 15, 2023 07:11
Swift: Handling actor reentrancy correctly
// Code from: https://alexdremov.me/swift-actors-common-problems-and-tips/
import Foundation
actor ActivitiesStorage {
var cache = [UUID: Task<Data?, Never>]()
func retrieveHeavyData(for id: UUID) async -> Data? {
if let task = cache[id] {
return await task.value
@yannxou
yannxou / onTapGestureAsync.swift
Created July 26, 2023 10:40
SwiftUI onTapGesture modifier async
extension View {
func onTapGesture(perform action: () async -> Void) -> some View {
self.onTapGesture {
Task { await action() }
}
}
}