Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: ra1028/swiftui-hooks
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 0.0.3
Choose a base ref
...
head repository: ra1028/swiftui-hooks
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref
Loading
Showing with 2,179 additions and 869 deletions.
  1. +1 −0 .github/FUNDING.yml
  2. +66 −0 .github/ISSUE_TEMPLATE/bug_report.yml
  3. +1 −0 .github/ISSUE_TEMPLATE/config.yml
  4. +27 −0 .github/ISSUE_TEMPLATE/documentation_request.yml
  5. +42 −0 .github/ISSUE_TEMPLATE/feature_request.yml
  6. +19 −0 .github/pull_request_template.md
  7. +28 −0 .github/workflows/docs.yml
  8. +21 −44 .github/workflows/test.yml
  9. +1 −2 .gitignore
  10. +9 −6 .swift-format.json → .swift-format
  11. +20 −12 Examples/BasicUsage/APIRequestPage.swift
  12. +2 −2 Examples/BasicUsage/IndexPage.swift
  13. +92 −14 Examples/BasicUsage/{HookListPage.swift → ShowcasePage.swift}
  14. +114 −34 Examples/Examples.xcodeproj/project.pbxproj
  15. +100 −0 Examples/Examples.xcodeproj/xcshareddata/xcschemes/Todo-UITests.xcscheme
  16. +12 −0 Examples/Examples.xcodeproj/xcshareddata/xcschemes/Todo.xcscheme
  17. +10 −14 Examples/TheMovieDB-MVVM-Tests/MovieDBServiceMock.swift
  18. +13 −10 Examples/TheMovieDB-MVVM-Tests/UseMovieImageTests.swift
  19. +19 −35 Examples/TheMovieDB-MVVM-Tests/UseTopRatedMoviesViewModelTests.swift
  20. +9 −0 Examples/TheMovieDB-MVVM-Tests/Utilities.swift
  21. +2 −2 Examples/TheMovieDB-MVVM/CustomHooks/UseMovieImage.swift
  22. +11 −33 Examples/TheMovieDB-MVVM/CustomHooks/UseTopRatedMoviesViewModel.swift
  23. +11 −19 Examples/TheMovieDB-MVVM/MovieDBService.swift
  24. +11 −5 Examples/TheMovieDB-MVVM/Pages/TopRatedMoviesPage.swift
  25. +50 −0 Examples/Todo-UITests/Info.plist
  26. +35 −0 Examples/Todo-UITests/SimpleUITests.swift
  27. +6 −1 Examples/Todo/TodoPage.swift
  28. +22 −6 Examples/project.yml
  29. +1 −1 LICENSE
  30. +50 −3 Makefile
  31. +5 −11 Package.swift
  32. +196 −95 README.md
  33. +1 −1 Sources/Hooks/Context/Consumer.swift
  34. +16 −18 Sources/Hooks/Hook.swift
  35. +135 −0 Sources/Hooks/Hook/UseAsync.swift
  36. +131 −0 Sources/Hooks/Hook/UseAsyncPerform.swift
  37. +2 −2 Sources/Hooks/Hook/UseContext.swift
  38. +23 −23 Sources/Hooks/Hook/UseEffect.swift
  39. +2 −2 Sources/Hooks/Hook/UseEnvironment.swift
  40. +14 −9 Sources/Hooks/Hook/UseMemo.swift
  41. +10 −12 Sources/Hooks/Hook/UsePublisher.swift
  42. +4 −5 Sources/Hooks/Hook/UsePublisherSubscribe.swift
  43. +14 −14 Sources/Hooks/Hook/UseReducer.swift
  44. +7 −4 Sources/Hooks/Hook/UseRef.swift
  45. +35 −10 Sources/Hooks/Hook/UseState.swift
  46. +0 −76 Sources/Hooks/HookComputation.swift
  47. +39 −27 Sources/Hooks/HookDispatcher.swift
  48. +57 −0 Sources/Hooks/HookUpdateStrategy.swift
  49. +56 −0 Sources/Hooks/Hooks.docc/Hooks.md
  50. +12 −0 Sources/Hooks/Internals/EnvironmentKeys.swift
  51. +19 −0 Sources/Hooks/ViewExtensions.swift
  52. +100 −0 Tests/HooksTests/Hook/UseAsyncPerformTests.swift
  53. +130 −0 Tests/HooksTests/Hook/UseAsyncTests.swift
  54. +57 −4 Tests/HooksTests/Hook/UseEffectTests.swift
  55. +8 −8 Tests/HooksTests/Hook/UseHookTests.swift
  56. +0 −21 Tests/HooksTests/Hook/UseMemoTests.swift
  57. +1 −26 Tests/HooksTests/Hook/UsePublisherTests.swift
  58. +48 −0 Tests/HooksTests/Hook/UseStateTests.swift
  59. +13 −0 Tests/HooksTests/Hook/Utilities.swift
  60. +0 −76 Tests/HooksTests/HookComputationTests.swift
  61. +42 −36 Tests/HooksTests/HookDispatcherTests.swift
  62. +24 −0 Tests/HooksTests/HookUpdateStrategyTests.swift
  63. +2 −2 Tests/HooksTests/Testing/HookTesterTests.swift
  64. +158 −0 Tools/Package.resolved
  65. +13 −0 Tools/Package.swift
  66. +0 −133 tools/Package.resolved
  67. +0 −11 tools/Package.swift
