PokeMaster app 现在已经是一个具有完整功能的 SwiftUI app 了。麻雀虽小,五脏俱全,在这个示例 app 里,我们涉及到了一个一般性的 iOS app 所需要的大部分内容:
- 如何构建内容展示的列表
- 如何构建用户交互的表单
- 如何进行网络请求并把内容展示出来
- 如何响应用户的手势
- 如何在不同页面之间进行导航
- 以及,如何通过一定的架构将所有上面的内容整合起来
import SwiftUI | |
struct ContentView: View { | |
@State var offset: CGFloat = 0.0 | |
@State var previousOffset: CGFloat = 0.0 | |
init() { | |
let appearance = UINavigationBarAppearance() |
```swift | |
actor GiftCache { | |
private(set) var cachedGifts: [GiftId: CachedGift] = [:] | |
// this method would be caller by other parts | |
func add(gift: CachedGift) { | |
cachedGifts[gift.giftId] = gift | |
//... | |
} | |
// https://github.com/pointfreeco/swift-composable-architecture/discussions/488#discussioncomment-591715 | |
@propertyWrapper | |
public struct CoW<T> { | |
private final class Ref { | |
var val: T | |
init(_ v: T) { val = v } | |
} | |
private var ref: Ref |
protocol P: AnyObject { } | |
class A: P {} | |
Runtime.classes(conformTo: P.Type.self) // [MyApp.A] | |
class Runtime { | |
public static func allClasses() -> [AnyClass] { | |
let numberOfClasses = Int(objc_getClassList(nil, 0)) | |
if numberOfClasses > 0 { |
import UIKit | |
protocol DefaultValue { | |
associatedtype Value: Decodable | |
static var defaultValue: Value { get } | |
} | |
@propertyWrapper | |
struct Default<T: DefaultValue> { | |
var wrappedValue: T.Value |
//: A UIKit based Playground for presenting user interface | |
import UIKit | |
import PlaygroundSupport | |
public protocol TrafficLightOption { | |
associatedtype Value | |
/// 默认的选项值 | |
static var defaultValue: Value { get } |
import Combine | |
import Foundation | |
extension Publishers { | |
struct ZipAll<Collection: Swift.Collection>: Publisher | |
where Collection.Element: Publisher | |
{ | |
typealias Output = [Collection.Element.Output] | |
typealias Failure = Collection.Element.Failure |
class CabalInstall < Formula | |
desc "Command-line interface for Cabal and Hackage" | |
homepage "https://www.haskell.org/cabal/" | |
url "https://hackage.haskell.org/package/cabal-install-2.4.1.0/cabal-install-2.4.1.0.tar.gz" | |
sha256 "69bcb2b54a064982412e1587c3c5c1b4fada3344b41b568aab25730034cb21ad" | |
head "https://github.com/haskell/cabal.git", :branch => "2.4" | |
bottle do | |
cellar :any_skip_relocation | |
sha256 "4c9ad9914b483ffb64f4449bd6446cb8c0ddfeeff42eddde9137884af3471825" => :mojave |
import Foundation | |
import Combine | |
protocol Resumable { | |
func resume() | |
} | |
extension Subscribers { | |
class ResumableSink<Input, Failure: Error>: Subscriber, Cancellable, Resumable { | |
let receiveCompletion: (Subscribers.Completion<Failure>) -> Void |