├── .gitignore
├── ActionableViewModel
├── ActionableViewModel.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── ActionableViewModel
│ ├── Actionable.swift
│ ├── ActionableViewModelApp.swift
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── ContentView.swift
│ ├── Feature
│ │ ├── About
│ │ │ └── AboutCoordinatorView.swift
│ │ ├── Main
│ │ │ ├── Enrollment
│ │ │ │ └── EnrollmentCoordinatorView.swift
│ │ │ ├── Home
│ │ │ │ ├── HomeCoordinatorView.swift
│ │ │ │ ├── HomeView.swift
│ │ │ │ └── Profile
│ │ │ │ │ └── ProfileView.swift
│ │ │ ├── MainCoordinatorView.swift
│ │ │ ├── More
│ │ │ │ ├── Details
│ │ │ │ │ └── DetailsView.swift
│ │ │ │ ├── MoreCoordinatorView.swift
│ │ │ │ └── MoreView.swift
│ │ │ └── Settings
│ │ │ │ └── SettingsCoordinatorView.swift
│ │ ├── Onboarding
│ │ │ └── OnboardingCoordinatorView.swift
│ │ └── RootCoordinatorView.swift
│ └── Preview Content
│ │ └── Preview Assets.xcassets
│ │ └── Contents.json
└── README.md
├── AlternateAppIcon
├── AlternateAppIcon.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── AlternateAppIcon
│ ├── AlternateAppIconApp.swift
│ ├── AppDelegate.swift
│ ├── AppInfoProvider.swift
│ ├── Application.swift
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── Blue Green.appiconset
│ │ │ ├── Contents.json
│ │ │ └── Icon BlueGreen.png
│ │ ├── Blue Red.appiconset
│ │ │ ├── Contents.json
│ │ │ └── Icon BlueRed.png
│ │ ├── Contents.json
│ │ ├── Green Red.appiconset
│ │ │ ├── Contents.json
│ │ │ └── Icon GreenRed.png
│ │ └── Red Blue.appiconset
│ │ │ ├── Contents.json
│ │ │ └── Icon RedBlue.png
│ ├── ContentView+ViewModel.swift
│ ├── ContentView.swift
│ ├── Dependencies.swift
│ └── Preview Content
│ │ ├── MockAppInfoProvider.swift
│ │ ├── MockApplication.swift
│ │ ├── MockDependencies.swift
│ │ └── Preview Assets.xcassets
│ │ └── Contents.json
└── README.md
├── BLEChat
├── BLEChat.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── swiftpm
│ │ │ └── Package.resolved
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── BLEChat.xcscheme
├── BLEChat
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Base.lproj
│ │ └── LaunchScreen.storyboard
│ ├── Bluetooth
│ │ ├── AssignedNumbers.swift
│ │ ├── BluetoothError.swift
│ │ ├── ChatHost
│ │ │ ├── ChatHost.swift
│ │ │ ├── ChatServiceFactory.swift
│ │ │ └── CoreBluetoothChatHost.swift
│ │ └── ChatHostScanner
│ │ │ ├── ChatHostConnection.swift
│ │ │ ├── ChatHostScanner.swift
│ │ │ ├── CoreBluetoothChatHostConnection.swift
│ │ │ └── CoreBluetoothChatHostScanner.swift
│ ├── Dependencies.swift
│ ├── Features
│ │ ├── Guest
│ │ │ ├── GuestChatViewController.swift
│ │ │ └── JoinViewController.swift
│ │ ├── HomeViewController.swift
│ │ ├── Host
│ │ │ └── HostChatViewController.swift
│ │ └── Shared
│ │ │ ├── ChatBubbleTableViewCell.swift
│ │ │ └── ChatSection.swift
│ ├── Info.plist
│ ├── SceneDelegate.swift
│ └── Utils
│ │ └── StopRunLoopSource.swift
└── README.md
├── BackgroundCleanup
├── BackgroundCleanup.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── BackgroundCleanup.xcscheme
├── BackgroundCleanup
│ ├── App
│ │ ├── AppDelegate.swift
│ │ ├── AppDependencies.swift
│ │ ├── DefaultAppDependencies.swift
│ │ ├── Info.plist
│ │ ├── SceneDelegate.swift
│ │ └── UIApplication+Application.swift
│ ├── Common
│ │ ├── Models
│ │ │ └── Item.swift
│ │ ├── Repositories
│ │ │ └── ItemRepository.swift
│ │ └── Services
│ │ │ ├── CleanupService.swift
│ │ │ └── RefreshService.swift
│ ├── Features
│ │ ├── ItemsViewController.swift
│ │ └── ItemsViewModel.swift
│ └── Resources
│ │ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ │ └── Base.lproj
│ │ └── LaunchScreen.storyboard
└── README.md
├── BottomSheetController
├── BottomSheetController.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── BottomSheetController
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Base.lproj
│ │ └── LaunchScreen.storyboard
│ ├── BottomSheet
│ │ ├── BottomSheetController.swift
│ │ ├── BottomSheetInteractiveDismissalTransition.swift
│ │ ├── BottomSheetPresentationController.swift
│ │ └── BottomSheetTransitioningDelegate.swift
│ ├── DenseContentSheetViewController.swift
│ ├── ExpandingContentSheetViewController.swift
│ ├── Info.plist
│ ├── LifecycleDependentContentSheetViewController.swift
│ ├── SceneDelegate.swift
│ ├── SparseContentSheetViewController.swift
│ ├── TableContentSheetViewController.swift
│ └── ViewController.swift
└── README.md
├── BuildConfigurations
├── BuildConfigurations.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata
│ │ └── xcschemes
│ │ ├── BuildConfigurations Prod.xcscheme
│ │ ├── BuildConfigurations-Develop.xcscheme
│ │ └── BuildConfigurations-Test.xcscheme
├── BuildConfigurations
│ ├── App
│ │ ├── BuildConfigurationsApp.swift
│ │ └── ContentView.swift
│ ├── Flavours
│ │ ├── Develop
│ │ │ ├── ConstantsDevelop.swift
│ │ │ └── Properties.plist
│ │ ├── Prod
│ │ │ ├── ConstantsProd.swift
│ │ │ └── Properties.plist
│ │ ├── Properties.plist
│ │ └── Test
│ │ │ ├── ConstantsTest.swift
│ │ │ └── Properties.plist
│ ├── Preview Content
│ │ └── Preview Assets.xcassets
│ │ │ └── Contents.json
│ └── Resources
│ │ └── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ └── Contents.json
│ │ └── Contents.json
└── README.md
├── ConsecutiveTabTaps
├── ConsecutiveTabTaps.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── ConsecutiveTabTaps
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── ConsecutiveTabTapsApp.swift
│ ├── Countries
│ │ ├── CountriesView.swift
│ │ ├── CountriesViewModel.swift
│ │ ├── Country.swift
│ │ └── Country
│ │ │ └── CountryView.swift
│ ├── MainView.swift
│ ├── MainViewModel.swift
│ ├── Preview Content
│ │ └── Preview Assets.xcassets
│ │ │ └── Contents.json
│ └── String+emojiFlag.swift
└── README.md
├── ContainerViewController
├── ContainerViewController.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── swiftpm
│ │ └── Package.resolved
├── ContainerViewController
│ ├── App
│ │ ├── AppDelegate.swift
│ │ ├── AppDependencies.swift
│ │ ├── AppFlowController.swift
│ │ ├── Info.plist
│ │ ├── SceneDelegate.swift
│ │ └── SceneFlowController.swift
│ ├── Common
│ │ ├── SegmentedPageController.swift
│ │ └── SinglePageController.swift
│ ├── Features
│ │ ├── Login
│ │ │ ├── Login
│ │ │ │ ├── LoginViewController.swift
│ │ │ │ └── LoginViewModel.swift
│ │ │ ├── LoginFlowController.swift
│ │ │ └── Registration
│ │ │ │ ├── RegisterViewController.swift
│ │ │ │ └── RegisterViewModel.swift
│ │ ├── Main
│ │ │ ├── Activity
│ │ │ │ ├── ActivityFlowController.swift
│ │ │ │ └── ActivityViewController.swift
│ │ │ ├── Home
│ │ │ │ ├── Feed
│ │ │ │ │ ├── FeedFlowController.swift
│ │ │ │ │ ├── New
│ │ │ │ │ │ └── NewsViewController.swift
│ │ │ │ │ └── Popular
│ │ │ │ │ │ └── PopularViewController.swift
│ │ │ │ ├── HomeFlowController.swift
│ │ │ │ └── HomeViewController.swift
│ │ │ ├── MainFlowController.swift
│ │ │ └── Profile
│ │ │ │ ├── ProfileFlowController.swift
│ │ │ │ ├── ProfileViewController.swift
│ │ │ │ └── ProfileViewModel.swift
│ │ └── Onboarding
│ │ │ ├── OnboardingFlowController.swift
│ │ │ ├── OnboardingViewController.swift
│ │ │ └── OnboardingViewModel.swift
│ └── Resources
│ │ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ │ └── LaunchScreen.storyboard
└── README.md
├── CustomInterfaceBuilderView
├── CustomInterfaceBuilderView.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── CustomInterfaceBuilderView
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ ├── CircularView.swift
│ ├── Info.plist
│ ├── RatingView.swift
│ ├── RoundedView.swift
│ ├── SceneDelegate.swift
│ └── ViewController.swift
└── README.md
├── CustomPresentationController
├── CustomPresentationController.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── CustomPresentationController
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ ├── Contents.json
│ │ └── fruit.imageset
│ │ │ ├── Contents.json
│ │ │ └── fruit.jpeg
│ ├── Base.lproj
│ │ └── LaunchScreen.storyboard
│ ├── ContentViewController.swift
│ ├── DialogTransitionManager.swift
│ ├── Info.plist
│ ├── MotionEffectsViewController.swift
│ ├── SceneDelegate.swift
│ ├── ShelfTransitionManager.swift
│ ├── ViewController.swift
│ └── VisualEffectsViewController.swift
└── README.md
├── DialogController
├── DialogController.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── DialogController
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Base.lproj
│ │ └── LaunchScreen.storyboard
│ ├── Dialog
│ │ ├── DialogController.swift
│ │ └── DialogTransitioningDelegate.swift
│ ├── ExpandableDialogController.swift
│ ├── FormDialogController.swift
│ ├── Info.plist
│ ├── OkCancelDialogController.swift
│ ├── OkDialogController.swift
│ ├── SceneDelegate.swift
│ └── ViewController.swift
└── README.md
├── DynamicAnimations
├── DynamicAnimations.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── DynamicAnimations
│ ├── App
│ │ ├── AppDelegate.swift
│ │ ├── Info.plist
│ │ ├── SceneDelegate.swift
│ │ └── TabBarController.swift
│ ├── Behaviors
│ │ ├── AttachmentBehaviorViewController.swift
│ │ ├── CollisionBehaviorViewController.swift
│ │ ├── FieldBehaviorViewController.swift
│ │ ├── PushBehaviorViewController.swift
│ │ └── SnapBehaviorViewController.swift
│ ├── Common
│ │ └── BallView.swift
│ └── Resources
│ │ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ │ └── Base.lproj
│ │ └── LaunchScreen.storyboard
└── README.md
├── DynamicTableHeaderView
├── DynamicTableHeaderView.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── DynamicTableHeaderView
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ ├── Contents.json
│ │ ├── episode3.imageset
│ │ │ ├── Contents.json
│ │ │ └── episode3.png
│ │ ├── episode4.imageset
│ │ │ ├── Contents.json
│ │ │ └── episode4.png
│ │ ├── episode5.imageset
│ │ │ ├── Contents.json
│ │ │ └── episode5.png
│ │ ├── episode6.imageset
│ │ │ ├── Contents.json
│ │ │ └── episode6.png
│ │ ├── episode7.imageset
│ │ │ ├── Contents.json
│ │ │ └── episode7.png
│ │ ├── episode8.imageset
│ │ │ ├── Contents.json
│ │ │ └── episode8.png
│ │ ├── episode9.imageset
│ │ │ ├── Contents.json
│ │ │ └── episode9.png
│ │ └── luke.imageset
│ │ │ ├── Contents.json
│ │ │ └── luke.png
│ ├── Base.lproj
│ │ └── LaunchScreen.storyboard
│ ├── Info.plist
│ ├── SceneDelegate.swift
│ ├── TableFooterView.swift
│ ├── TableHeaderView.swift
│ └── TableViewController.swift
└── README.md
├── ErrorResponder
├── ErrorResponder.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ └── contents.xcworkspacedata
├── ErrorResponder
│ ├── App
│ │ ├── BackgroundService.swift
│ │ └── ErrorResponderApp.swift
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Common
│ │ └── HTTPAPIProblem.swift
│ ├── ErrorResponder.swift
│ ├── ErrorResponderChain.swift
│ ├── ErrorResponderViewModel.swift
│ ├── Feature
│ │ ├── CommonError.swift
│ │ ├── FeatureOne
│ │ │ ├── FeatureOneCoordinatorView+ViewModel.swift
│ │ │ ├── FeatureOneCoordinatorView.swift
│ │ │ ├── FeatureOneError.swift
│ │ │ └── PageOne
│ │ │ │ ├── PageOneFeatureOneError.swift
│ │ │ │ ├── PageOneFeatureOneView+ViewModel.swift
│ │ │ │ └── PageOneFeatureOneView.swift
│ │ ├── FeatureThree
│ │ │ ├── FeatureThreeCoordinatorView.swift
│ │ │ └── PageOne
│ │ │ │ └── PageOneFeatureThreeView.swift
│ │ ├── FeatureTwo
│ │ │ ├── FeatureTwoCoordinatorView+ViewModel.swift
│ │ │ ├── FeatureTwoCoordinatorView.swift
│ │ │ ├── FeatureTwoError.swift
│ │ │ └── PageOne
│ │ │ │ ├── PageOneFeatureTwoError.swift
│ │ │ │ ├── PageOneFeatureTwoView+ViewModel.swift
│ │ │ │ └── PageOneFeatureTwoView.swift
│ │ ├── RootCoordinatorView+ViewModel.swift
│ │ └── RootCoordinatorView.swift
│ ├── Preview Content
│ │ └── Preview Assets.xcassets
│ │ │ └── Contents.json
│ └── View+AlertDetails.swift
└── README.md
├── ExpandableTableViewCell
├── ExpandableTableViewCell.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── ExpandableTableViewCell
│ ├── Accordion
│ │ ├── AccordionTableViewCell.swift
│ │ └── AccordionTableViewController.swift
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Base.lproj
│ │ └── LaunchScreen.storyboard
│ ├── Details
│ │ ├── DetailsTableViewCell.swift
│ │ └── DetailsTableViewController.swift
│ ├── ExpandableTableViewCellDelegate.swift
│ ├── HeaderView.swift
│ ├── Info.plist
│ ├── SceneDelegate.swift
│ └── TabBarViewController.swift
└── README.md
├── ExtendedSplashScreen
├── ExtendedSplashScreen.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── ExtendedSplashScreen
│ ├── AppBlockedViewController.swift
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Base.lproj
│ │ └── LaunchScreen.storyboard
│ ├── DeviceManager.swift
│ ├── Info.plist
│ ├── MainViewController.swift
│ ├── RootViewController.swift
│ ├── SceneDelegate.swift
│ └── SplashScreenViewController.swift
└── README.md
├── FeatureModules
├── CoreKit
│ ├── .gitignore
│ ├── Package.swift
│ ├── README.md
│ └── Sources
│ │ └── CoreKit
│ │ └── Coordinator.swift
├── FeatureModules.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── FeatureModules
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Base.lproj
│ │ └── LaunchScreen.storyboard
│ ├── Info.plist
│ ├── SceneDelegate.swift
│ └── TabBarController.swift
├── FeatureOneKit
│ ├── .gitignore
│ ├── Package.swift
│ ├── README.md
│ └── Sources
│ │ └── FeatureOneKit
│ │ ├── FeatureOneCoordinator.swift
│ │ └── FeatureOneViewController.swift
├── FeatureThreeKit
│ ├── .gitignore
│ ├── Package.swift
│ ├── README.md
│ └── Sources
│ │ └── FeatureThreeKit
│ │ ├── CustomNavigationController.swift
│ │ ├── FeatureThreeCoordinator.swift
│ │ └── FeatureThreeViewController.swift
├── FeatureTwoKit
│ ├── .gitignore
│ ├── Package.swift
│ ├── README.md
│ └── Sources
│ │ └── FeatureTwoKit
│ │ ├── FeatureTwoCoordinator.swift
│ │ └── FeatureTwoViewController.swift
└── README.md
├── FlowControllerPattern
├── ExamplePush.apns
├── FlowControllerPattern.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── FlowControllerPattern.xcscheme
├── FlowControllerPattern
│ ├── App
│ │ ├── AppDelegate.swift
│ │ ├── AppDependencies.swift
│ │ ├── AppFlowFactory.swift
│ │ ├── AppFlowHost+AppFlowController.swift
│ │ ├── AppPage.swift
│ │ ├── Base.lproj
│ │ │ └── LaunchScreen.storyboard
│ │ ├── DefaultAppDependencies.swift
│ │ ├── DefaultAppFlowFactory.swift
│ │ ├── DefaultAppFlowHost.swift
│ │ ├── FlowControllerPattern.entitlements
│ │ └── Info.plist
│ ├── Common
│ │ ├── Configuration
│ │ │ ├── App
│ │ │ │ ├── AppConfiguration.swift
│ │ │ │ └── DefaultAppConfiguration.swift
│ │ │ └── Remote
│ │ │ │ ├── DefaultRemoteConfiguration.swift
│ │ │ │ └── RemoteConfiguration.swift
│ │ ├── Models
│ │ │ ├── ShoppingCart
│ │ │ │ └── ShoppingCart.swift
│ │ │ └── Store
│ │ │ │ └── Store.swift
│ │ ├── Networking
│ │ │ └── Core
│ │ │ │ ├── DefaultNetworkClient.swift
│ │ │ │ ├── NetworkClient.swift
│ │ │ │ ├── Request+Endpoint.swift
│ │ │ │ ├── Request.swift
│ │ │ │ └── RequestBuilder.swift
│ │ ├── Repositories
│ │ │ └── Defaults
│ │ │ │ ├── DefaultDefaultsRepository.swift
│ │ │ │ └── DefaultsRepository.swift
│ │ ├── Services
│ │ │ ├── Analytics
│ │ │ │ ├── AnalyticsLogger.swift
│ │ │ │ └── DefaultAnalyticsLogger.swift
│ │ │ ├── Booking
│ │ │ │ ├── BookingService.swift
│ │ │ │ └── DefaultBookingService.swift
│ │ │ ├── Crashlytics
│ │ │ │ ├── CrashlyticsRecorder.swift
│ │ │ │ └── DefaultCrashlyticsRecorder.swift
│ │ │ └── Store
│ │ │ │ ├── DefaultStoreService.swift
│ │ │ │ └── StoreService.swift
│ │ └── ViewControllers
│ │ │ ├── SegmentedPageController.swift
│ │ │ └── SinglePageController.swift
│ ├── Resources
│ │ └── Assets.xcassets
│ │ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ │ └── Contents.json
│ └── Scenes
│ │ ├── Extractor.swift
│ │ ├── Primary
│ │ ├── AppPage+Primary.swift
│ │ ├── DefaultPrimarySceneFlowHost.swift
│ │ ├── Features
│ │ │ ├── Main
│ │ │ │ ├── Activity
│ │ │ │ │ ├── ActivityFlowFactory.swift
│ │ │ │ │ ├── ActivityFlowHost+ActivityFlowController.swift
│ │ │ │ │ ├── DefaultActivityFlowHost.swift
│ │ │ │ │ └── Purchases
│ │ │ │ │ │ ├── DefaultPurchasesFlowHost.swift
│ │ │ │ │ │ └── PurchasesFlowHost+PurchasesFlowController.swift
│ │ │ │ ├── Booking
│ │ │ │ │ ├── BookingFlowFactory.swift
│ │ │ │ │ ├── BookingFlowHost+BookingFlowController.swift
│ │ │ │ │ ├── Checkout
│ │ │ │ │ │ ├── CheckoutViewController.swift
│ │ │ │ │ │ └── CheckoutViewModel.swift
│ │ │ │ │ ├── DefaultBookingFlowHost.swift
│ │ │ │ │ └── Store
│ │ │ │ │ │ ├── StoreViewController.swift
│ │ │ │ │ │ └── StoreViewModel.swift
│ │ │ │ ├── DefaultMainFlowController.swift
│ │ │ │ ├── Explore
│ │ │ │ │ ├── DefaultExploreFlowHost.swift
│ │ │ │ │ ├── ExploreFlowFactory.swift
│ │ │ │ │ ├── ExploreFlowHost+ExploreFlowController.swift
│ │ │ │ │ ├── Referral
│ │ │ │ │ │ └── ReferralViewController.swift
│ │ │ │ │ └── Store
│ │ │ │ │ │ ├── DefaultStoreFlowHost.swift
│ │ │ │ │ │ ├── List
│ │ │ │ │ │ ├── StoreListView.swift
│ │ │ │ │ │ ├── StoreListViewController.swift
│ │ │ │ │ │ └── StoreListViewModel.swift
│ │ │ │ │ │ ├── Map
│ │ │ │ │ │ ├── StoreMapView.swift
│ │ │ │ │ │ └── StoreMapViewController.swift
│ │ │ │ │ │ ├── StoreFilterSheet
│ │ │ │ │ │ └── StoreFilterSheetController.swift
│ │ │ │ │ │ ├── StoreFlowFactory.swift
│ │ │ │ │ │ ├── StoreFlowHost+StoreFlowController.swift
│ │ │ │ │ │ └── StoreFlowModels.swift
│ │ │ │ ├── MainFlowFactory.swift
│ │ │ │ ├── MainFlowHost+MainFlowController.swift
│ │ │ │ └── Profile
│ │ │ │ │ ├── DefaultProfileFlowHost.swift
│ │ │ │ │ ├── ProfileFlowFactory.swift
│ │ │ │ │ └── ProfileFlowHost+ProfileFlowController.swift
│ │ │ └── Onboarding
│ │ │ │ ├── DefaultOnboardingFlowHost.swift
│ │ │ │ ├── Onboarding
│ │ │ │ ├── OnboardingView.swift
│ │ │ │ ├── OnboardingViewController.swift
│ │ │ │ └── OnboardingViewModel.swift
│ │ │ │ ├── OnboardingFlowFactory.swift
│ │ │ │ └── OnboardingFlowHost+OnboardingFlowController.swift
│ │ ├── PrimarySceneFlowFactory.swift
│ │ └── PrimarySceneFlowHost+PrimarySceneFlowController.swift
│ │ └── SceneDelegate.swift
└── README.md
├── FlowViewPattern
├── FlowViewPattern.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── FlowViewPattern.xcscheme
├── FlowViewPattern
│ ├── App
│ │ ├── AppDelegate.swift
│ │ ├── AppDependencies.swift
│ │ ├── AppPath.swift
│ │ ├── DefaultAppDependencies.swift
│ │ ├── DefaultAppFlowViewFactory.swift
│ │ ├── Extractor.swift
│ │ └── FlowViewPatternApp.swift
│ ├── Common
│ │ └── Repositories
│ │ │ └── Defaults
│ │ │ ├── DefaultsRepository.swift
│ │ │ └── UserDefaultsDefaultsRepository.swift
│ ├── Content
│ │ ├── AppFlowCoordinator.swift
│ │ ├── AppFlowView.swift
│ │ ├── AppFlowViewFactory.swift
│ │ ├── AppFlowViewModel.swift
│ │ ├── Main
│ │ │ ├── Activity
│ │ │ │ ├── ActivityFlowCoordinator.swift
│ │ │ │ ├── ActivityFlowView.swift
│ │ │ │ └── ActivityFlowViewModel.swift
│ │ │ ├── Booking
│ │ │ │ ├── BookingFlowCoordinator.swift
│ │ │ │ ├── BookingFlowView.swift
│ │ │ │ └── BookingFlowViewModel.swift
│ │ │ ├── Explore
│ │ │ │ ├── ExploreFlowCoordinator.swift
│ │ │ │ ├── ExploreFlowView.swift
│ │ │ │ ├── ExploreFlowViewFactory.swift
│ │ │ │ ├── ExploreFlowViewModel.swift
│ │ │ │ ├── MapAndList
│ │ │ │ │ ├── List
│ │ │ │ │ │ ├── ExploreListView.swift
│ │ │ │ │ │ └── ExploreListViewModel.swift
│ │ │ │ │ ├── Map
│ │ │ │ │ │ ├── ExploreMapView.swift
│ │ │ │ │ │ └── ExploreMapViewModel.swift
│ │ │ │ │ ├── MapAndListFlowCoordinator.swift
│ │ │ │ │ ├── MapAndListFlowView.swift
│ │ │ │ │ ├── MapAndListFlowViewFactory.swift
│ │ │ │ │ └── MapAndListFlowViewModel.swift
│ │ │ │ └── News
│ │ │ │ │ └── ExploreNewsView.swift
│ │ │ ├── Greeting
│ │ │ │ ├── WelcomeBackView.swift
│ │ │ │ └── WelcomeBackViewModel.swift
│ │ │ ├── MainFlowCoordinator.swift
│ │ │ ├── MainFlowView.swift
│ │ │ ├── MainFlowViewFactory.swift
│ │ │ ├── MainFlowViewModel.swift
│ │ │ └── Profile
│ │ │ │ ├── ProfileFlowView.swift
│ │ │ │ └── ProfileFlowViewModel.swift
│ │ └── Onboarding
│ │ │ ├── GetStarted
│ │ │ ├── GetStartedView.swift
│ │ │ └── GetStartedViewModel.swift
│ │ │ ├── OnboardingFlowCoordinator.swift
│ │ │ ├── OnboardingFlowView.swift
│ │ │ ├── OnboardingFlowViewFactory.swift
│ │ │ ├── OnboardingFlowViewModel.swift
│ │ │ └── Welcome
│ │ │ └── WelcomeView.swift
│ ├── FlowViewPattern.entitlements
│ ├── Info.plist
│ └── Resources
│ │ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ │ ├── Mocks
│ │ └── MockFlowCoordinator.swift
│ │ └── PreviewContent
│ │ ├── PreviewAppDependencies.swift
│ │ ├── PreviewAssets.xcassets
│ │ └── Contents.json
│ │ ├── PreviewFlowCoordinator.swift
│ │ └── PreviewFlowViewFactory.swift
└── README.md
├── FullScreenImageTransition
├── FullScreenImageTransition.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── swiftpm
│ │ └── Package.resolved
├── FullScreenImageTransition
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Base.lproj
│ │ └── LaunchScreen.storyboard
│ ├── FullScreenImageViewController.swift
│ ├── FullScreenTransitionManager.swift
│ ├── Info.plist
│ ├── Resources
│ │ └── octocats
│ │ │ ├── filmtocat.png
│ │ │ ├── goretocat.png
│ │ │ ├── jetpacktocat.png
│ │ │ ├── manufacturetocat.png
│ │ │ ├── murakamicat.png
│ │ │ ├── skatetocat.png
│ │ │ ├── spidertocat.png
│ │ │ ├── stormtroopocat.png
│ │ │ ├── swagtocat.png
│ │ │ ├── waldocat.png
│ │ │ └── welcometocat.png
│ ├── SceneDelegate.swift
│ ├── TableViewCell.swift
│ └── TableViewController.swift
└── README.md
├── GRPCFTW
├── GRPCFTWClient
│ ├── GRPCFTWClient.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── swiftpm
│ │ │ └── Package.resolved
│ ├── GRPCFTWClient
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ │ ├── AccentColor.colorset
│ │ │ │ └── Contents.json
│ │ │ ├── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ ├── Authentication
│ │ │ └── AuthenticationService.swift
│ │ ├── Base.lproj
│ │ │ └── LaunchScreen.storyboard
│ │ ├── Info.plist
│ │ ├── Networking
│ │ │ ├── ClientFactory.swift
│ │ │ ├── GRPCClient+makeStreamingCallWithRetry.swift
│ │ │ ├── GRPCClient+makeUnaryCallWithRetry.swift
│ │ │ ├── Interceptors
│ │ │ │ ├── AuthToken
│ │ │ │ │ └── AuthTokenInterceptor.swift
│ │ │ │ ├── FooServiceClientInterceptorFactory.swift
│ │ │ │ └── Logging
│ │ │ │ │ └── LoggingInterceptor.swift
│ │ │ └── Models
│ │ │ │ └── Generated
│ │ │ │ ├── bar.grpc.swift
│ │ │ │ ├── bar.pb.swift
│ │ │ │ ├── foo.grpc.swift
│ │ │ │ └── foo.pb.swift
│ │ ├── SceneDelegate.swift
│ │ ├── Services
│ │ │ └── FooService.swift
│ │ └── ViewController.swift
│ └── README.md
├── GRPCFTWProtofiles
│ ├── bar.proto
│ └── foo.proto
├── GRPCFTWServer
│ ├── GRPCFTWServer.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── swiftpm
│ │ │ └── Package.resolved
│ ├── GRPCFTWServer
│ │ ├── Networking
│ │ │ ├── DefaultBarServiceProvider.swift
│ │ │ ├── DefaultFooServiceProvider.swift
│ │ │ ├── Interceptors
│ │ │ │ ├── BarServiceServerInterceptorFactory.swift
│ │ │ │ └── Logging
│ │ │ │ │ └── LoggingInterceptor.swift
│ │ │ └── Models
│ │ │ │ └── Generated
│ │ │ │ ├── bar.grpc.swift
│ │ │ │ ├── bar.pb.swift
│ │ │ │ ├── foo.grpc.swift
│ │ │ │ └── foo.pb.swift
│ │ └── main.swift
│ └── README.md
├── README.md
├── proto-generate-client.sh
└── proto-generate-server.sh
├── HTTPAPIProblem
├── HTTPAPIProblem.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ └── contents.xcworkspacedata
├── HTTPAPIProblem
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── ContentView.swift
│ ├── HTTPAPIProblem.swift
│ ├── HTTPAPIProblemApp.swift
│ ├── OpaqueValue.swift
│ └── Preview Content
│ │ └── Preview Assets.xcassets
│ │ └── Contents.json
├── HTTPAPIProblemTests
│ └── HTTPAPIProblemTests.swift
└── README.md
├── HTTPClient
├── HTTPClient.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── swiftpm
│ │ │ └── Package.resolved
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── HTTPClient.xcscheme
├── HTTPClient
│ ├── App
│ │ ├── ContentView.swift
│ │ ├── HTTPClientApp.swift
│ │ └── ItemView.swift
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Misc
│ │ ├── PrintHTTPClientInterceptor.swift
│ │ └── URLRequest+curlRepresentation.swift
│ ├── Model
│ │ ├── ErrorBody.swift
│ │ └── Item.swift
│ ├── Networking
│ │ ├── DefaultHTTPClient.swift
│ │ ├── HTTPClient.swift
│ │ ├── HTTPClientError.swift
│ │ ├── HTTPClientInterceptor.swift
│ │ ├── HTTPMethod.swift
│ │ └── HTTPMimeType.swift
│ └── Preview Content
│ │ └── Preview Assets.xcassets
│ │ └── Contents.json
├── HTTPServer
│ ├── .gitignore
│ ├── Package.resolved
│ ├── Package.swift
│ └── Sources
│ │ └── HTTPServer
│ │ ├── configure.swift
│ │ ├── entrypoint.swift
│ │ └── routes.swift
└── README.md
├── ImprovedContainerViewController
├── ImprovedContainerViewController.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── ImprovedContainerViewController
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Base.lproj
│ │ └── LaunchScreen.storyboard
│ ├── Info.plist
│ ├── SceneDelegate.swift
│ ├── SegmentedPageController
│ │ └── SegmentedPageController.swift
│ ├── SinglePageController
│ │ └── SinglePageController.swift
│ ├── TabBarController.swift
│ └── ViewController.swift
└── README.md
├── InteractiveAnimations
├── InteractiveAnimations.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── InteractiveAnimations
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Base.lproj
│ │ └── LaunchScreen.storyboard
│ ├── BottomSheetAnimationViewController.swift
│ ├── BouncyCubeViewController.swift
│ ├── Info.plist
│ ├── RootViewController.swift
│ └── SceneDelegate.swift
└── README.md
├── KeyboardAvoidance
├── KeyboardAvoidance.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── KeyboardAvoidance
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Base.lproj
│ │ └── LaunchScreen.storyboard
│ ├── FormView.swift
│ ├── Info.plist
│ ├── KeyboardAvoidanceViewController.swift
│ ├── LongFormViewController.swift
│ ├── MediumFormViewController.swift
│ ├── RootViewController.swift
│ ├── SceneDelegate.swift
│ └── ShortFormViewController.swift
└── README.md
├── KeychainStorage
├── KeychainStorage.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── KeychainStorage
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── ContentView.swift
│ ├── ContentViewModel.swift
│ ├── KeychainStorageApp.swift
│ ├── Preview Content
│ │ └── Preview Assets.xcassets
│ │ │ └── Contents.json
│ └── SecureStorage
│ │ ├── KeychainSecureStorage.swift
│ │ └── SecureStorage.swift
└── README.md
├── LICENSE
├── LiveMockData
├── LiveMockData.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── LiveMockData
│ ├── AppDelegate.swift
│ ├── EmojiCollectionViewCell.swift
│ ├── EmojiRepository
│ │ ├── EmojiRepository.swift
│ │ └── MockEmojiRepository.swift
│ ├── EmojisViewController.swift
│ ├── Info.plist
│ ├── MockData
│ │ └── emojis.json
│ ├── Resources
│ │ ├── Assets.xcassets
│ │ │ ├── AccentColor.colorset
│ │ │ │ └── Contents.json
│ │ │ ├── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ └── Base.lproj
│ │ │ └── LaunchScreen.storyboard
│ └── SceneDelegate.swift
└── README.md
├── NetworkMonitoring
├── NetworkMonitoring.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── NetworkMonitoring
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── ContentView.swift
│ ├── ContentViewModel.swift
│ ├── NetworkMonitor.swift
│ ├── NetworkMonitoringApp.swift
│ └── Preview Content
│ │ └── Preview Assets.xcassets
│ │ └── Contents.json
└── README.md
├── OpaqueValue
├── OpaqueValue.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ └── contents.xcworkspacedata
├── OpaqueValue
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── ContentView.swift
│ ├── OpaqueValue.swift
│ ├── OpaqueValueApp.swift
│ └── Preview Content
│ │ └── Preview Assets.xcassets
│ │ └── Contents.json
├── OpaqueValueTests
│ └── OpaqueValueTests.swift
└── README.md
├── README.md
├── ResourceCache
├── README.md
├── ResourceCache.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── swiftpm
│ │ │ └── Package.resolved
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── ResourceCache.xcscheme
├── ResourceCache.xctestplan
├── ResourceCache
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── ContentView.swift
│ ├── Preview Content
│ │ └── Preview Assets.xcassets
│ │ │ └── Contents.json
│ ├── ResourceCache
│ │ ├── CancelableResourceCache.swift
│ │ └── ResourceCache.swift
│ ├── ResourceCacheApp.swift
│ └── Utils
│ │ ├── AtomicCount.swift
│ │ ├── LockedCount.swift
│ │ ├── PendingOperation.swift
│ │ ├── PendingValue.swift
│ │ └── WaitingContinuationsLocker.swift
└── ResourceCacheTests
│ ├── CancelableResourceCacheTests.swift
│ ├── PendingOperationTests.swift
│ ├── PendingValueTests.swift
│ └── ResourceCacheTests.swift
├── SharedAppAuthState
├── README.md
├── SharedAppAuthState.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── swiftpm
│ │ │ └── Package.resolved
│ └── xcshareddata
│ │ └── xcschemes
│ │ ├── SharedAppAuthState.xcscheme
│ │ ├── SharedAppAuthStateAppClip.xcscheme
│ │ ├── SharedAppAuthStateSecondApp.xcscheme
│ │ └── SharedAppAuthStateWidgetExtension.xcscheme
├── SharedAppAuthState
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ ├── 100.png
│ │ │ ├── 1024.png
│ │ │ ├── 114.png
│ │ │ ├── 120.png
│ │ │ ├── 128.png
│ │ │ ├── 144.png
│ │ │ ├── 152.png
│ │ │ ├── 16.png
│ │ │ ├── 167.png
│ │ │ ├── 172.png
│ │ │ ├── 180.png
│ │ │ ├── 196.png
│ │ │ ├── 20.png
│ │ │ ├── 216.png
│ │ │ ├── 256.png
│ │ │ ├── 29.png
│ │ │ ├── 32.png
│ │ │ ├── 40.png
│ │ │ ├── 48.png
│ │ │ ├── 50.png
│ │ │ ├── 512.png
│ │ │ ├── 55.png
│ │ │ ├── 57.png
│ │ │ ├── 58.png
│ │ │ ├── 60.png
│ │ │ ├── 64.png
│ │ │ ├── 72.png
│ │ │ ├── 76.png
│ │ │ ├── 80.png
│ │ │ ├── 87.png
│ │ │ ├── 88.png
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Auth
│ │ ├── AuthError.swift
│ │ ├── AuthService
│ │ │ ├── Auth0AuthService.swift
│ │ │ └── AuthService.swift
│ │ ├── AuthStateRepository
│ │ │ ├── AuthStateRepository.swift
│ │ │ ├── KeychainAuthStateRepository.swift
│ │ │ └── SharedUserDefaultsAuthStateRepository.swift
│ │ └── AuthTokenProvider.swift
│ ├── Base.lproj
│ │ └── LaunchScreen.storyboard
│ ├── Info.plist
│ ├── SceneDelegate.swift
│ ├── SharedAppAuthState.entitlements
│ └── ViewController.swift
├── SharedAppAuthStateAppClip
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ ├── 100.png
│ │ │ ├── 1024.png
│ │ │ ├── 114.png
│ │ │ ├── 120.png
│ │ │ ├── 128.png
│ │ │ ├── 144.png
│ │ │ ├── 152.png
│ │ │ ├── 16.png
│ │ │ ├── 167.png
│ │ │ ├── 172.png
│ │ │ ├── 180.png
│ │ │ ├── 196.png
│ │ │ ├── 20.png
│ │ │ ├── 216.png
│ │ │ ├── 256.png
│ │ │ ├── 29.png
│ │ │ ├── 32.png
│ │ │ ├── 40.png
│ │ │ ├── 48.png
│ │ │ ├── 50.png
│ │ │ ├── 512.png
│ │ │ ├── 55.png
│ │ │ ├── 57.png
│ │ │ ├── 58.png
│ │ │ ├── 60.png
│ │ │ ├── 64.png
│ │ │ ├── 72.png
│ │ │ ├── 76.png
│ │ │ ├── 80.png
│ │ │ ├── 87.png
│ │ │ ├── 88.png
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── ContentView.swift
│ ├── Info.plist
│ ├── Preview Content
│ │ └── Preview Assets.xcassets
│ │ │ └── Contents.json
│ ├── SharedAppAuthStateAppClip.entitlements
│ └── SharedAppAuthStateAppClipApp.swift
├── SharedAppAuthStateSecondApp
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ ├── 100.png
│ │ │ ├── 1024.png
│ │ │ ├── 114.png
│ │ │ ├── 120.png
│ │ │ ├── 128.png
│ │ │ ├── 144.png
│ │ │ ├── 152.png
│ │ │ ├── 16.png
│ │ │ ├── 167.png
│ │ │ ├── 172.png
│ │ │ ├── 180.png
│ │ │ ├── 196.png
│ │ │ ├── 20.png
│ │ │ ├── 216.png
│ │ │ ├── 256.png
│ │ │ ├── 29.png
│ │ │ ├── 32.png
│ │ │ ├── 40.png
│ │ │ ├── 48.png
│ │ │ ├── 50.png
│ │ │ ├── 512.png
│ │ │ ├── 55.png
│ │ │ ├── 57.png
│ │ │ ├── 58.png
│ │ │ ├── 60.png
│ │ │ ├── 64.png
│ │ │ ├── 72.png
│ │ │ ├── 76.png
│ │ │ ├── 80.png
│ │ │ ├── 87.png
│ │ │ ├── 88.png
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Auth
│ │ ├── AuthError.swift
│ │ ├── AuthService
│ │ │ ├── Auth0AuthService.swift
│ │ │ └── AuthService.swift
│ │ ├── AuthStateRepository
│ │ │ ├── AuthStateRepository.swift
│ │ │ └── KeychainAuthStateRepository.swift
│ │ └── AuthTokenProvider.swift
│ ├── Base.lproj
│ │ └── LaunchScreen.storyboard
│ ├── Info.plist
│ ├── SceneDelegate.swift
│ ├── SharedAppAuthStateSecondApp.entitlements
│ └── ViewController.swift
├── SharedAppAuthStateWidget
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ ├── 100.png
│ │ │ ├── 1024.png
│ │ │ ├── 114.png
│ │ │ ├── 120.png
│ │ │ ├── 128.png
│ │ │ ├── 144.png
│ │ │ ├── 152.png
│ │ │ ├── 16.png
│ │ │ ├── 167.png
│ │ │ ├── 172.png
│ │ │ ├── 180.png
│ │ │ ├── 196.png
│ │ │ ├── 20.png
│ │ │ ├── 216.png
│ │ │ ├── 256.png
│ │ │ ├── 29.png
│ │ │ ├── 32.png
│ │ │ ├── 40.png
│ │ │ ├── 48.png
│ │ │ ├── 50.png
│ │ │ ├── 512.png
│ │ │ ├── 55.png
│ │ │ ├── 57.png
│ │ │ ├── 58.png
│ │ │ ├── 60.png
│ │ │ ├── 64.png
│ │ │ ├── 72.png
│ │ │ ├── 76.png
│ │ │ ├── 80.png
│ │ │ ├── 87.png
│ │ │ ├── 88.png
│ │ │ └── Contents.json
│ │ ├── Contents.json
│ │ └── WidgetBackground.colorset
│ │ │ └── Contents.json
│ ├── Auth
│ │ └── WidgetAuthTokenProvider.swift
│ ├── Info.plist
│ ├── SharedAppAuthStateWidget.intentdefinition
│ └── SharedAppAuthStateWidget.swift
└── SharedAppAuthStateWidgetExtension.entitlements
├── SignalingStorage
├── README.md
├── SignalingStorage.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ └── contents.xcworkspacedata
└── SignalingStorage
│ ├── Assets.xcassets
│ ├── AccentColor.colorset
│ │ └── Contents.json
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── Contents.json
│ ├── ContentView.swift
│ ├── Defaults
│ ├── DefaultsStorage.swift
│ ├── ObservableDefaults.swift
│ └── SignalingDefaults.swift
│ ├── Keychain
│ ├── KeychainStorage.swift
│ ├── ObservableKeychain.swift
│ └── SignalingKeychain.swift
│ ├── ObservableDefaultsView.swift
│ ├── ObservableKeychainView.swift
│ ├── Preview Content
│ └── Preview Assets.xcassets
│ │ └── Contents.json
│ ├── SignalingDefaultsView.swift
│ ├── SignalingKeychainView.swift
│ └── SignalingStorageApp.swift
├── StretchyTableViewHeader
├── README.md
├── StretchyTableViewHeader.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── swiftpm
│ │ └── Package.resolved
└── StretchyTableViewHeader
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AccentColor.colorset
│ │ └── Contents.json
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Contents.json
│ └── octocats.imageset
│ │ ├── Contents.json
│ │ └── octocats.jpeg
│ ├── Base.lproj
│ └── LaunchScreen.storyboard
│ ├── FullScreenImageViewController.swift
│ ├── FullScreenTransitionManager.swift
│ ├── Info.plist
│ ├── OctocatTableHeaderView.swift
│ ├── Resources
│ └── octocats
│ │ ├── filmtocat.png
│ │ ├── goretocat.png
│ │ ├── jetpacktocat.png
│ │ ├── manufacturetocat.png
│ │ ├── murakamicat.png
│ │ ├── skatetocat.png
│ │ ├── spidertocat.png
│ │ ├── stormtroopocat.png
│ │ ├── swagtocat.png
│ │ ├── waldocat.png
│ │ └── welcometocat.png
│ ├── SceneDelegate.swift
│ ├── StretchyTableHeaderView.swift
│ ├── TableViewCell.swift
│ └── TableViewController.swift
├── SwiftUIHTML
├── README.md
├── SwiftUIHTML.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── SwiftUIHTML
│ ├── Assets.xcassets
│ ├── AccentColor.colorset
│ │ └── Contents.json
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── Contents.json
│ ├── AttributedText.swift
│ ├── ContentView.swift
│ ├── EnvironmentValues+theme.swift
│ ├── NSAttributedString+html.swift
│ ├── NSAttributedString+themedHtml.swift
│ ├── Preview Content
│ └── Preview Assets.xcassets
│ │ └── Contents.json
│ ├── SwiftUIHTMLApp.swift
│ └── UIColor+hex.swift
├── VerticalSlices
├── README.md
├── VerticalSlices.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── swiftpm
│ │ └── Package.resolved
└── VerticalSlices
│ ├── App
│ └── VerticalSlicesApp.swift
│ ├── Common
│ ├── CryptographicKeyStorage.swift
│ ├── DefaultsStorage.swift
│ ├── EnvironmentValues+DatabaseClient.swift
│ ├── EnvironmentValues+HTTPClient.swift
│ ├── FeatureToggles.swift
│ └── SecureStorage.swift
│ ├── Domain
│ └── DomainModels.swift
│ ├── Features
│ ├── Explore
│ │ └── ExploreView.swift
│ ├── Home
│ │ ├── HomeModels.swift
│ │ ├── HomeView.swift
│ │ └── Profile
│ │ │ └── ProfileView.swift
│ ├── Login
│ │ └── LoginView.swift
│ ├── More
│ │ └── MoreView.swift
│ └── RootView.swift
│ └── Resources
│ └── Assets.xcassets
│ ├── AccentColor.colorset
│ └── Contents.json
│ ├── AppIcon.appiconset
│ └── Contents.json
│ └── Contents.json
├── ViewModelHierarchy
├── README.md
├── ViewModelHierarchy.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ └── contents.xcworkspacedata
└── ViewModelHierarchy
│ ├── Actionable.swift
│ ├── Assets.xcassets
│ ├── AccentColor.colorset
│ │ └── Contents.json
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── Contents.json
│ ├── CardFlipTransition.swift
│ ├── Feature
│ ├── About
│ │ └── AboutCoordinatorView.swift
│ ├── Main
│ │ ├── Enrollment
│ │ │ └── EnrollmentCoordinatorView.swift
│ │ ├── Home
│ │ │ ├── Enroll
│ │ │ │ └── EnrollView.swift
│ │ │ ├── Home
│ │ │ │ └── HomeView.swift
│ │ │ ├── HomeCoordinatorView.swift
│ │ │ └── Profile
│ │ │ │ └── ProfileView.swift
│ │ ├── MainCoordinatorView.swift
│ │ ├── More
│ │ │ ├── Details
│ │ │ │ └── DetailsView.swift
│ │ │ ├── More
│ │ │ │ └── MoreView.swift
│ │ │ └── MoreCoordinatorView.swift
│ │ └── Settings
│ │ │ └── SettingsCoordinatorView.swift
│ └── Onboarding
│ │ └── OnboardingCoordinatorView.swift
│ ├── Hashable+extensions.swift
│ ├── Info.plist
│ ├── Preview Content
│ └── Preview Assets.xcassets
│ │ └── Contents.json
│ ├── RootCoordinatorView.swift
│ ├── ViewModelHierarchy.entitlements
│ └── ViewModelHierarchyApp.swift
└── WebSocketClient
├── README.md
├── WebSocketClient.xcodeproj
├── project.pbxproj
└── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ ├── IDEWorkspaceChecks.plist
│ └── swiftpm
│ └── Package.resolved
├── WebSocketClient
├── App
│ ├── ContentView.swift
│ ├── ItemView.swift
│ └── WebSocketClientApp.swift
├── Assets.xcassets
│ ├── AccentColor.colorset
│ │ └── Contents.json
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── Contents.json
├── Model
│ ├── IncomingMessage.swift
│ ├── Item.swift
│ └── OutgoingMessage.swift
├── Networking
│ ├── WebSocketConnection.swift
│ └── WebSocketConnectionFactory.swift
└── Preview Content
│ └── Preview Assets.xcassets
│ └── Contents.json
└── WebSocketServer
├── .gitignore
├── Package.resolved
├── Package.swift
└── Sources
└── WebSocketServer
├── configure.swift
├── entrypoint.swift
└── routes.swift
/ActionableViewModel/ActionableViewModel.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ActionableViewModel/ActionableViewModel.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ActionableViewModel/ActionableViewModel/ActionableViewModelApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ActionableViewModelApp.swift
3 | // ActionableViewModel
4 | //
5 | // Created by Thomas Asheim Smedmann on 15/06/2024.
6 | //
7 |
8 | import SwiftUI
9 |
10 | @main
11 | struct ActionableViewModelApp: App {
12 | var body: some Scene {
13 | WindowGroup {
14 | ContentView()
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/ActionableViewModel/ActionableViewModel/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/ActionableViewModel/ActionableViewModel/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ActionableViewModel/ActionableViewModel/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/ActionableViewModel/ActionableViewModel/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // ActionableViewModel
4 | //
5 | // Created by Thomas Asheim Smedmann on 15/06/2024.
6 | //
7 |
8 | import SwiftUI
9 |
10 | struct ContentView: View {
11 | var body: some View {
12 | RootCoordinatorView(
13 | viewModel: RootCoordinatorView.ViewModel { _ in }
14 | )
15 | }
16 | }
17 |
18 | #Preview {
19 | ContentView()
20 | }
21 |
--------------------------------------------------------------------------------
/ActionableViewModel/ActionableViewModel/Feature/Main/Home/Profile/ProfileView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ProfileView.swift
3 | // ActionableViewModel
4 | //
5 | // Created by Thomas Asheim Smedmann on 15/06/2024.
6 | //
7 |
8 | import SwiftUI
9 |
10 | struct ProfileView: View {
11 | var body: some View {
12 | ScrollView {
13 | Text("Profile name")
14 | .padding()
15 |
16 | Text("Profile details")
17 | .padding()
18 | }
19 | .navigationTitle("Profile")
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/ActionableViewModel/ActionableViewModel/Feature/Main/More/Details/DetailsView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DetailsView.swift
3 | // ActionableViewModel
4 | //
5 | // Created by Thomas Asheim Smedmann on 15/06/2024.
6 | //
7 |
8 | import SwiftUI
9 |
10 | struct DetailsView: View {
11 | var body: some View {
12 | ScrollView {
13 | Text("Details")
14 | .padding()
15 | }
16 | .navigationTitle("Details")
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ActionableViewModel/ActionableViewModel/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/AlternateAppIcon/AlternateAppIcon.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/AlternateAppIcon/AlternateAppIcon.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/AlternateAppIcon/AlternateAppIcon/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // AlternateAppIcon
4 | //
5 | // Created by Thomas Asheim Smedmann on 25/06/2023.
6 | //
7 |
8 | import UIKit
9 |
10 | final class AppDelegate: NSObject, UIApplicationDelegate {
11 |
12 | private(set) lazy var dependencies = DefaultDependencies()
13 |
14 | func application(
15 | _ application: UIApplication,
16 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil
17 | ) -> Bool {
18 |
19 | return true
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/AlternateAppIcon/AlternateAppIcon/Application.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Application.swift
3 | // AlternateAppIcon
4 | //
5 | // Created by Thomas Asheim Smedmann on 25/06/2023.
6 | //
7 |
8 | import UIKit
9 |
10 | protocol Application: AnyObject {
11 | var alternateIconName: String? { get }
12 | func setAlternateIconName(_ alternateIconName: String?, completionHandler: ((Error?) -> Void)?)
13 | }
14 |
15 | extension UIApplication: Application {}
16 |
--------------------------------------------------------------------------------
/AlternateAppIcon/AlternateAppIcon/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/AlternateAppIcon/AlternateAppIcon/Assets.xcassets/Blue Green.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "Icon BlueGreen.png",
5 | "idiom" : "universal",
6 | "platform" : "ios",
7 | "size" : "1024x1024"
8 | }
9 | ],
10 | "info" : {
11 | "author" : "xcode",
12 | "version" : 1
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/AlternateAppIcon/AlternateAppIcon/Assets.xcassets/Blue Green.appiconset/Icon BlueGreen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/AlternateAppIcon/AlternateAppIcon/Assets.xcassets/Blue Green.appiconset/Icon BlueGreen.png
--------------------------------------------------------------------------------
/AlternateAppIcon/AlternateAppIcon/Assets.xcassets/Blue Red.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "Icon BlueRed.png",
5 | "idiom" : "universal",
6 | "platform" : "ios",
7 | "size" : "1024x1024"
8 | }
9 | ],
10 | "info" : {
11 | "author" : "xcode",
12 | "version" : 1
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/AlternateAppIcon/AlternateAppIcon/Assets.xcassets/Blue Red.appiconset/Icon BlueRed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/AlternateAppIcon/AlternateAppIcon/Assets.xcassets/Blue Red.appiconset/Icon BlueRed.png
--------------------------------------------------------------------------------
/AlternateAppIcon/AlternateAppIcon/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/AlternateAppIcon/AlternateAppIcon/Assets.xcassets/Green Red.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "Icon GreenRed.png",
5 | "idiom" : "universal",
6 | "platform" : "ios",
7 | "size" : "1024x1024"
8 | }
9 | ],
10 | "info" : {
11 | "author" : "xcode",
12 | "version" : 1
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/AlternateAppIcon/AlternateAppIcon/Assets.xcassets/Green Red.appiconset/Icon GreenRed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/AlternateAppIcon/AlternateAppIcon/Assets.xcassets/Green Red.appiconset/Icon GreenRed.png
--------------------------------------------------------------------------------
/AlternateAppIcon/AlternateAppIcon/Assets.xcassets/Red Blue.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "Icon RedBlue.png",
5 | "idiom" : "universal",
6 | "platform" : "ios",
7 | "size" : "1024x1024"
8 | }
9 | ],
10 | "info" : {
11 | "author" : "xcode",
12 | "version" : 1
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/AlternateAppIcon/AlternateAppIcon/Assets.xcassets/Red Blue.appiconset/Icon RedBlue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/AlternateAppIcon/AlternateAppIcon/Assets.xcassets/Red Blue.appiconset/Icon RedBlue.png
--------------------------------------------------------------------------------
/AlternateAppIcon/AlternateAppIcon/Preview Content/MockAppInfoProvider.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MockAppInfoProvider.swift
3 | // AlternateAppIcon
4 | //
5 | // Created by Thomas Asheim Smedmann on 25/06/2023.
6 | //
7 |
8 | import Foundation
9 |
10 | final class MockAppInfoProvider: AppInfoProvider {
11 | var bundleName: String = ""
12 | var bundleDisplayName: String = ""
13 | var bundleIdentifier: String = ""
14 | var bundleShortVersionString: String = ""
15 | var bundleVersion: String = ""
16 | var primaryAppIconName: String = ""
17 | var alternateAppIconNames: [String] = []
18 | }
19 |
--------------------------------------------------------------------------------
/AlternateAppIcon/AlternateAppIcon/Preview Content/MockApplication.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MockApplication.swift
3 | // AlternateAppIcon
4 | //
5 | // Created by Thomas Asheim Smedmann on 25/06/2023.
6 | //
7 |
8 | import Foundation
9 |
10 | final class MockApplication: Application {
11 | var alternateIconName: String? = nil
12 |
13 | func setAlternateIconName(_ alternateIconName: String?, completionHandler: ((Error?) -> Void)?) {
14 | completionHandler?(nil)
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/AlternateAppIcon/AlternateAppIcon/Preview Content/MockDependencies.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MockDependencies.swift
3 | // AlternateAppIcon
4 | //
5 | // Created by Thomas Asheim Smedmann on 25/06/2023.
6 | //
7 |
8 | import Foundation
9 |
10 | final class MockDependencies: Dependencies {
11 | let application: Application = MockApplication()
12 | let appInfoProvider: AppInfoProvider = MockAppInfoProvider()
13 |
14 | private init() {}
15 | }
16 |
17 | extension MockDependencies {
18 | static let shared = MockDependencies()
19 | }
20 |
--------------------------------------------------------------------------------
/AlternateAppIcon/AlternateAppIcon/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/AlternateAppIcon/README.md:
--------------------------------------------------------------------------------
1 | # Dynamically alternate/change app icon
2 |
3 | A simple example (in SwiftUI) on how to dynamically change the App Icon of you app. Perfect if you want to give your users a little extra when it come to personalisation of your app!
4 |
--------------------------------------------------------------------------------
/BLEChat/BLEChat.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/BLEChat/BLEChat.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/BLEChat/BLEChat.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved:
--------------------------------------------------------------------------------
1 | {
2 | "object": {
3 | "pins": [
4 | {
5 | "package": "TinyConstraints",
6 | "repositoryURL": "git@github.com:roberthein/TinyConstraints.git",
7 | "state": {
8 | "branch": null,
9 | "revision": "3262e5c591d4ab6272255df2087a01bbebd138dc",
10 | "version": "4.0.2"
11 | }
12 | }
13 | ]
14 | },
15 | "version": 1
16 | }
17 |
--------------------------------------------------------------------------------
/BLEChat/BLEChat/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/BLEChat/BLEChat/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/BLEChat/BLEChat/Bluetooth/BluetoothError.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BluetoothError.swift
3 | // BLEChat
4 | //
5 | // Created by Thomas Asheim Smedmann on 18/01/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | enum BluetoothError: Error {
11 | case invalidState
12 | case unknownPeripheral
13 | case connectionFailure
14 | }
15 |
--------------------------------------------------------------------------------
/BLEChat/BLEChat/Dependencies.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Dependencies.swift
3 | // BLEChat
4 | //
5 | // Created by Thomas Asheim Smedmann on 14/01/2022.
6 | //
7 |
8 | import Foundation
9 | import UIKit
10 |
11 | enum Dependencies {
12 | static let chatHostScanner: ChatHostScanner = CoreBluetoothChatHostScanner()
13 | static let chatHost: ChatHost = CoreBluetoothChatHost(chatBroadcastingName: UIDevice.current.name)
14 | }
15 |
--------------------------------------------------------------------------------
/BLEChat/BLEChat/Features/Shared/ChatSection.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ChatSection.swift
3 | // BLEChat
4 | //
5 | // Created by Thomas Asheim Smedmann on 17/04/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | struct ChatSection {
11 | let title: String
12 | var messages: [ChatBubbleMessage]
13 | }
14 |
--------------------------------------------------------------------------------
/BackgroundCleanup/BackgroundCleanup.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/BackgroundCleanup/BackgroundCleanup.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/BackgroundCleanup/BackgroundCleanup/App/AppDependencies.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDependencies.swift
3 | // BackgroundCleanup
4 | //
5 | // Created by Thomas Asheim Smedmann on 17/07/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | protocol AppDependencies: AnyObject {
11 | var application: Application { get }
12 | var itemRepository: ItemRepository { get }
13 | var refreshService: RefreshService { get }
14 | var cleanupService: CleanupService { get }
15 | }
16 |
--------------------------------------------------------------------------------
/BackgroundCleanup/BackgroundCleanup/App/UIApplication+Application.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Application.swift
3 | // BackgroundCleanup
4 | //
5 | // Created by Thomas Asheim Smedmann on 17/07/2022.
6 | //
7 |
8 | import UIKit
9 |
10 | protocol Application: AnyObject {
11 | func beginBackgroundTask(expirationHandler handler: (() -> Void)?) -> UIBackgroundTaskIdentifier
12 | func endBackgroundTask(_ identifier: UIBackgroundTaskIdentifier)
13 | }
14 |
15 | extension UIApplication: Application { }
16 |
--------------------------------------------------------------------------------
/BackgroundCleanup/BackgroundCleanup/Common/Models/Item.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Item.swift
3 | // BackgroundCleanup
4 | //
5 | // Created by Thomas Asheim Smedmann on 16/07/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | struct Item: Codable {
11 | let text: String
12 | let timestamp: Date
13 | }
14 |
--------------------------------------------------------------------------------
/BackgroundCleanup/BackgroundCleanup/Resources/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/BackgroundCleanup/BackgroundCleanup/Resources/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/BottomSheetController/BottomSheetController.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/BottomSheetController/BottomSheetController.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/BottomSheetController/BottomSheetController/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/BottomSheetController/BottomSheetController/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/BottomSheetController/README.md:
--------------------------------------------------------------------------------
1 | # Dynamic sized bottom sheet controller
2 |
3 | Check out [Custom dynamic sized bottom sheet (iOS)](https://medium.com/@thomsmed/custom-dynamic-sized-bottom-sheet-ios-fbae44485255)!
4 |
--------------------------------------------------------------------------------
/BuildConfigurations/BuildConfigurations.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/BuildConfigurations/BuildConfigurations.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/BuildConfigurations/BuildConfigurations/Flavours/Develop/ConstantsDevelop.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Constants.swift
3 | // BuildConfigurations
4 | //
5 | // Created by Thomas Asheim Smedmann on 04/11/2022.
6 | //
7 | #if FLAVOUR_DEVELOP
8 | import Foundation
9 |
10 | enum Constants {
11 | static let hello = "Hello from the Develop flavour"
12 | }
13 | #endif
14 |
--------------------------------------------------------------------------------
/BuildConfigurations/BuildConfigurations/Flavours/Develop/Properties.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SomeProperty
6 | Some property value for Develop
7 |
8 |
9 |
--------------------------------------------------------------------------------
/BuildConfigurations/BuildConfigurations/Flavours/Prod/ConstantsProd.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Constants.swift
3 | // BuildConfigurations
4 | //
5 | // Created by Thomas Asheim Smedmann on 04/11/2022.
6 | //
7 | #if FLAVOUR_PROD
8 | import Foundation
9 |
10 | enum Constants {
11 | static let hello = "Hello from the Prod flavour"
12 | }
13 | #endif
14 |
--------------------------------------------------------------------------------
/BuildConfigurations/BuildConfigurations/Flavours/Prod/Properties.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SomeProperty
6 | Some property value for Prod
7 |
8 |
9 |
--------------------------------------------------------------------------------
/BuildConfigurations/BuildConfigurations/Flavours/Properties.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SomeProperty
6 | Some property value for Develop
7 |
8 |
9 |
--------------------------------------------------------------------------------
/BuildConfigurations/BuildConfigurations/Flavours/Test/ConstantsTest.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Constant.swift
3 | // BuildConfigurations
4 | //
5 | // Created by Thomas Asheim Smedmann on 04/11/2022.
6 | //
7 | #if FLAVOUR_TEST
8 | import Foundation
9 |
10 | enum Constants {
11 | static let hello = "Hello from the Test flavour"
12 | }
13 | #endif
14 |
--------------------------------------------------------------------------------
/BuildConfigurations/BuildConfigurations/Flavours/Test/Properties.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SomeProperty
6 | Some property value for Test
7 |
8 |
9 |
--------------------------------------------------------------------------------
/BuildConfigurations/BuildConfigurations/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/BuildConfigurations/BuildConfigurations/Resources/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/BuildConfigurations/BuildConfigurations/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/BuildConfigurations/BuildConfigurations/Resources/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/ConsecutiveTabTaps/ConsecutiveTabTaps.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ConsecutiveTabTaps/ConsecutiveTabTaps.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ConsecutiveTabTaps/ConsecutiveTabTaps/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/ConsecutiveTabTaps/ConsecutiveTabTaps/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ConsecutiveTabTaps/ConsecutiveTabTaps/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/ConsecutiveTabTaps/ConsecutiveTabTaps/ConsecutiveTabTapsApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ConsecutiveTabTapsApp.swift
3 | // ConsecutiveTabTaps
4 | //
5 | // Created by Thomas Asheim Smedmann on 27/08/2022.
6 | //
7 |
8 | import SwiftUI
9 |
10 | @main
11 | struct ConsecutiveTabTapsApp: App {
12 | var body: some Scene {
13 | WindowGroup {
14 | MainView(viewModel: MainViewModel())
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/ConsecutiveTabTaps/ConsecutiveTabTaps/Countries/Country.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Country.swift
3 | // ConsecutiveTabTaps
4 | //
5 | // Created by Thomas Asheim Smedmann on 27/08/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | struct Country: Identifiable, Hashable {
11 | var id: String
12 | let emojiFlag: String?
13 | }
14 |
--------------------------------------------------------------------------------
/ConsecutiveTabTaps/ConsecutiveTabTaps/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/ConsecutiveTabTaps/README.md:
--------------------------------------------------------------------------------
1 | # Handle consecutive taps on a tab in a TabView
2 |
3 | An example on how to utilise consecutive taps on a tab in a TabView. Consecutive taps on the same tab will make a NavigationStack pop to its root View, and a ScrollView scroll to its first item.
4 |
--------------------------------------------------------------------------------
/ContainerViewController/ContainerViewController.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ContainerViewController/ContainerViewController.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ContainerViewController/ContainerViewController.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved:
--------------------------------------------------------------------------------
1 | {
2 | "object": {
3 | "pins": [
4 | {
5 | "package": "Cartography",
6 | "repositoryURL": "https://github.com/robb/Cartography",
7 | "state": {
8 | "branch": null,
9 | "revision": "b75197ea134f42b5feafb04b526b37eb1a41034b",
10 | "version": "4.0.0"
11 | }
12 | }
13 | ]
14 | },
15 | "version": 1
16 | }
17 |
--------------------------------------------------------------------------------
/ContainerViewController/ContainerViewController/App/AppDependencies.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDependencies.swift
3 | // ContainerViewController
4 | //
5 | // Created by Thomas Asheim Smedmann on 02/04/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | protocol AppDependencies {
11 | // Dependencies goes here
12 | }
13 |
14 | final class DefaultAppDependencies {
15 |
16 | init() {
17 | // Do some initialisation
18 | }
19 | }
20 |
21 | extension DefaultAppDependencies: AppDependencies {
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/ContainerViewController/ContainerViewController/Resources/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/ContainerViewController/ContainerViewController/Resources/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/ContainerViewController/README.md:
--------------------------------------------------------------------------------
1 | # Custom Container View Controller
2 |
3 | Check out [Swap root view controllers using a custom container view controller](https://medium.com/@thomsmed/swap-root-view-controllers-using-a-custom-container-view-controller-fae93f5ad2c0)!
4 |
--------------------------------------------------------------------------------
/CustomInterfaceBuilderView/CustomInterfaceBuilderView.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/CustomInterfaceBuilderView/CustomInterfaceBuilderView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/CustomInterfaceBuilderView/CustomInterfaceBuilderView/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/CustomInterfaceBuilderView/CustomInterfaceBuilderView/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/CustomInterfaceBuilderView/CustomInterfaceBuilderView/CircularView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CircleView.swift
3 | // CustomInterfaceBuilderView
4 | //
5 | // Created by Thomas Asheim Smedmann on 10/09/2021.
6 | //
7 |
8 | import UIKit
9 |
10 | @IBDesignable
11 | class CircularView: UIView {
12 | override func layoutSubviews() {
13 | super.layoutSubviews()
14 | layer.cornerRadius = CGFloat(min(bounds.width / 2, bounds.height / 2))
15 | layer.masksToBounds = true
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/CustomInterfaceBuilderView/README.md:
--------------------------------------------------------------------------------
1 | # Custom Interface Builder View
2 |
3 | A simple example to showcase the use of [@IBDesignable and @IBInspectable](https://nshipster.com/ibinspectable-ibdesignable/) to build your own custom Interface Builder View.
4 |
--------------------------------------------------------------------------------
/CustomPresentationController/CustomPresentationController.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/CustomPresentationController/CustomPresentationController.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/CustomPresentationController/CustomPresentationController/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/CustomPresentationController/CustomPresentationController/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/CustomPresentationController/CustomPresentationController/Assets.xcassets/fruit.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "fruit.jpeg",
5 | "idiom" : "universal"
6 | }
7 | ],
8 | "info" : {
9 | "author" : "xcode",
10 | "version" : 1
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/CustomPresentationController/CustomPresentationController/Assets.xcassets/fruit.imageset/fruit.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/CustomPresentationController/CustomPresentationController/Assets.xcassets/fruit.imageset/fruit.jpeg
--------------------------------------------------------------------------------
/CustomPresentationController/README.md:
--------------------------------------------------------------------------------
1 | # Custom Presentation Controller
2 |
3 | A simple example on how to create your very own [UIPresentationController](https://developer.apple.com/documentation/uikit/uipresentationcontroller).
4 |
--------------------------------------------------------------------------------
/DialogController/DialogController.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/DialogController/DialogController.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/DialogController/DialogController/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/DialogController/DialogController/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/DialogController/README.md:
--------------------------------------------------------------------------------
1 | # Dynamic sized dialog controller
2 |
3 | Check out [Custom dynamic sized dialog (iOS)](https://medium.com/@thomsmed/custom-dynamic-sized-dialog-ios-84a6e2a2774d)!
4 |
--------------------------------------------------------------------------------
/DynamicAnimations/DynamicAnimations.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/DynamicAnimations/DynamicAnimations.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/DynamicAnimations/DynamicAnimations/Resources/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/DynamicAnimations/DynamicAnimations/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/DynamicAnimations/DynamicAnimations/Resources/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/DynamicAnimations/README.md:
--------------------------------------------------------------------------------
1 | # Dynamic Animations with UIDynamicAnimator
2 |
3 | This sample app showcase how to use the awesome UIDynamicAnimator to drive dynamic and physics based animations.
4 | The UIDynamicAnimator has a variety of UIDynamicBehaviors that can be added and combined for various effects. A lot of the properties of these UIDynamicBehaviors can also be changed dynamically while the animator is running!
5 |
--------------------------------------------------------------------------------
/DynamicTableHeaderView/DynamicTableHeaderView.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/DynamicTableHeaderView/DynamicTableHeaderView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/DynamicTableHeaderView/DynamicTableHeaderView/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/DynamicTableHeaderView/DynamicTableHeaderView/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/DynamicTableHeaderView/DynamicTableHeaderView/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/DynamicTableHeaderView/DynamicTableHeaderView/Assets.xcassets/episode3.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "episode3.png",
5 | "idiom" : "universal"
6 | }
7 | ],
8 | "info" : {
9 | "author" : "xcode",
10 | "version" : 1
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/DynamicTableHeaderView/DynamicTableHeaderView/Assets.xcassets/episode3.imageset/episode3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/DynamicTableHeaderView/DynamicTableHeaderView/Assets.xcassets/episode3.imageset/episode3.png
--------------------------------------------------------------------------------
/DynamicTableHeaderView/DynamicTableHeaderView/Assets.xcassets/episode4.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "episode4.png",
5 | "idiom" : "universal"
6 | }
7 | ],
8 | "info" : {
9 | "author" : "xcode",
10 | "version" : 1
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/DynamicTableHeaderView/DynamicTableHeaderView/Assets.xcassets/episode4.imageset/episode4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/DynamicTableHeaderView/DynamicTableHeaderView/Assets.xcassets/episode4.imageset/episode4.png
--------------------------------------------------------------------------------
/DynamicTableHeaderView/DynamicTableHeaderView/Assets.xcassets/episode5.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "episode5.png",
5 | "idiom" : "universal"
6 | }
7 | ],
8 | "info" : {
9 | "author" : "xcode",
10 | "version" : 1
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/DynamicTableHeaderView/DynamicTableHeaderView/Assets.xcassets/episode5.imageset/episode5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/DynamicTableHeaderView/DynamicTableHeaderView/Assets.xcassets/episode5.imageset/episode5.png
--------------------------------------------------------------------------------
/DynamicTableHeaderView/DynamicTableHeaderView/Assets.xcassets/episode6.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "episode6.png",
5 | "idiom" : "universal"
6 | }
7 | ],
8 | "info" : {
9 | "author" : "xcode",
10 | "version" : 1
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/DynamicTableHeaderView/DynamicTableHeaderView/Assets.xcassets/episode6.imageset/episode6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/DynamicTableHeaderView/DynamicTableHeaderView/Assets.xcassets/episode6.imageset/episode6.png
--------------------------------------------------------------------------------
/DynamicTableHeaderView/DynamicTableHeaderView/Assets.xcassets/episode7.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "episode7.png",
5 | "idiom" : "universal"
6 | }
7 | ],
8 | "info" : {
9 | "author" : "xcode",
10 | "version" : 1
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/DynamicTableHeaderView/DynamicTableHeaderView/Assets.xcassets/episode7.imageset/episode7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/DynamicTableHeaderView/DynamicTableHeaderView/Assets.xcassets/episode7.imageset/episode7.png
--------------------------------------------------------------------------------
/DynamicTableHeaderView/DynamicTableHeaderView/Assets.xcassets/episode8.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "episode8.png",
5 | "idiom" : "universal"
6 | }
7 | ],
8 | "info" : {
9 | "author" : "xcode",
10 | "version" : 1
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/DynamicTableHeaderView/DynamicTableHeaderView/Assets.xcassets/episode8.imageset/episode8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/DynamicTableHeaderView/DynamicTableHeaderView/Assets.xcassets/episode8.imageset/episode8.png
--------------------------------------------------------------------------------
/DynamicTableHeaderView/DynamicTableHeaderView/Assets.xcassets/episode9.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "episode9.png",
5 | "idiom" : "universal"
6 | }
7 | ],
8 | "info" : {
9 | "author" : "xcode",
10 | "version" : 1
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/DynamicTableHeaderView/DynamicTableHeaderView/Assets.xcassets/episode9.imageset/episode9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/DynamicTableHeaderView/DynamicTableHeaderView/Assets.xcassets/episode9.imageset/episode9.png
--------------------------------------------------------------------------------
/DynamicTableHeaderView/DynamicTableHeaderView/Assets.xcassets/luke.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "luke.png",
5 | "idiom" : "universal"
6 | }
7 | ],
8 | "info" : {
9 | "author" : "xcode",
10 | "version" : 1
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/DynamicTableHeaderView/DynamicTableHeaderView/Assets.xcassets/luke.imageset/luke.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/DynamicTableHeaderView/DynamicTableHeaderView/Assets.xcassets/luke.imageset/luke.png
--------------------------------------------------------------------------------
/ErrorResponder/ErrorResponder.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ErrorResponder/ErrorResponder/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/ErrorResponder/ErrorResponder/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/ErrorResponder/ErrorResponder/Feature/CommonError.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CommonError.swift
3 | // ErrorResponder
4 | //
5 | // Created by Thomas Asheim Smedmann on 15/09/2024.
6 | //
7 |
8 | import Foundation
9 |
10 | public enum CommonError: Error {
11 | case networkTrouble
12 | case sessionExpired
13 | case blocked
14 | }
15 |
--------------------------------------------------------------------------------
/ErrorResponder/ErrorResponder/Feature/FeatureOne/FeatureOneError.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FeatureOneError.swift
3 | // ErrorResponder
4 | //
5 | // Created by Thomas Asheim Smedmann on 15/09/2024.
6 | //
7 |
8 | import Foundation
9 |
10 | enum FeatureOneError: Error {
11 | case blocked
12 | case common(CommonError)
13 | }
14 |
--------------------------------------------------------------------------------
/ErrorResponder/ErrorResponder/Feature/FeatureOne/PageOne/PageOneFeatureOneError.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PageOneFeatureOneError.swift
3 | // ErrorResponder
4 | //
5 | // Created by Thomas Asheim Smedmann on 15/09/2024.
6 | //
7 |
8 | import Foundation
9 |
10 | enum PageOneFeatureOneError: Error {
11 | case wrongInput
12 | case needsConfirmation
13 | case feature(FeatureOneError)
14 | case common(CommonError)
15 | }
16 |
--------------------------------------------------------------------------------
/ErrorResponder/ErrorResponder/Feature/FeatureTwo/FeatureTwoError.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FeatureTwoError.swift
3 | // ErrorResponder
4 | //
5 | // Created by Thomas Asheim Smedmann on 15/09/2024.
6 | //
7 |
8 | import Foundation
9 |
10 | enum FeatureTwoError: Error {
11 | case blocked
12 | case common(CommonError)
13 | }
14 |
--------------------------------------------------------------------------------
/ErrorResponder/ErrorResponder/Feature/FeatureTwo/PageOne/PageOneFeatureTwoError.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PageOneFeatureTwoError.swift
3 | // ErrorResponder
4 | //
5 | // Created by Thomas Asheim Smedmann on 15/09/2024.
6 | //
7 |
8 | import Foundation
9 |
10 | enum PageOneFeatureTwoError: Error {
11 | case wrongInput
12 | case needsConfirmation
13 | case feature(FeatureTwoError)
14 | case common(CommonError)
15 | }
16 |
--------------------------------------------------------------------------------
/ErrorResponder/ErrorResponder/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/ExpandableTableViewCell/ExpandableTableViewCell.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ExpandableTableViewCell/ExpandableTableViewCell.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ExpandableTableViewCell/ExpandableTableViewCell/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/ExpandableTableViewCell/ExpandableTableViewCell/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/ExpandableTableViewCell/ExpandableTableViewCell/ExpandableTableViewCellDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ExpandableTableViewCellDelegate.swift
3 | // ExpandableTableViewCell
4 | //
5 | // Created by Thomas Asheim Smedmann on 05/08/2022.
6 | //
7 |
8 | import UIKit
9 |
10 | protocol ExpandableTableViewCellDelegate: AnyObject {
11 | func expandableTableViewCell(_ tableViewCell: UITableViewCell, expanded: Bool)
12 | }
13 |
--------------------------------------------------------------------------------
/ExtendedSplashScreen/ExtendedSplashScreen.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ExtendedSplashScreen/ExtendedSplashScreen.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ExtendedSplashScreen/ExtendedSplashScreen/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/ExtendedSplashScreen/ExtendedSplashScreen/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ExtendedSplashScreen/ExtendedSplashScreen/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/ExtendedSplashScreen/README.md:
--------------------------------------------------------------------------------
1 | # Extended Splash Screen on App startup
2 |
3 | Perfect when you need to do some initial checks before you can let the user start using the app.
4 |
5 | And definitely a better option than just blocking main thread on app start up.
6 |
--------------------------------------------------------------------------------
/FeatureModules/CoreKit/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | /.build
3 | /Packages
4 | /*.xcodeproj
5 | xcuserdata/
6 | DerivedData/
7 | .swiftpm/config/registries.json
8 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
9 | .netrc
10 |
--------------------------------------------------------------------------------
/FeatureModules/CoreKit/README.md:
--------------------------------------------------------------------------------
1 | # CoreKit
2 |
3 | Some package containing core features and utilities of the app.
4 |
--------------------------------------------------------------------------------
/FeatureModules/CoreKit/Sources/CoreKit/Coordinator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Coordinator.swift
3 | //
4 | //
5 | // Created by Thomas Asheim Smedmann on 20/11/2022.
6 | //
7 |
8 | import UIKit
9 |
10 | public protocol Coordinator: AnyObject {
11 | var navigationController: UINavigationController { get set }
12 | var childCoordinators: [Coordinator] { get set }
13 |
14 | func start()
15 | }
16 |
17 | public extension Coordinator {
18 | func removeChildCoordinator(_ coordinator: Coordinator) {
19 | childCoordinators.removeAll(where: { $0 === coordinator })
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/FeatureModules/FeatureModules.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/FeatureModules/FeatureModules.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/FeatureModules/FeatureModules/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/FeatureModules/FeatureModules/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/FeatureModules/FeatureModules/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/FeatureModules/FeatureOneKit/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | /.build
3 | /Packages
4 | /*.xcodeproj
5 | xcuserdata/
6 | DerivedData/
7 | .swiftpm/config/registries.json
8 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
9 | .netrc
10 |
--------------------------------------------------------------------------------
/FeatureModules/FeatureOneKit/README.md:
--------------------------------------------------------------------------------
1 | # FeatureOneKit
2 |
3 | Some package containing everything related to Feature One. The feature is exposed via a selected protocols and types - like a root Coordinator implementation, a CoordinatorDelegate protocol and configuration structs.
4 |
--------------------------------------------------------------------------------
/FeatureModules/FeatureThreeKit/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | /.build
3 | /Packages
4 | /*.xcodeproj
5 | xcuserdata/
6 | DerivedData/
7 | .swiftpm/config/registries.json
8 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
9 | .netrc
10 |
--------------------------------------------------------------------------------
/FeatureModules/FeatureThreeKit/README.md:
--------------------------------------------------------------------------------
1 | # FeatureThreeKit
2 |
3 | Some package containing everything related to Feature Three. The feature is exposed via a selected protocols and types - like a root Coordinator implementation, a CoordinatorDelegate protocol and configuration structs.
4 |
--------------------------------------------------------------------------------
/FeatureModules/FeatureThreeKit/Sources/FeatureThreeKit/CustomNavigationController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CustomNavigationController.swift
3 | //
4 | //
5 | // Created by Thomas Asheim Smedmann on 04/04/2023.
6 | //
7 |
8 | import UIKit
9 |
10 | final class CustomNavigationController: UINavigationController {
11 |
12 | override func viewDidLoad() {
13 | super.viewDidLoad()
14 |
15 | // Customize the custom UINavigationController
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/FeatureModules/FeatureTwoKit/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | /.build
3 | /Packages
4 | /*.xcodeproj
5 | xcuserdata/
6 | DerivedData/
7 | .swiftpm/config/registries.json
8 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
9 | .netrc
10 |
--------------------------------------------------------------------------------
/FeatureModules/FeatureTwoKit/README.md:
--------------------------------------------------------------------------------
1 | # FeatureTwoKit
2 |
3 | Some package containing everything related to Feature Two. The feature is exposed via a selected protocols and types - like a root Coordinator implementation, a CoordinatorDelegate protocol and configuration structs.
4 |
--------------------------------------------------------------------------------
/FeatureModules/README.md:
--------------------------------------------------------------------------------
1 | # Multi Module App
2 |
3 | An example on how to spread app features into multiple feature modules (Swift Packages).
4 |
5 | The Coordinator pattern is used as a navigation pattern and a way to separate responsibility (and features).
6 | Each feature module's entry point is a feature specific root Coordinator implementation. Feature "notifications"/"events" (e.g. when the feature has completed normal flow) are exposed via a CoordinatorDelegate.
7 |
--------------------------------------------------------------------------------
/FlowControllerPattern/ExamplePush.apns:
--------------------------------------------------------------------------------
1 | {
2 | "aps": {
3 | "alert" : {
4 | "title" : "Test Notification",
5 | "subtitle" : "Just a test notification",
6 | "body" : "This notification was sent to you for testing purpose"
7 | },
8 | "sound": "default",
9 | "badge": 1,
10 | "category" : "LINK"
11 | },
12 | "link": "https://www.flowcontrolpattern.com//app/primary/main/explore/store/map/1a2b/booking/checkout?service=123&product=123"
13 | }
14 |
--------------------------------------------------------------------------------
/FlowControllerPattern/FlowControllerPattern.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/FlowControllerPattern/FlowControllerPattern.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/FlowControllerPattern/FlowControllerPattern/App/AppDependencies.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDependencies.swift
3 | // FlowControllerPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 04/07/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | protocol AppDependencies: AnyObject {
11 | var analytics: AnalyticsLogger { get }
12 | var crashlytics: CrashlyticsRecorder { get }
13 | var storeService: StoreService { get }
14 | var bookingService: BookingService { get }
15 | }
16 |
--------------------------------------------------------------------------------
/FlowControllerPattern/FlowControllerPattern/App/AppFlowFactory.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppFlowFactory.swift
3 | // FlowControllerPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 13/07/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | protocol AppFlowFactory: AnyObject {
11 | func makePrimarySceneFlowHost(with flowController: AppFlowController) -> PrimarySceneFlowHost
12 | }
13 |
--------------------------------------------------------------------------------
/FlowControllerPattern/FlowControllerPattern/App/FlowControllerPattern.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | aps-environment
6 | development
7 |
8 |
9 |
--------------------------------------------------------------------------------
/FlowControllerPattern/FlowControllerPattern/Common/Models/ShoppingCart/ShoppingCart.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ShoppingCart.swift
3 | // FlowControllerPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 09/07/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | final class ShoppingCart {
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/FlowControllerPattern/FlowControllerPattern/Common/Models/Store/Store.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Store.swift
3 | // FlowControllerPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 07/07/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | struct StoreInfo: Equatable {
11 | let id: String
12 | let name: String
13 | }
14 |
15 | struct StoreDetails {
16 | let id: String
17 | let name: String
18 | let description: String
19 | }
20 |
--------------------------------------------------------------------------------
/FlowControllerPattern/FlowControllerPattern/Common/Services/Analytics/DefaultAnalyticsLogger.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DefaultAnalyticsLogger.swift
3 | // FlowControllerPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 09/07/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | final class DefaultAnalyticsLogger {
11 |
12 | }
13 |
14 | extension DefaultAnalyticsLogger: AnalyticsLogger {
15 |
16 | func log(_ event: Analytics.Event) {
17 |
18 | }
19 |
20 | func set(_ property: Analytics.Property) {
21 |
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/FlowControllerPattern/FlowControllerPattern/Common/Services/Booking/BookingService.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BookingService.swift
3 | // FlowControllerPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 09/07/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | protocol BookingService: AnyObject {
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/FlowControllerPattern/FlowControllerPattern/Common/Services/Booking/DefaultBookingService.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DefaultBookingService.swift
3 | // FlowControllerPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 09/07/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | final class DefaultBookingService {
11 |
12 | }
13 |
14 | extension DefaultBookingService: BookingService {
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/FlowControllerPattern/FlowControllerPattern/Common/Services/Crashlytics/CrashlyticsRecorder.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CrashlyticsRecorder.swift
3 | // FlowControllerPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 09/07/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | enum Crashlytics {
11 | enum Level {
12 | case info
13 | case warning
14 | case fatal
15 | }
16 | }
17 |
18 | protocol CrashlyticsRecorder {
19 | func record(_ error: Error, level: Crashlytics.Level)
20 | }
21 |
--------------------------------------------------------------------------------
/FlowControllerPattern/FlowControllerPattern/Common/Services/Crashlytics/DefaultCrashlyticsRecorder.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DefaultCrashlyticsRecorder.swift
3 | // FlowControllerPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 09/07/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | final class DefaultCrashlyticsRecorder {
11 |
12 | }
13 |
14 | extension DefaultCrashlyticsRecorder: CrashlyticsRecorder {
15 |
16 | func record(_ error: Error, level: Crashlytics.Level) {
17 |
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/FlowControllerPattern/FlowControllerPattern/Common/Services/Store/DefaultStoreService.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DefaultStoreService.swift
3 | // FlowControllerPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 09/07/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | final class DefaultStoreService {
11 |
12 | }
13 |
14 | extension DefaultStoreService: StoreService {
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/FlowControllerPattern/FlowControllerPattern/Common/Services/Store/StoreService.swift:
--------------------------------------------------------------------------------
1 | //
2 | // StoreService.swift
3 | // FlowControllerPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 09/07/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | protocol StoreService: AnyObject {
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/FlowControllerPattern/FlowControllerPattern/Resources/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/FlowControllerPattern/FlowControllerPattern/Resources/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/FlowControllerPattern/FlowControllerPattern/Scenes/Primary/Features/Main/Activity/ActivityFlowFactory.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ActivityFlowFactory.swift
3 | // FlowControllerPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 13/07/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | protocol ActivityFlowFactory: AnyObject {
11 |
12 | }
13 |
14 | extension DefaultAppFlowFactory: ActivityFlowFactory {
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/FlowControllerPattern/FlowControllerPattern/Scenes/Primary/Features/Main/Activity/ActivityFlowHost+ActivityFlowController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ActivityFlowHost+ActivityFlowController.swift
3 | // FlowControllerPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 06/07/2022.
6 | //
7 |
8 | import UIKit
9 |
10 | protocol ActivityFlowController: AnyObject {
11 |
12 | }
13 |
14 | protocol ActivityFlowHost: ActivityFlowController & UIViewController {
15 | func start(_ page: AppPage.Primary.Main.Activity)
16 | func go(to page: AppPage.Primary.Main.Activity)
17 | }
18 |
--------------------------------------------------------------------------------
/FlowControllerPattern/FlowControllerPattern/Scenes/Primary/Features/Main/Activity/Purchases/PurchasesFlowHost+PurchasesFlowController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PurchasesFlowHost+PurchasesFlowController.swift
3 | // FlowControllerPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 06/07/2022.
6 | //
7 |
8 | import UIKit
9 |
10 | protocol PurchasesFlowController: AnyObject {
11 |
12 | }
13 |
14 | protocol PurchasesFlowHost: PurchasesFlowController & UIViewController {
15 | func start(_ page: AppPage.Primary.Main.Activity.Purchases)
16 | func go(to page: AppPage.Primary.Main.Activity.Purchases)
17 | }
18 |
--------------------------------------------------------------------------------
/FlowControllerPattern/FlowControllerPattern/Scenes/Primary/Features/Main/Explore/Referral/ReferralViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ReferralViewController.swift
3 | // FlowControllerPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 06/07/2022.
6 | //
7 |
8 | import UIKit
9 |
10 | protocol ReferralViewHolder: UIViewController {
11 |
12 | }
13 |
14 | final class ReferralViewController: UIViewController {
15 |
16 | }
17 |
18 | extension ReferralViewController: ReferralViewHolder {
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/FlowControllerPattern/FlowControllerPattern/Scenes/Primary/Features/Main/Explore/Store/StoreFlowModels.swift:
--------------------------------------------------------------------------------
1 | //
2 | // StoreFlowModels.swift
3 | // FlowControllerPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 13/07/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | enum StoreFlow {
11 |
12 | struct FilterOptions {
13 | let country: String
14 | let onlyOpen: Bool
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/FlowControllerPattern/FlowControllerPattern/Scenes/Primary/Features/Main/Profile/ProfileFlowFactory.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ProfileFlowFactory.swift
3 | // FlowControllerPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 13/07/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | protocol ProfileFlowFactory: AnyObject {
11 |
12 | }
13 |
14 | extension DefaultAppFlowFactory: ProfileFlowFactory {
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/FlowControllerPattern/FlowControllerPattern/Scenes/Primary/Features/Main/Profile/ProfileFlowHost+ProfileFlowController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ProfileFlowHost+ProfileFlowController.swift
3 | // FlowControllerPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 06/07/2022.
6 | //
7 |
8 | import UIKit
9 |
10 | protocol ProfileFlowController: AnyObject {
11 |
12 | }
13 |
14 | protocol ProfileFlowHost: ProfileFlowController & UIViewController {
15 | func start(_ page: AppPage.Primary.Main.Profile)
16 | func go(to page: AppPage.Primary.Main.Profile)
17 | }
18 |
--------------------------------------------------------------------------------
/FlowViewPattern/FlowViewPattern.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/FlowViewPattern/FlowViewPattern.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/FlowViewPattern/FlowViewPattern/App/AppDependencies.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDependencies.swift
3 | // FlowViewPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 31/07/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | protocol AppDependencies: AnyObject {
11 | var defaultsRepository: DefaultsRepository { get }
12 | }
13 |
--------------------------------------------------------------------------------
/FlowViewPattern/FlowViewPattern/App/DefaultAppDependencies.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DefaultAppDependencies.swift
3 | // FlowViewPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 31/07/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | final class DefaultAppDependencies: AppDependencies {
11 |
12 | let defaultsRepository: DefaultsRepository
13 |
14 | init() {
15 | defaultsRepository = UserDefaultsDefaultsRepository()
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/FlowViewPattern/FlowViewPattern/App/DefaultAppFlowViewFactory.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DefaultAppFlowViewFactory.swift
3 | // FlowViewPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 12/08/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | final class DefaultAppFlowViewFactory {
11 |
12 | internal let appDependencies: AppDependencies
13 |
14 | init(appDependencies: AppDependencies) {
15 | self.appDependencies = appDependencies
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/FlowViewPattern/FlowViewPattern/Content/AppFlowCoordinator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppFlowCoordinator.swift
3 | // FlowViewPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 31/07/2022.
6 | //
7 |
8 | import Foundation
9 | import Combine
10 |
11 | protocol AppFlowCoordinator: AnyObject {
12 | func onboardingCompleteContinueToMain()
13 | }
14 |
15 | extension PreviewFlowCoordinator: AppFlowCoordinator {
16 | func onboardingCompleteContinueToMain() {}
17 | }
18 |
--------------------------------------------------------------------------------
/FlowViewPattern/FlowViewPattern/Content/Main/Activity/ActivityFlowCoordinator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ActivityFlowCoordinator.swift
3 | // FlowViewPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 31/07/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | protocol ActivityFlowCoordinator: AnyObject {
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/FlowViewPattern/FlowViewPattern/Content/Main/Activity/ActivityFlowViewModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ActivityFlowViewModel.swift
3 | // FlowViewPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 31/07/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | final class ActivityFlowViewModel: ObservableObject {
11 |
12 | func go(to path: AppPath.Main.Activity) {
13 |
14 | }
15 | }
16 |
17 | extension ActivityFlowViewModel: ActivityFlowCoordinator {
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/FlowViewPattern/FlowViewPattern/Content/Main/Booking/BookingFlowCoordinator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BookingFlowCoordinator.swift
3 | // FlowViewPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 31/07/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | protocol BookingFlowCoordinator: AnyObject {
11 |
12 | }
13 |
14 | extension PreviewFlowCoordinator: BookingFlowCoordinator {
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/FlowViewPattern/FlowViewPattern/Content/Main/Booking/BookingFlowViewModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BookingFlowViewModel.swift
3 | // FlowViewPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 31/07/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | final class BookingFlowViewModel: ObservableObject {
11 |
12 | }
13 |
14 | extension BookingFlowViewModel: BookingFlowCoordinator {
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/FlowViewPattern/FlowViewPattern/Content/Main/Explore/ExploreFlowCoordinator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ExploreFlowCoordinator.swift
3 | // FlowViewPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 31/07/2022.
6 | //
7 |
8 | import Foundation
9 | import Combine
10 |
11 | protocol ExploreFlowCoordinator: AnyObject {
12 | func continueToNews()
13 | func continueToBooking()
14 | }
15 |
16 | extension PreviewFlowCoordinator: ExploreFlowCoordinator {
17 | func continueToNews() {}
18 | func continueToBooking() {}
19 | }
20 |
--------------------------------------------------------------------------------
/FlowViewPattern/FlowViewPattern/Content/Main/Explore/MapAndList/MapAndListFlowCoordinator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MapAndListFlowCoordinator.swift
3 | // FlowViewPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 07/08/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | protocol MapAndListFlowCoordinator: AnyObject {
11 | func showMap()
12 | func showList()
13 | func continueToNews()
14 | func continueToBooking()
15 | }
16 |
17 | extension PreviewFlowCoordinator: MapAndListFlowCoordinator {
18 | func showMap() {}
19 | func showList() {}
20 | }
21 |
--------------------------------------------------------------------------------
/FlowViewPattern/FlowViewPattern/Content/Main/Explore/News/ExploreNewsView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ExploreNewsView.swift
3 | // FlowViewPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 07/08/2022.
6 | //
7 |
8 | import SwiftUI
9 |
10 | struct ExploreNewsView: View {
11 | var body: some View {
12 | Text("Explore news view")
13 | }
14 | }
15 |
16 | struct ExploreNewsView_Previews: PreviewProvider {
17 | static var previews: some View {
18 | ExploreNewsView()
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/FlowViewPattern/FlowViewPattern/Content/Main/MainFlowCoordinator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MainFlowCoordinator.swift
3 | // FlowViewPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 31/07/2022.
6 | //
7 |
8 | import Foundation
9 | import Combine
10 |
11 | protocol MainFlowCoordinator: AnyObject {
12 | func presentBooking()
13 | }
14 |
15 | extension PreviewFlowCoordinator: MainFlowCoordinator {
16 | func presentBooking() {}
17 | }
18 |
--------------------------------------------------------------------------------
/FlowViewPattern/FlowViewPattern/Content/Onboarding/OnboardingFlowCoordinator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // OnboardingFlowCoordinator.swift
3 | // FlowViewPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 31/07/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | protocol OnboardingFlowCoordinator: AnyObject {
11 | func onboardingComplete()
12 | }
13 |
14 | extension PreviewFlowCoordinator: OnboardingFlowCoordinator {
15 |
16 | func onboardingComplete() {
17 |
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/FlowViewPattern/FlowViewPattern/Content/Onboarding/Welcome/WelcomeView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WelcomeView.swift
3 | // FlowViewPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 13/08/2022.
6 | //
7 |
8 | import SwiftUI
9 |
10 | struct WelcomeView: View {
11 |
12 | var body: some View {
13 | VStack {
14 | Text("Welcome! 👋")
15 | }
16 | }
17 | }
18 |
19 | struct WelcomeView_Previews: PreviewProvider {
20 | static var previews: some View {
21 | WelcomeView()
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/FlowViewPattern/FlowViewPattern/FlowViewPattern.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/FlowViewPattern/FlowViewPattern/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleURLTypes
6 |
7 |
8 | CFBundleTypeRole
9 | Viewer
10 | CFBundleURLName
11 | com.thomsmed.flowviewpattern
12 | CFBundleURLSchemes
13 |
14 | flowviewpattern
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/FlowViewPattern/FlowViewPattern/Resources/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/FlowViewPattern/FlowViewPattern/Resources/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/FlowViewPattern/FlowViewPattern/Resources/Mocks/MockFlowCoordinator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MockFlowCoordinator.swift
3 | // FlowViewPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 31/07/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | final class PreviewFlowCoordinator {
11 |
12 | static let shared = PreviewFlowCoordinator()
13 |
14 | private init() {}
15 | }
16 |
--------------------------------------------------------------------------------
/FlowViewPattern/FlowViewPattern/Resources/PreviewContent/PreviewAppDependencies.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PreviewAppDependencies.swift
3 | // FlowViewPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 31/07/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | final class PreviewAppDependencies: AppDependencies {
11 |
12 | static let shared: AppDependencies = PreviewAppDependencies()
13 |
14 | let defaultsRepository: DefaultsRepository
15 |
16 | private init() {
17 | defaultsRepository = UserDefaultsDefaultsRepository()
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/FlowViewPattern/FlowViewPattern/Resources/PreviewContent/PreviewAssets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/FlowViewPattern/FlowViewPattern/Resources/PreviewContent/PreviewFlowCoordinator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PreviewFlowCoordinator.swift
3 | // FlowViewPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 31/07/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | final class PreviewFlowCoordinator {
11 |
12 | static let shared = PreviewFlowCoordinator()
13 |
14 | private init() {}
15 | }
16 |
--------------------------------------------------------------------------------
/FlowViewPattern/FlowViewPattern/Resources/PreviewContent/PreviewFlowViewFactory.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PreviewFlowViewFactory.swift
3 | // FlowViewPattern
4 | //
5 | // Created by Thomas Asheim Smedmann on 12/08/2022.
6 | //
7 |
8 | import Foundation
9 |
10 | struct PreviewFlowViewFactory {
11 |
12 | private static let appDependencies = PreviewAppDependencies.shared
13 |
14 | static let shared = DefaultAppFlowViewFactory(appDependencies: appDependencies)
15 |
16 | private init() {}
17 | }
18 |
--------------------------------------------------------------------------------
/FullScreenImageTransition/FullScreenImageTransition.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/FullScreenImageTransition/FullScreenImageTransition.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/FullScreenImageTransition/FullScreenImageTransition.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved:
--------------------------------------------------------------------------------
1 | {
2 | "object": {
3 | "pins": [
4 | {
5 | "package": "TinyConstraints",
6 | "repositoryURL": "git@github.com:roberthein/TinyConstraints.git",
7 | "state": {
8 | "branch": null,
9 | "revision": "3262e5c591d4ab6272255df2087a01bbebd138dc",
10 | "version": "4.0.2"
11 | }
12 | }
13 | ]
14 | },
15 | "version": 1
16 | }
17 |
--------------------------------------------------------------------------------
/FullScreenImageTransition/FullScreenImageTransition/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/FullScreenImageTransition/FullScreenImageTransition/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/FullScreenImageTransition/FullScreenImageTransition/Resources/octocats/filmtocat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/FullScreenImageTransition/FullScreenImageTransition/Resources/octocats/filmtocat.png
--------------------------------------------------------------------------------
/FullScreenImageTransition/FullScreenImageTransition/Resources/octocats/goretocat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/FullScreenImageTransition/FullScreenImageTransition/Resources/octocats/goretocat.png
--------------------------------------------------------------------------------
/FullScreenImageTransition/FullScreenImageTransition/Resources/octocats/jetpacktocat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/FullScreenImageTransition/FullScreenImageTransition/Resources/octocats/jetpacktocat.png
--------------------------------------------------------------------------------
/FullScreenImageTransition/FullScreenImageTransition/Resources/octocats/manufacturetocat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/FullScreenImageTransition/FullScreenImageTransition/Resources/octocats/manufacturetocat.png
--------------------------------------------------------------------------------
/FullScreenImageTransition/FullScreenImageTransition/Resources/octocats/murakamicat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/FullScreenImageTransition/FullScreenImageTransition/Resources/octocats/murakamicat.png
--------------------------------------------------------------------------------
/FullScreenImageTransition/FullScreenImageTransition/Resources/octocats/skatetocat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/FullScreenImageTransition/FullScreenImageTransition/Resources/octocats/skatetocat.png
--------------------------------------------------------------------------------
/FullScreenImageTransition/FullScreenImageTransition/Resources/octocats/spidertocat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/FullScreenImageTransition/FullScreenImageTransition/Resources/octocats/spidertocat.png
--------------------------------------------------------------------------------
/FullScreenImageTransition/FullScreenImageTransition/Resources/octocats/stormtroopocat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/FullScreenImageTransition/FullScreenImageTransition/Resources/octocats/stormtroopocat.png
--------------------------------------------------------------------------------
/FullScreenImageTransition/FullScreenImageTransition/Resources/octocats/swagtocat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/FullScreenImageTransition/FullScreenImageTransition/Resources/octocats/swagtocat.png
--------------------------------------------------------------------------------
/FullScreenImageTransition/FullScreenImageTransition/Resources/octocats/waldocat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/FullScreenImageTransition/FullScreenImageTransition/Resources/octocats/waldocat.png
--------------------------------------------------------------------------------
/FullScreenImageTransition/FullScreenImageTransition/Resources/octocats/welcometocat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/FullScreenImageTransition/FullScreenImageTransition/Resources/octocats/welcometocat.png
--------------------------------------------------------------------------------
/FullScreenImageTransition/README.md:
--------------------------------------------------------------------------------
1 | # Transition images to full screen + zoomable image and stretchy header
2 |
3 | Check out [Transition images to full screen + zoomable image](https://medium.com/@thomsmed/transition-images-to-full-screen-animated-ios-f68261489c81)!
4 |
5 | The Octocat images used in this example project was downloaded from https://octodex.github.com/.
6 |
--------------------------------------------------------------------------------
/GRPCFTW/GRPCFTWClient/GRPCFTWClient.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/GRPCFTW/GRPCFTWClient/GRPCFTWClient.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/GRPCFTW/GRPCFTWClient/GRPCFTWClient/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/GRPCFTW/GRPCFTWClient/GRPCFTWClient/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/GRPCFTW/GRPCFTWClient/GRPCFTWClient/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // GRPCFTWClient
4 | //
5 | // Created by Thomas Asheim Smedmann on 06/06/2022.
6 | //
7 |
8 | import UIKit
9 |
10 | class ViewController: UIViewController {
11 |
12 | override func viewDidLoad() {
13 | super.viewDidLoad()
14 | // Do any additional setup after loading the view.
15 | }
16 |
17 |
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/GRPCFTW/GRPCFTWClient/README.md:
--------------------------------------------------------------------------------
1 | # gRPC Swift (iOS) client
2 |
3 | ⚠️ This example project only contains some basic example code. And is meant to be used as an inspiration as is.
4 |
5 | It was used as a "playground" when writing up [5 Tips when getting started with gRPC and iOS](https://medium.com/@thomsmed/5-tips-when-getting-started-with-grpc-and-ios-9e4323bd6b98).
6 |
--------------------------------------------------------------------------------
/GRPCFTW/GRPCFTWServer/GRPCFTWServer.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/GRPCFTW/GRPCFTWServer/GRPCFTWServer.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/GRPCFTW/GRPCFTWServer/README.md:
--------------------------------------------------------------------------------
1 | # gRPC Swift server
2 |
3 | ⚠️ This example project only contains some basic example code. And is meant to be used as an inspiration as is.
4 |
5 | It was used to experiment while writing up [5 Tips when getting started with gRPC and iOS](https://medium.com/@thomsmed/5-tips-when-getting-started-with-grpc-and-ios-9e4323bd6b98).
6 |
--------------------------------------------------------------------------------
/HTTPAPIProblem/HTTPAPIProblem.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/HTTPAPIProblem/HTTPAPIProblem/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/HTTPAPIProblem/HTTPAPIProblem/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/HTTPAPIProblem/HTTPAPIProblem/HTTPAPIProblemApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HTTPAPIProblemApp.swift
3 | // HTTPAPIProblem
4 | //
5 | // Created by Thomas Smedmann on 07/01/2025.
6 | //
7 |
8 | import SwiftUI
9 |
10 | @main
11 | struct HTTPAPIProblemApp: App {
12 | var body: some Scene {
13 | WindowGroup {
14 | ContentView()
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/HTTPAPIProblem/HTTPAPIProblem/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/HTTPAPIProblem/README.md:
--------------------------------------------------------------------------------
1 | # Model and handle HTTP API Problems (RFC 9457)
2 |
3 | This example application showcase one possible way to model and handle HTTP API Problems,
4 | as defined by [RFC 9457](https://datatracker.ietf.org/doc/rfc9457/).
5 |
6 | The idea of an OpaqueValue is also touched upon. Stolen from [Representing arbitrary data (e.g JSON) as a custom and opaque Codable type](https://medium.com/@thomsmed/representing-arbitrary-data-e-g-json-as-a-custom-and-opaque-codable-type-dfaa07b22cd3).
7 |
--------------------------------------------------------------------------------
/HTTPClient/HTTPClient.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/HTTPClient/HTTPClient.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/HTTPClient/HTTPClient/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/HTTPClient/HTTPClient/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/HTTPClient/HTTPClient/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/HTTPClient/HTTPClient/Model/ErrorBody.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ErrorBody.swift
3 | // HTTPClient
4 | //
5 | // Created by Thomas Asheim Smedmann on 10/02/2024.
6 | //
7 |
8 | import Foundation
9 |
10 | struct ErrorBody: Decodable {
11 | let title: String
12 | let message: String
13 | }
14 |
--------------------------------------------------------------------------------
/HTTPClient/HTTPClient/Model/Item.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Item.swift
3 | // HTTPClient
4 | //
5 | // Created by Thomas Asheim Smedmann on 10/02/2024.
6 | //
7 |
8 | import Foundation
9 |
10 | struct Item: Codable {
11 | let id: UUID
12 | let text: String
13 | }
14 |
--------------------------------------------------------------------------------
/HTTPClient/HTTPClient/Networking/HTTPMethod.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HTTPMethod.swift
3 | // HTTPClient
4 | //
5 | // Created by Thomas Asheim Smedmann on 09/02/2024.
6 | //
7 |
8 | import Foundation
9 |
10 | /// Enumeration representing possible HTTP Request Methods.
11 | public enum HTTPMethod: String {
12 | case get = "GET"
13 | case put = "PUT"
14 | case post = "POST"
15 | case delete = "DELETE"
16 | }
17 |
--------------------------------------------------------------------------------
/HTTPClient/HTTPClient/Networking/HTTPMimeType.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HTTPMimeType.swift
3 | // HTTPClient
4 | //
5 | // Created by Thomas Asheim Smedmann on 09/02/2024.
6 | //
7 |
8 | import Foundation
9 |
10 | /// Enumeration representing possible HTTP MIME (Multipurpose Internet Mail Extensions) Types.
11 | public enum HTTPMimeType: String {
12 | case textHtml = "text/html; charset=utf-8"
13 | case applicationJson = "application/json; charset=utf-8"
14 | case applicationJoseJson = "application/jose+json; charset=utf-8"
15 | }
16 |
--------------------------------------------------------------------------------
/HTTPClient/HTTPClient/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/HTTPClient/HTTPServer/.gitignore:
--------------------------------------------------------------------------------
1 | Packages
2 | .build
3 | xcuserdata
4 | *.xcodeproj
5 | DerivedData/
6 | .DS_Store
7 | db.sqlite
8 | .swiftpm
9 | .env
10 | .env.*
11 | ! .env.example
12 | .vscode
13 |
--------------------------------------------------------------------------------
/HTTPClient/HTTPServer/Sources/HTTPServer/configure.swift:
--------------------------------------------------------------------------------
1 | import Vapor
2 |
3 | // configures your application
4 | public func configure(_ app: Application) async throws {
5 | // register routes
6 | try routes(app)
7 | }
8 |
--------------------------------------------------------------------------------
/HTTPClient/HTTPServer/Sources/HTTPServer/entrypoint.swift:
--------------------------------------------------------------------------------
1 | import Vapor
2 | import Logging
3 |
4 | @main
5 | enum Entrypoint {
6 | static func main() async throws {
7 | var env = try Environment.detect()
8 | try LoggingSystem.bootstrap(from: &env)
9 |
10 | let app = Application(env)
11 | defer { app.shutdown() }
12 |
13 | do {
14 | try await configure(app)
15 | } catch {
16 | app.logger.report(error: error)
17 | throw error
18 | }
19 | try await app.execute()
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/ImprovedContainerViewController/ImprovedContainerViewController.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ImprovedContainerViewController/ImprovedContainerViewController.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ImprovedContainerViewController/ImprovedContainerViewController/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/ImprovedContainerViewController/ImprovedContainerViewController/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/ImprovedContainerViewController/README.md:
--------------------------------------------------------------------------------
1 | # Custom Container View Controller (improved)
2 |
3 | Example on how to create a custom Container View Controller ([SinglePageController](ImprovedContainerViewController/SinglePageController/SinglePageController.swift) and [SegmentedPageViewController](ImprovedContainerViewController/SegmentedPageViewController/SegmentedPageViewController.swift)), and constraining it's children using Auto Layout Constraints.
4 |
5 | Check out [Custom Container View Controller](https://medium.com/@thomsmed/custom-container-view-controller-89123e3f2df9) for a writeup @ Medium.
6 |
--------------------------------------------------------------------------------
/InteractiveAnimations/InteractiveAnimations.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/InteractiveAnimations/InteractiveAnimations.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/InteractiveAnimations/InteractiveAnimations/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/InteractiveAnimations/InteractiveAnimations/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/InteractiveAnimations/InteractiveAnimations/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/KeyboardAvoidance/KeyboardAvoidance.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/KeyboardAvoidance/KeyboardAvoidance.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/KeyboardAvoidance/KeyboardAvoidance/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/KeyboardAvoidance/KeyboardAvoidance/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/KeyboardAvoidance/KeyboardAvoidance/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/KeyboardAvoidance/README.md:
--------------------------------------------------------------------------------
1 | # Keyboard Avoidance View Controller
2 |
3 | A basic and simple View Controller that automatically handle keyboard appearance / disappearance and makes sure content is not hidden behind the keyboard.
4 | The [KeyboardAvoidanceViewController](KeyboardAvoidance/KeyboardAvoidanceViewController.swift) View Controller is meant to be subclassed and have subviews added the its `contentView` property.
5 |
6 | Check out [Keyboard Avoidance View Controller](https://medium.com/@thomsmed/keyboard-avoidance-view-controller-c19112c6b66d)!
7 |
--------------------------------------------------------------------------------
/KeychainStorage/KeychainStorage.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/KeychainStorage/KeychainStorage.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/KeychainStorage/KeychainStorage/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/KeychainStorage/KeychainStorage/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/KeychainStorage/KeychainStorage/KeychainStorageApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // KeychainStorageApp.swift
3 | // KeychainStorage
4 | //
5 | // Created by Thomas Asheim Smedmann on 26/09/2022.
6 | //
7 |
8 | import SwiftUI
9 |
10 | @main
11 | struct KeychainStorageApp: App {
12 | var body: some Scene {
13 | WindowGroup {
14 | ContentView()
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/KeychainStorage/KeychainStorage/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/KeychainStorage/README.md:
--------------------------------------------------------------------------------
1 | # Securely store objects and values in Keychain
2 |
3 | A simple example on how to store various data types securely using the [Keychain Services API](https://developer.apple.com/documentation/security/keychain_services).
4 |
--------------------------------------------------------------------------------
/LiveMockData/LiveMockData.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/LiveMockData/LiveMockData.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/LiveMockData/LiveMockData/EmojiRepository/EmojiRepository.swift:
--------------------------------------------------------------------------------
1 | //
2 | // EmojiRepository.swift
3 | // LiveMockData
4 | //
5 | // Created by Thomas Asheim Smedmann on 28/08/2022.
6 | //
7 |
8 | import Foundation
9 | import Combine
10 |
11 | typealias Emoji = String
12 |
13 | protocol EmojiRepository {
14 | var emojis: AnyPublisher<[Emoji], Never> { get }
15 | }
16 |
--------------------------------------------------------------------------------
/LiveMockData/LiveMockData/MockData/emojis.json:
--------------------------------------------------------------------------------
1 | [
2 | "😂",
3 | "😃",
4 | "😄",
5 | "😁",
6 | "😀",
7 | "😅",
8 | "😆",
9 | "🤣"
10 | ]
11 |
--------------------------------------------------------------------------------
/LiveMockData/LiveMockData/Resources/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/LiveMockData/LiveMockData/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/LiveMockData/LiveMockData/Resources/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/LiveMockData/README.md:
--------------------------------------------------------------------------------
1 | # Live mock data
2 |
3 | An example on how to use [DispatchSource.makeFileSystemObjectSource(fileDescriptor:eventMask:queue:)](https://developer.apple.com/documentation/dispatch/dispatchsource/2300040-makefilesystemobjectsource) to monitor a file with mock data (json file in this case), so that editing file will cause a live update of the app running in a simulator.
4 |
--------------------------------------------------------------------------------
/NetworkMonitoring/NetworkMonitoring.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/NetworkMonitoring/NetworkMonitoring.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/NetworkMonitoring/NetworkMonitoring/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/NetworkMonitoring/NetworkMonitoring/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/NetworkMonitoring/NetworkMonitoring/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/NetworkMonitoring/NetworkMonitoring/NetworkMonitoringApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NetworkMonitoringApp.swift
3 | // NetworkMonitoring
4 | //
5 | // Created by Thomas Asheim Smedmann on 06/11/2022.
6 | //
7 |
8 | import SwiftUI
9 |
10 | @main
11 | struct NetworkMonitoringApp: App {
12 | var body: some Scene {
13 | WindowGroup {
14 | ContentView()
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/NetworkMonitoring/NetworkMonitoring/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/NetworkMonitoring/README.md:
--------------------------------------------------------------------------------
1 | # Network monitoring
2 |
3 | Simple network monitoring using [NWPathMonitor](https://developer.apple.com/documentation/network/nwpathmonitor).
4 |
--------------------------------------------------------------------------------
/OpaqueValue/OpaqueValue.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/OpaqueValue/OpaqueValue/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/OpaqueValue/OpaqueValue/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/OpaqueValue/OpaqueValue/OpaqueValueApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // OpaqueValueApp.swift
3 | // OpaqueValue
4 | //
5 | // Created by Thomas Asheim Smedmann on 14/07/2024.
6 | //
7 |
8 | import SwiftUI
9 |
10 | @main
11 | struct OpaqueValueApp: App {
12 | var body: some Scene {
13 | WindowGroup {
14 | ContentView()
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/OpaqueValue/OpaqueValue/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/OpaqueValue/README.md:
--------------------------------------------------------------------------------
1 | # Representing arbitrary data as an opaque Codable type
2 |
3 | This example app illustrate the concept of an opaque Codable type that can represent arbitrary (Codable) data. E.g some arbitrary JSON.
4 | The type consists of one or more primitive types and/or one or more nested opaque values.
5 |
6 | This code is heavily inspired by [Rob Napier](https://stackoverflow.com/users/97337/rob-napier)'s answer to this [StackOverflow post](https://stackoverflow.com/questions/65901928/swift-jsonencoder-encoding-class-containing-a-nested-raw-json-object-literal).
7 |
--------------------------------------------------------------------------------
/ResourceCache/ResourceCache.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ResourceCache/ResourceCache.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ResourceCache/ResourceCache.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved:
--------------------------------------------------------------------------------
1 | {
2 | "pins" : [
3 | {
4 | "identity" : "swift-atomics",
5 | "kind" : "remoteSourceControl",
6 | "location" : "https://github.com/apple/swift-atomics.git",
7 | "state" : {
8 | "revision" : "cd142fd2f64be2100422d658e7411e39489da985",
9 | "version" : "1.2.0"
10 | }
11 | }
12 | ],
13 | "version" : 2
14 | }
15 |
--------------------------------------------------------------------------------
/ResourceCache/ResourceCache.xctestplan:
--------------------------------------------------------------------------------
1 | {
2 | "configurations" : [
3 | {
4 | "id" : "A212AF8E-3A86-4AB0-A9E9-B68B18215DF7",
5 | "name" : "Configuration 1",
6 | "options" : {
7 |
8 | }
9 | }
10 | ],
11 | "defaultOptions" : {
12 |
13 | },
14 | "testTargets" : [
15 | {
16 | "target" : {
17 | "containerPath" : "container:ResourceCache.xcodeproj",
18 | "identifier" : "ED14E0822B89FC0700F9CEA4",
19 | "name" : "ResourceCacheTests"
20 | }
21 | }
22 | ],
23 | "version" : 1
24 | }
25 |
--------------------------------------------------------------------------------
/ResourceCache/ResourceCache/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/ResourceCache/ResourceCache/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ResourceCache/ResourceCache/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/ResourceCache/ResourceCache/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/ResourceCache/ResourceCache/ResourceCacheApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ResourceCacheApp.swift
3 | // ResourceCache
4 | //
5 | // Created by Thomas Asheim Smedmann on 24/02/2024.
6 | //
7 |
8 | import SwiftUI
9 |
10 | @main
11 | struct ResourceCacheApp: App {
12 | var body: some Scene {
13 | WindowGroup {
14 | ContentView()
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/SharedAppAuthState/README.md:
--------------------------------------------------------------------------------
1 | # Shared authentication state
2 |
3 | Check out [Share authentication state across your apps, App Clips and widgets](https://medium.com/@thomsmed/share-authentication-state-across-your-apps-app-clips-and-widgets-ios-e7e7f24e5525)!
4 |
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "color" : {
5 | "platform" : "universal",
6 | "reference" : "systemOrangeColor"
7 | },
8 | "idiom" : "universal"
9 | }
10 | ],
11 | "info" : {
12 | "author" : "xcode",
13 | "version" : 1
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/100.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/1024.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/114.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/114.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/120.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/128.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/144.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/152.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/16.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/167.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/167.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/172.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/172.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/180.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/196.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/196.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/20.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/216.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/216.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/256.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/29.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/32.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/40.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/48.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/50.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/50.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/512.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/55.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/55.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/57.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/58.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/58.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/60.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/64.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/72.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/76.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/80.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/80.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/87.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/87.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/88.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/AppIcon.appiconset/88.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Auth/AuthError.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AuthError.swift
3 | // SharedAppAuthState
4 | //
5 | // Created by Thomas Asheim Smedmann on 30/12/2021.
6 | //
7 |
8 | import Foundation
9 |
10 | enum AuthError: Error {
11 | case missingConfiguration
12 | case notAuthenticated
13 | case failedToPersistState
14 | }
15 |
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Auth/AuthService/AuthService.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AuthService.swift
3 | // SharedAppAuthState
4 | //
5 | // Created by Thomas Asheim Smedmann on 30/12/2021.
6 | //
7 |
8 | import Foundation
9 | import UIKit
10 | import Combine
11 |
12 | protocol AuthService: AnyObject {
13 | func login(_ completion: @escaping (Result) -> Void)
14 | func logout()
15 | var hasSignedInBefore: Bool { get }
16 | }
17 |
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Auth/AuthStateRepository/AuthStateRepository.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AuthStateRepository.swift
3 | // SharedAppAuthState
4 | //
5 | // Created by Thomas Asheim Smedmann on 30/12/2021.
6 | //
7 |
8 | import Foundation
9 | import AppAuth
10 |
11 | protocol AuthStateRepository: AnyObject {
12 | var state: OIDAuthState? { get }
13 | func persist(state: OIDAuthState) throws
14 | func clear()
15 | }
16 |
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/Auth/AuthTokenProvider.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AuthTokenProvider.swift
3 | // SharedAppAuthState
4 | //
5 | // Created by Thomas Asheim Smedmann on 30/12/2021.
6 | //
7 |
8 | import Foundation
9 |
10 | protocol AuthTokenProvider: AnyObject {
11 | func performWithFreshToken(_ action: @escaping (Result) -> Void)
12 | }
13 |
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthState/SharedAppAuthState.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.application-groups
6 |
7 | group.com.mydomain.shared
8 |
9 | keychain-access-groups
10 |
11 | $(AppIdentifierPrefix)com.mydomain.shared
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "color" : {
5 | "platform" : "universal",
6 | "reference" : "systemGreenColor"
7 | },
8 | "idiom" : "universal"
9 | }
10 | ],
11 | "info" : {
12 | "author" : "xcode",
13 | "version" : 1
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/100.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/1024.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/114.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/114.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/120.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/128.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/144.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/152.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/16.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/167.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/167.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/172.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/172.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/180.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/196.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/196.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/20.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/216.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/216.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/256.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/29.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/32.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/40.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/48.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/50.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/50.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/512.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/55.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/55.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/57.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/58.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/58.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/60.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/64.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/72.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/76.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/80.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/80.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/87.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/87.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/88.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/AppIcon.appiconset/88.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSAppClip
6 |
7 | NSAppClipRequestEphemeralUserNotification
8 |
9 | NSAppClipRequestLocationConfirmation
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/SharedAppAuthStateAppClip.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.developer.parent-application-identifiers
6 |
7 | $(AppIdentifierPrefix)ios.example.SharedAppAuthState
8 |
9 | com.apple.security.application-groups
10 |
11 | group.com.mydomain.shared
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateAppClip/SharedAppAuthStateAppClipApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SharedAppAuthStateAppClipApp.swift
3 | // SharedAppAuthStateAppClip
4 | //
5 | // Created by Thomas Asheim Smedmann on 30/12/2021.
6 | //
7 |
8 | import SwiftUI
9 |
10 | @main
11 | struct SharedAppAuthStateAppClipApp: App {
12 | var body: some Scene {
13 | WindowGroup {
14 | ContentView()
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "color" : {
5 | "platform" : "universal",
6 | "reference" : "systemPinkColor"
7 | },
8 | "idiom" : "universal"
9 | }
10 | ],
11 | "info" : {
12 | "author" : "xcode",
13 | "version" : 1
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/100.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/1024.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/114.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/114.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/120.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/128.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/144.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/152.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/16.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/167.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/167.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/172.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/172.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/180.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/196.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/196.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/20.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/216.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/216.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/256.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/29.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/32.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/40.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/48.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/50.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/50.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/512.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/55.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/55.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/57.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/58.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/58.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/60.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/64.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/72.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/76.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/80.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/80.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/87.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/87.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/88.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/AppIcon.appiconset/88.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Auth/AuthError.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AuthError.swift
3 | // SharedAppAuthState
4 | //
5 | // Created by Thomas Asheim Smedmann on 30/12/2021.
6 | //
7 |
8 | import Foundation
9 |
10 | enum AuthError: Error {
11 | case missingConfiguration
12 | case notAuthenticated
13 | case failedToPersistState
14 | }
15 |
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Auth/AuthService/AuthService.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AuthService.swift
3 | // SharedAppAuthState
4 | //
5 | // Created by Thomas Asheim Smedmann on 30/12/2021.
6 | //
7 |
8 | import Foundation
9 | import UIKit
10 | import Combine
11 |
12 | protocol AuthService: AnyObject {
13 | func login(_ completion: @escaping (Result) -> Void)
14 | func logout()
15 | var hasSignedInBefore: Bool { get }
16 | }
17 |
18 |
19 |
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Auth/AuthStateRepository/AuthStateRepository.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AuthStateRepository.swift
3 | // SharedAppAuthState
4 | //
5 | // Created by Thomas Asheim Smedmann on 30/12/2021.
6 | //
7 |
8 | import Foundation
9 | import AppAuth
10 |
11 | protocol AuthStateRepository: AnyObject {
12 | var state: OIDAuthState? { get }
13 | func persist(state: OIDAuthState) throws
14 | func clear()
15 | }
16 |
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/Auth/AuthTokenProvider.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AuthTokenProvider.swift
3 | // SharedAppAuthState
4 | //
5 | // Created by Thomas Asheim Smedmann on 30/12/2021.
6 | //
7 |
8 | import Foundation
9 |
10 | protocol AuthTokenProvider: AnyObject {
11 | func performWithFreshToken(_ action: @escaping (Result) -> Void)
12 | }
13 |
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateSecondApp/SharedAppAuthStateSecondApp.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | keychain-access-groups
6 |
7 | $(AppIdentifierPrefix)com.mydomain.shared
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/100.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/1024.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/114.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/114.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/120.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/128.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/144.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/152.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/16.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/167.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/167.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/172.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/172.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/180.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/196.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/196.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/20.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/216.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/216.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/256.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/29.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/32.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/40.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/48.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/50.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/50.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/512.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/55.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/55.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/57.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/58.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/58.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/60.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/64.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/72.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/76.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/80.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/80.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/87.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/87.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/88.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/AppIcon.appiconset/88.png
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Assets.xcassets/WidgetBackground.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidget/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSExtension
6 |
7 | NSExtensionPointIdentifier
8 | com.apple.widgetkit-extension
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/SharedAppAuthState/SharedAppAuthStateWidgetExtension.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | keychain-access-groups
6 |
7 | $(AppIdentifierPrefix)com.mydomain.shared
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/SignalingStorage/SignalingStorage.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SignalingStorage/SignalingStorage/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/SignalingStorage/SignalingStorage/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/SignalingStorage/SignalingStorage/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/SignalingStorage/SignalingStorage/SignalingStorageApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SignalingStorageApp.swift
3 | // SignalingStorage
4 | //
5 | // Created by Thomas Smedmann on 23/03/2025.
6 | //
7 |
8 | import SwiftUI
9 |
10 | @main
11 | struct SignalingStorageApp: App {
12 | var body: some Scene {
13 | WindowGroup {
14 | ContentView()
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/StretchyTableViewHeader/README.md:
--------------------------------------------------------------------------------
1 | # Stretchy table header view
2 |
3 | Check out [Stretchy table header view](https://medium.com/@thomsmed/stretchy-table-header-view-ios-635a0e95d3c5)!
4 |
5 | The Octocat images used in this example project was downloaded from https://octodex.github.com/.
6 |
--------------------------------------------------------------------------------
/StretchyTableViewHeader/StretchyTableViewHeader.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/StretchyTableViewHeader/StretchyTableViewHeader.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/StretchyTableViewHeader/StretchyTableViewHeader.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved:
--------------------------------------------------------------------------------
1 | {
2 | "object": {
3 | "pins": [
4 | {
5 | "package": "TinyConstraints",
6 | "repositoryURL": "git@github.com:roberthein/TinyConstraints.git",
7 | "state": {
8 | "branch": null,
9 | "revision": "3262e5c591d4ab6272255df2087a01bbebd138dc",
10 | "version": "4.0.2"
11 | }
12 | }
13 | ]
14 | },
15 | "version": 1
16 | }
17 |
--------------------------------------------------------------------------------
/StretchyTableViewHeader/StretchyTableViewHeader/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/StretchyTableViewHeader/StretchyTableViewHeader/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/StretchyTableViewHeader/StretchyTableViewHeader/Assets.xcassets/octocats.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "octocats.jpeg",
5 | "idiom" : "universal"
6 | }
7 | ],
8 | "info" : {
9 | "author" : "xcode",
10 | "version" : 1
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/StretchyTableViewHeader/StretchyTableViewHeader/Assets.xcassets/octocats.imageset/octocats.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/StretchyTableViewHeader/StretchyTableViewHeader/Assets.xcassets/octocats.imageset/octocats.jpeg
--------------------------------------------------------------------------------
/StretchyTableViewHeader/StretchyTableViewHeader/Resources/octocats/filmtocat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/StretchyTableViewHeader/StretchyTableViewHeader/Resources/octocats/filmtocat.png
--------------------------------------------------------------------------------
/StretchyTableViewHeader/StretchyTableViewHeader/Resources/octocats/goretocat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/StretchyTableViewHeader/StretchyTableViewHeader/Resources/octocats/goretocat.png
--------------------------------------------------------------------------------
/StretchyTableViewHeader/StretchyTableViewHeader/Resources/octocats/jetpacktocat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/StretchyTableViewHeader/StretchyTableViewHeader/Resources/octocats/jetpacktocat.png
--------------------------------------------------------------------------------
/StretchyTableViewHeader/StretchyTableViewHeader/Resources/octocats/manufacturetocat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/StretchyTableViewHeader/StretchyTableViewHeader/Resources/octocats/manufacturetocat.png
--------------------------------------------------------------------------------
/StretchyTableViewHeader/StretchyTableViewHeader/Resources/octocats/murakamicat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/StretchyTableViewHeader/StretchyTableViewHeader/Resources/octocats/murakamicat.png
--------------------------------------------------------------------------------
/StretchyTableViewHeader/StretchyTableViewHeader/Resources/octocats/skatetocat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/StretchyTableViewHeader/StretchyTableViewHeader/Resources/octocats/skatetocat.png
--------------------------------------------------------------------------------
/StretchyTableViewHeader/StretchyTableViewHeader/Resources/octocats/spidertocat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/StretchyTableViewHeader/StretchyTableViewHeader/Resources/octocats/spidertocat.png
--------------------------------------------------------------------------------
/StretchyTableViewHeader/StretchyTableViewHeader/Resources/octocats/stormtroopocat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/StretchyTableViewHeader/StretchyTableViewHeader/Resources/octocats/stormtroopocat.png
--------------------------------------------------------------------------------
/StretchyTableViewHeader/StretchyTableViewHeader/Resources/octocats/swagtocat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/StretchyTableViewHeader/StretchyTableViewHeader/Resources/octocats/swagtocat.png
--------------------------------------------------------------------------------
/StretchyTableViewHeader/StretchyTableViewHeader/Resources/octocats/waldocat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/StretchyTableViewHeader/StretchyTableViewHeader/Resources/octocats/waldocat.png
--------------------------------------------------------------------------------
/StretchyTableViewHeader/StretchyTableViewHeader/Resources/octocats/welcometocat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomsmed/ios-examples/4c4c5b6bca18d970041a8d32f2239c298317a2ad/StretchyTableViewHeader/StretchyTableViewHeader/Resources/octocats/welcometocat.png
--------------------------------------------------------------------------------
/SwiftUIHTML/SwiftUIHTML.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SwiftUIHTML/SwiftUIHTML.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/SwiftUIHTML/SwiftUIHTML/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/SwiftUIHTML/SwiftUIHTML/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/SwiftUIHTML/SwiftUIHTML/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/SwiftUIHTML/SwiftUIHTML/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/SwiftUIHTML/SwiftUIHTML/SwiftUIHTMLApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SwiftUIHTMLApp.swift
3 | // SwiftUIHTML
4 | //
5 | // Created by Thomas Asheim Smedmann on 09/07/2023.
6 | //
7 |
8 | import SwiftUI
9 |
10 | @main
11 | struct SwiftUIHTMLApp: App {
12 | var body: some Scene {
13 | WindowGroup {
14 | ContentView()
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/VerticalSlices/VerticalSlices.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/VerticalSlices/VerticalSlices/Features/Explore/ExploreView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ExploreView.swift
3 | // VerticalSlices
4 | //
5 | // Created by Thomas Smedmann on 09/11/2024.
6 | //
7 |
8 | import SwiftUI
9 |
10 | struct ExploreView: View {
11 | var body: some View {
12 | Text("Explore")
13 | }
14 | }
15 |
16 | #Preview {
17 | ExploreView()
18 | }
19 |
--------------------------------------------------------------------------------
/VerticalSlices/VerticalSlices/Features/Home/Profile/ProfileView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ProfileView.swift
3 | // VerticalSlices
4 | //
5 | // Created by Thomas Asheim Smedmann on 21/10/2024.
6 | //
7 |
8 | import SwiftUI
9 |
10 | struct ProfileView: View {
11 | var body: some View {
12 | VStack {
13 | Text("Profile")
14 | }
15 | }
16 | }
17 |
18 | #Preview {
19 | ProfileView()
20 | }
21 |
--------------------------------------------------------------------------------
/VerticalSlices/VerticalSlices/Features/Login/LoginView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LoginView.swift
3 | // VerticalSlices
4 | //
5 | // Created by Thomas Asheim Smedmann on 21/10/2024.
6 | //
7 |
8 | import SwiftUI
9 |
10 | struct LoginView: View {
11 | var body: some View {
12 | NavigationStack {
13 | VStack {
14 | Text("Login")
15 | }
16 | }
17 | }
18 | }
19 |
20 | #Preview {
21 | LoginView()
22 | }
23 |
--------------------------------------------------------------------------------
/VerticalSlices/VerticalSlices/Features/More/MoreView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MoreView.swift
3 | // VerticalSlices
4 | //
5 | // Created by Thomas Asheim Smedmann on 21/10/2024.
6 | //
7 |
8 | import SwiftUI
9 |
10 | struct MoreView: View {
11 | var body: some View {
12 | NavigationStack {
13 | VStack {
14 | Text("More")
15 | }
16 | }
17 | }
18 | }
19 |
20 | #Preview {
21 | MoreView()
22 | }
23 |
--------------------------------------------------------------------------------
/VerticalSlices/VerticalSlices/Resources/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/VerticalSlices/VerticalSlices/Resources/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/ViewModelHierarchy/ViewModelHierarchy.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ViewModelHierarchy/ViewModelHierarchy/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/ViewModelHierarchy/ViewModelHierarchy/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/ViewModelHierarchy/ViewModelHierarchy/Feature/Main/Home/Profile/ProfileView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ProfileView.swift
3 | // ViewModelHierarchy
4 | //
5 | // Created by Thomas Asheim Smedmann on 23/07/2024.
6 | //
7 |
8 | import SwiftUI
9 |
10 | struct ProfileView: View {
11 | var body: some View {
12 | ScrollView {
13 | VStack {
14 | Text("Profile name")
15 | .padding()
16 |
17 | Text("Profile details")
18 | .padding()
19 | }
20 | }
21 | .navigationTitle("Profile")
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ViewModelHierarchy/ViewModelHierarchy/Feature/Main/More/Details/DetailsView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DetailsCoordinatorView.swift
3 | // ViewModelHierarchy
4 | //
5 | // Created by Thomas Asheim Smedmann on 23/07/2024.
6 | //
7 |
8 | import SwiftUI
9 |
10 | struct DetailsView: View {
11 | var body: some View {
12 | ScrollView {
13 | VStack {
14 | Text("Details")
15 | .padding()
16 | }
17 | }
18 | .navigationTitle("Details")
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/ViewModelHierarchy/ViewModelHierarchy/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/ViewModelHierarchy/ViewModelHierarchy/ViewModelHierarchy.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.developer.associated-domains
6 |
7 | applinks:ios.example.ViewModelHierarchy?mode=developer
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/WebSocketClient/WebSocketClient.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/WebSocketClient/WebSocketClient.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/WebSocketClient/WebSocketClient/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/WebSocketClient/WebSocketClient/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/WebSocketClient/WebSocketClient/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/WebSocketClient/WebSocketClient/Model/IncomingMessage.swift:
--------------------------------------------------------------------------------
1 | //
2 | // IncomingMessage.swift
3 | // WebSocketClient
4 | //
5 | // Created by Thomas Asheim Smedmann on 17/02/2024.
6 | //
7 |
8 | import Foundation
9 |
10 | enum IncomingMessage: Decodable {
11 | case items(items: [Item])
12 | case update(item: Item)
13 | case add(item: Item)
14 | case delete(item: Item)
15 | }
16 |
--------------------------------------------------------------------------------
/WebSocketClient/WebSocketClient/Model/Item.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Item.swift
3 | // WebSocketClient
4 | //
5 | // Created by Thomas Asheim Smedmann on 13/02/2024.
6 | //
7 |
8 | import Foundation
9 |
10 | struct Item: Codable {
11 | let id: UUID
12 | let text: String
13 | }
14 |
--------------------------------------------------------------------------------
/WebSocketClient/WebSocketClient/Model/OutgoingMessage.swift:
--------------------------------------------------------------------------------
1 | //
2 | // OutgoingMessage.swift
3 | // WebSocketClient
4 | //
5 | // Created by Thomas Asheim Smedmann on 17/02/2024.
6 | //
7 |
8 | import Foundation
9 |
10 | enum OutgoingMessage: Encodable {
11 | case update(item: Item)
12 | case add(item: Item)
13 | case delete(id: UUID)
14 | }
15 |
--------------------------------------------------------------------------------
/WebSocketClient/WebSocketClient/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/WebSocketClient/WebSocketServer/.gitignore:
--------------------------------------------------------------------------------
1 | Packages
2 | .build
3 | xcuserdata
4 | *.xcodeproj
5 | DerivedData/
6 | .DS_Store
7 | db.sqlite
8 | .swiftpm
9 | .env
10 | .env.*
11 | ! .env.example
12 | .vscode
13 |
--------------------------------------------------------------------------------
/WebSocketClient/WebSocketServer/Sources/WebSocketServer/configure.swift:
--------------------------------------------------------------------------------
1 | import Vapor
2 |
3 | // configures your application
4 | public func configure(_ app: Application) async throws {
5 | // register routes
6 | try routes(app)
7 | }
8 |
--------------------------------------------------------------------------------
/WebSocketClient/WebSocketServer/Sources/WebSocketServer/entrypoint.swift:
--------------------------------------------------------------------------------
1 | import Vapor
2 | import Logging
3 |
4 | @main
5 | enum Entrypoint {
6 | static func main() async throws {
7 | var env = try Environment.detect()
8 | try LoggingSystem.bootstrap(from: &env)
9 |
10 | let app = Application(env)
11 | defer { app.shutdown() }
12 |
13 | do {
14 | try await configure(app)
15 | } catch {
16 | app.logger.report(error: error)
17 | throw error
18 | }
19 | try await app.execute()
20 | }
21 | }
22 |
--------------------------------------------------------------------------------