1 change: 1 addition & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
github: ra1028
66 changes: 66 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: Bug Report
description: File a bug report
title: "[Bug]: "
labels: ["bug"]
body:
- type: checkboxes
attributes:
label: Checklist
options:
- label: This is not a bug caused by platform.
required: true
- label: Reviewed the README and documentation.
required: true
- label: Checked existing issues & PRs to ensure not duplicated.
required: true

- type: textarea
attributes:
label: What happened?
validations:
required: true

- type: textarea
id: expected-behavior
attributes:
label: Expected Behavior
validations:
required: true

- type: textarea
attributes:
label: Reproduction Steps
value: |
1.
2.
3.
validations:
required: true

- type: input
attributes:
label: Swift Version
validations:
required: true

- type: input
attributes:
label: Library Version
validations:
required: true

- type: dropdown
attributes:
label: Platform
multiple: true
options:
- iOS
- tvOS
- macOS
- watchOS

- type: textarea
attributes:
label: Scrrenshot/Video/Gif
placeholder: |
Drag and drop screenshot, video, or gif here if you have.
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
blank_issues_enabled: false
27 changes: 27 additions & 0 deletions .github/ISSUE_TEMPLATE/documentation_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Documentation Request
description: Suggest a new doc/example or ask a question about an existing one
title: "[Doc Request]: "
labels: ["documentation"]
body:
- type: checkboxes
attributes:
label: Checklist
options:
- label: Reviewed the README and documentation.
required: true
- label: Confirmed that this is uncovered by existing docs or examples.
required: true
- label: Checked existing issues & PRs to ensure not duplicated.
required: true

- type: textarea
attributes:
label: Description
placeholder: Describe what the scenario you think is uncovered by the existing ones and why you think it should be covered.
validations:
required: true

- type: textarea
attributes:
label: Motivation & Context
placeholder: Feel free to describe any additional context, such as why you thought the scenario should be covered.
42 changes: 42 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Feature Request
description: Suggest a new idea of feature
title: "[Feat Request]: "
labels: ["enhancement"]
body:
- type: checkboxes
attributes:
label: Checklist
options:
- label: Reviewed the README and documentation.
required: true
- label: Checked existing issues & PRs to ensure not duplicated.
required: true

- type: textarea
attributes:
label: Description
placeholder: Describe the feature that you want to propose.
validations:
required: true

- type: textarea
attributes:
label: Example Use Case
placeholder: Describe an example use case that the feature is useful.
validations:
required: true

- type: textarea
attributes:
label: Alternative Solution
placeholder: Describe alternatives solutions that you've considered.

- type: textarea
attributes:
label: Proposed Solution
placeholder: Describe how we can achieve the feature you'd like to suggest.

- type: textarea
attributes:
label: Motivation & Context
placeholder: Feel free to describe any additional context, such as why you want to suggest this feature.
19 changes: 19 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
## Pull Request Type

- [ ] Bug fix
- [ ] New feature
- [ ] Refactoring
- [ ] Documentation update
- [ ] Chore

## Issue for this PR

