| #!/bin/bash | |
| TARGET_DIR=$1 | |
| echo "やるお" | |
| for file in $(find "$TARGET_DIR" -name "*.swift"); do | |
| # struct User: * { の場合。ただし、View適応は除く | |
| sed -i '' -E '/struct [A-Za-z0-9_]+: [^{]*View[^{]*\{/!s/(struct [A-Za-z0-9_]+: [^{]*)\{/\1, Sendable {/g' "$file" | |
| sed -i '' -E '/enum [A-Za-z0-9_]+: [^{]*View[^{]*\{/!s/(enum [A-Za-z0-9_]+: [^{]*)\{/\1, Sendable {/g' "$file" |
| import SwiftUI | |
| // MARK: - ObservableObject | |
| final class Counter: ObservableObject { | |
| @Published private(set) var count: Int | |
| deinit { | |
| print("🍂", #function, count) | |
| } |
| import SwiftUI | |
| struct MyValue: _ViewTraitKey { | |
| static var defaultValue: Int = 0 | |
| } | |
| extension View { | |
| func myValue(_ value: Int) -> some View { | |
| _trait(MyValue.self, value) | |
| } |
| import SwiftUI | |
| import class UIKit.UIImage | |
| struct AppleLogo: View { | |
| private let colors: [Color] = [ | |
| .green, | |
| .green, | |
| .green, | |
| .yellow, | |
| .orange, |
| extension Task where Failure == Error { | |
| // Start a new Task with a timeout. If the timeout expires before the operation is | |
| // completed then the task is cancelled and an error is thrown. | |
| init(priority: TaskPriority? = nil, timeout: TimeInterval, operation: @escaping @Sendable () async throws -> Success) { | |
| self = Task(priority: priority) { | |
| try await withThrowingTaskGroup(of: Success.self) { group -> Success in | |
| group.addTask(operation: operation) | |
| group.addTask { | |
| try await _Concurrency.Task.sleep(nanoseconds: UInt64(timeout * 1_000_000_000)) |
| import SwiftUI | |
| extension AttributedString { | |
| // call this init to make all the `code` block highlighted in specific way: | |
| init(codeHightlighted key: String.LocalizationValue) { | |
| var result = AttributedString(localized: key) | |
| let highlight = AttributeContainer.foregroundColor(.red).backgroundColor(.mint) | |
| result.replaceAttributes(AttributeContainer.inlinePresentationIntent(.code), with: highlight) | |
| self = result | |
| } |
| /// - seealso: https://www.hackingwithswift.com/articles/212/whats-new-in-swift-5-2 | |
| import Foundation | |
| protocol OptionalType { | |
| associatedtype Wrapped | |
| var value: Wrapped? { get } | |
| } | |
| extension Optional: OptionalType { |
| struct Contact: Decodable, CustomStringConvertible { | |
| var id: String | |
| @NestedKey | |
| var firstname: String | |
| @NestedKey | |
| var lastname: String | |
| @NestedKey | |
| var address: String | |
| enum CodingKeys: String, NestableCodingKey { |
| // Advanced SwiftUI Transitions | |
| // https://swiftui-lab.com | |
| // https://swiftui-lab.com/advanced-transitions | |
| import SwiftUI | |
| struct CrossEffectDemo: View { | |
| let animationDuration: Double = 2 | |
| let images = ["photo1", "photo2", "photo3", "photo4"] | |
| @State private var idx = 0 |