Link:

## Description

## Motivation and Context

## Impact on Existing Code

## Screenshot/Video/Gif
28 changes: 28 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# https://github.com/actions/virtual-environments

name: docs

on:
release:
types: [published]
workflow_dispatch:

jobs:
test:
name: Test
runs-on: macos-12
strategy:
matrix:
xcode_version:
- 13.3
env:
DEVELOPER_DIR: /Applications/Xcode_${{ matrix.xcode_version }}.app
steps:
- uses: actions/checkout@v2
- name: Build docs
run: make docs
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: docs
65 changes: 21 additions & 44 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,25 +1,22 @@
# https://github.com/actions/virtual-environments

name: GitHub Actions
name: test

on:
pull_request:
push:
branches:
- main
workflow_dispatch:
branches:
- main

jobs:
test:
name: Test
runs-on: macos-10.15
runs-on: macos-12
strategy:
matrix:
xcode_version:
- 12.4
# Should revisit these versions once Big sur will be available.
# - 12.5.1
# - 13.0
- 13.3
env:
DEVELOPER_DIR: /Applications/Xcode_${{ matrix.xcode_version }}.app
steps:
@@ -28,45 +25,25 @@ jobs:
run: |
swift --version
xcodebuild -version
- name: Test for macOS
run: xcodebuild test -scheme Hooks -destination "platform=macOS"
- name: Test for iOS
run: xcodebuild test -scheme Hooks -destination "platform=iOS Simulator,name=iPhone 12 Pro"
- name: Test for tvOS
run: xcodebuild test -scheme Hooks -destination "platform=tvOS Simulator,name=Apple TV"
- name: Build for watchOS
run: WATCHOS=true xcodebuild build -scheme Hooks -destination "platform=watchOS Simulator,name=Apple Watch Series 6 - 44mm"
- name: Test library
run: make test-library
- name: Build examples
run: make build-examples

build-examples:
name: Build examples
runs-on: macos-10.15
validation:
name: Validation
runs-on: macos-12
env:
DEVELOPER_DIR: /Applications/Xcode_12.4.app
OLD_XCODE_APP: /Applications/Xcode_11.7.app
OLD_TARGET_OS: 13.7
OLD_RUNTIME_NAME: com.apple.CoreSimulator.SimRuntime.iOS-13-7
defaults:
run:
working-directory: Examples
DEVELOPER_DIR: /Applications/Xcode_13.3.app
steps:
- uses: actions/checkout@v2
- name: Show environments
- name: Validate lint
run: make lint
- name: Validate format
run: |
swift --version
xcodebuild -version
- name: Prepare old OS simulator
make format
if [ -n "$(git status --porcelain)" ]; then echo "Make sure that the code is formated by 'make format'."; exit 1; fi
- name: Validate example project
run: |
sudo mkdir -p /Library/Developer/CoreSimulator/Profiles/Runtimes
sudo ln -s $OLD_XCODE_APP/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime /Library/Developer/CoreSimulator/Profiles/Runtimes/iOS\ $OLD_TARGET_OS.simruntime
xcrun simctl list runtimes
xcrun simctl list devices $OLD_TARGET_OS
- name: Build TheMovieDB
run: xcodebuild build -scheme TheMovieDB-MVVM -destination "platform=iOS Simulator,name=iPhone 12 Pro"
- name: Test TheMovieDB
run: xcodebuild test -scheme TheMovieDB-MVVM-Tests -destination "platform=iOS Simulator,name=iPhone 12 Pro"
- name: Build Basic
run: xcodebuild build -scheme BasicUsage -destination "platform=iOS Simulator,name=iPhone 12 Pro"
- name: Build Legacy
run: xcodebuild build -scheme Todo -destination "platform=iOS Simulator,name=iPhone 12 Pro"
- name: Build Legacy with iOS13
run: xcodebuild build -scheme Todo -destination "platform=iOS Simulator,name=iPhone 11 Pro,OS=$OLD_TARGET_OS"
make proj
if [ -n "$(git status --porcelain)" ]; then echo "Make sure that 'Examples/Examples.xcodeproj' is formated by 'make proj'."; exit 1; fi
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -19,7 +19,6 @@ DerivedData
build/
archive/
*.xcframework

## SwiftPM
.swiftpm
.build
docs
15 changes: 9 additions & 6 deletions .swift-format.json → .swift-format
Original file line number Diff line number Diff line change
@@ -7,7 +7,8 @@
"accessLevel": "private"
},
"indentConditionalCompilationBlocks": true,
"lineBreakAroundMultilineExpressionChainComponents": true,
"indentSwitchCaseLabels": false,
"lineBreakAroundMultilineExpressionChainComponents": false,
"lineBreakBeforeControlFlowKeywords": true,
"lineBreakBeforeEachArgument": true,
"lineBreakBeforeEachGenericRequirement": true,
@@ -21,14 +22,14 @@
"AmbiguousTrailingClosureOverload": true,
"BeginDocumentationCommentWithOneLineSummary": false,
"DoNotUseSemicolons": true,
"DontRepeatTypeInStaticProperties": true,
"FileprivateAtFileScope": true,
"DontRepeatTypeInStaticProperties": false,
"FileScopedDeclarationPrivacy": true,
"FullyIndirectEnum": true,
"GroupNumericLiterals": true,
"IdentifiersMustBeASCII": true,
"NeverForceUnwrap": true,
"NeverForceUnwrap": false,
"NeverUseForceTry": true,
"NeverUseImplicitlyUnwrappedOptionals": true,
"NeverUseImplicitlyUnwrappedOptionals": false,
"NoAccessLevelOnExtensionDeclaration": false,
"NoBlockComments": true,
"NoCasesWithOnlyFallthrough": true,
@@ -42,11 +43,13 @@
"OnlyOneTrailingClosureArgument": false,
"OrderedImports": true,
"ReturnVoidInsteadOfEmptyTuple": true,
"UseEarlyExits": false,
"UseLetInEveryBoundCaseVariable": true,
"UseShorthandTypeNames": true,
"UseSingleLinePropertyGetter": true,
"UseSynthesizedInitializer": false,
"UseSynthesizedInitializer": true,
"UseTripleSlashForDocumentationComments": true,
"UseWhereClausesInForLoops": false,
"ValidateDocumentationComments": false
}
}
32 changes: 20 additions & 12 deletions Examples/BasicUsage/APIRequestPage.swift
Original file line number Diff line number Diff line change
@@ -7,16 +7,15 @@ struct Post: Codable {
let body: String
}

func useFetchPosts() -> (phase: AsyncPhase<[Post], Error>, fetch: () -> Void) {
let url = URL(string: "https://jsonplaceholder.typicode.com/posts").unsafelyUnwrapped
let (phase, subscribe) = usePublisherSubscribe {
URLSession.shared.dataTaskPublisher(for: url)
.map(\.data)
.decode(type: [Post].self, decoder: JSONDecoder())
.receive(on: DispatchQueue.main)
func useFetchPosts() -> (phase: AsyncPhase<[Post], Error>, fetch: () async -> Void) {
let url = URL(string: "https://jsonplaceholder.typicode.com/posts")!
let (phase, fetch) = useAsyncPerform { () throws -> [Post] in
let decoder = JSONDecoder()
let (data, _) = try await URLSession.shared.data(from: url)
return try decoder.decode([Post].self, from: data)
}

return (phase: phase, fetch: subscribe)
return (phase: phase, fetch: fetch)
}

struct APIRequestPage: HookView {
@@ -44,7 +43,9 @@ struct APIRequestPage: HookView {
}
.navigationTitle("API Request")
.background(Color(.systemBackground).ignoresSafeArea())
.onAppear(perform: fetch)
.task {
await fetch()
}
}

func postRows(_ posts: [Post]) -> some View {
@@ -58,11 +59,18 @@ struct APIRequestPage: HookView {
}
}

func errorRow(_ error: Error, retry: @escaping () -> Void) -> some View {
func errorRow(_ error: Error, retry: @escaping () async -> Void) -> some View {
VStack {
Text("Error: \(error.localizedDescription)").fixedSize(horizontal: false, vertical: true)
Text("Error: \(error.localizedDescription)")
.fixedSize(horizontal: false, vertical: true)

Divider()
Button("Refresh", action: retry)

Button("Refresh") {
Task {
await retry()
}
}
}
}
}
Loading