├── .gitignore ├── README.md ├── RandomUsers ├── README.md ├── RandomUsers.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── swiftpm │ │ └── Package.resolved ├── Shared │ ├── Assets.xcassets │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Data │ │ ├── UserModel.swift │ │ └── UsersData.swift │ ├── Extensions.swift │ ├── RandomUsersApp.swift │ ├── Resources │ │ └── randomusers.json │ ├── RootView.swift │ └── Screens │ │ ├── ShortcutsScreen.swift │ │ ├── UserDetailScreen.swift │ │ ├── UserLocationScreen.swift │ │ └── UsersScreen.swift ├── macOS │ └── macOS.entitlements └── preview.jpg ├── Swiping ├── README.md ├── Swiping.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── swiftpm │ │ └── Package.resolved ├── Swiping │ ├── Assets.xcassets │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── ContentView.swift │ ├── Extensions.swift │ ├── Preview Content │ │ └── Preview Assets.xcassets │ │ │ └── Contents.json │ └── SwipingApp.swift └── preview.gif └── TabViewRouting ├── README.md ├── Shared ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json ├── Screens.swift └── TabViewRoutingApp.swift ├── TabViewRouting.xcodeproj ├── project.pbxproj └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ ├── IDEWorkspaceChecks.plist │ └── swiftpm │ └── Package.resolved ├── iOS └── RootView.swift └── macOS ├── RootView.swift └── macOS.entitlements /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.toptal.com/developers/gitignore/api/macos,swift,xcode,swiftpm 3 | # Edit at https://www.toptal.com/developers/gitignore?templates=macos,swift,xcode,swiftpm 4 | 5 | ### macOS ### 6 | # General 7 | .DS_Store 8 | .AppleDouble 9 | .LSOverride 10 | 11 | # Icon must end with two \r 12 | Icon 13 | 14 | 15 | # Thumbnails 16 | ._* 17 | 18 | # Files that might appear in the root of a volume 19 | .DocumentRevisions-V100 20 | .fseventsd 21 | .Spotlight-V100 22 | .TemporaryItems 23 | .Trashes 24 | .VolumeIcon.icns 25 | .com.apple.timemachine.donotpresent 26 | 27 | # Directories potentially created on remote AFP share 28 | .AppleDB 29 | .AppleDesktop 30 | Network Trash Folder 31 | Temporary Items 32 | .apdisk 33 | 34 | ### Swift ### 35 | # Xcode 36 | # 37 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 38 | 39 | ## User settings 40 | xcuserdata/ 41 | 42 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 43 | *.xcscmblueprint 44 | *.xccheckout 45 | 46 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 47 | build/ 48 | DerivedData/ 49 | *.moved-aside 50 | *.pbxuser 51 | !default.pbxuser 52 | *.mode1v3 53 | !default.mode1v3 54 | *.mode2v3 55 | !default.mode2v3 56 | *.perspectivev3 57 | !default.perspectivev3 58 | 59 | ## Obj-C/Swift specific 60 | *.hmap 61 | 62 | ## App packaging 63 | *.ipa 64 | *.dSYM.zip 65 | *.dSYM 66 | 67 | ## Playgrounds 68 | timeline.xctimeline 69 | playground.xcworkspace 70 | 71 | # Swift Package Manager 72 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 73 | # Packages/ 74 | # Package.pins 75 | # Package.resolved 76 | # *.xcodeproj 77 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata 78 | # hence it is not needed unless you have added a package configuration file to your project 79 | # .swiftpm 80 | 81 | .build/ 82 | 83 | # CocoaPods 84 | # We recommend against adding the Pods directory to your .gitignore. However 85 | # you should judge for yourself, the pros and cons are mentioned at: 86 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 87 | # Pods/ 88 | # Add this line if you want to avoid checking in source code from the Xcode workspace 89 | # *.xcworkspace 90 | 91 | # Carthage 92 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 93 | # Carthage/Checkouts 94 | 95 | Carthage/Build/ 96 | 97 | # Accio dependency management 98 | Dependencies/ 99 | .accio/ 100 | 101 | # fastlane 102 | # It is recommended to not store the screenshots in the git repo. 103 | # Instead, use fastlane to re-generate the screenshots whenever they are needed. 104 | # For more information about the recommended setup visit: 105 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 106 | 107 | fastlane/report.xml 108 | fastlane/Preview.html 109 | fastlane/screenshots/**/*.png 110 | fastlane/test_output 111 | 112 | # Code Injection 113 | # After new code Injection tools there's a generated folder /iOSInjectionProject 114 | # https://github.com/johnno1962/injectionforxcode 115 | 116 | iOSInjectionProject/ 117 | 118 | ### SwiftPM ### 119 | Packages 120 | xcuserdata 121 | 122 | 123 | ### Xcode ### 124 | # Xcode 125 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 126 | 127 | 128 | 129 | 130 | ## Gcc Patch 131 | /*.gcno 132 | 133 | ### Xcode Patch ### 134 | *.xcodeproj/* 135 | !*.xcodeproj/project.pbxproj 136 | !*.xcodeproj/xcshareddata/ 137 | !*.xcworkspace/contents.xcworkspacedata 138 | **/xcshareddata/WorkspaceSettings.xcsettings 139 | 140 | # End of https://www.toptal.com/developers/gitignore/api/macos,swift,xcode,swiftpm 141 | 142 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SwiftUI Router examples 2 | 3 | [![SwiftUI](https://img.shields.io/badge/SwiftUI-blue.svg?style=for-the-badge&logo=swift&logoColor=black)](https://developer.apple.com/xcode/swiftui) 4 | [![Swift](https://img.shields.io/badge/Swift-5.5-orange.svg?style=for-the-badge&logo=swift)](https://swift.org) 5 | [![Xcode](https://img.shields.io/badge/Xcode-13-blue.svg?style=for-the-badge&logo=Xcode&logoColor=white)](https://developer.apple.com/xcode) 6 | 7 | This repository contains examples demonstrating how to utilize path-based routing using the [SwiftUI Router](https://github.com/frzi/SwiftUIRouter) library. These examples are not made to look pretty, but rather, are simplified to better showcase *SwiftUI Router*'s features as well as giving examples on how to structure your routes and code. 8 | 9 | ## The examples 10 | 11 | | Example | Platforms1,2 | Description | 12 | | ------- | ---------- | ----------- | 13 | | [RandomUsers](RandomUsers) | iOS, macOS | A simple contacts-like app with 100 randomly generated users from [randomuser.me](https://randomuser.me). It demonstrates most of the features *SwiftUI Router* has to offer, how to organize routes and being able to redirect users to different parts of the app with a single button. | 14 | | [Swiping](Swiping) | iOS | A featureless app trying to replicate iOS's swipe-to-return navigation. | 15 | | [TabView](TabViewRouting) | iOS, macOS | Example of how to combine *SwiftUI Router* and SwiftUI's builtin `TabView`. | 16 | 17 | 1 *SwiftUI Router* is available on iOS (and iPadOS), macOS, tvOS and watchOS. Due to the interest of time the examples were only made and tested on iOS and macOS. 🙇 18 | 2 All projects are made for iOS 15+ or macOS 12+. -------------------------------------------------------------------------------- /RandomUsers/README.md: -------------------------------------------------------------------------------- 1 | # RandomUsers App 2 | > A contacts-like app with randomly generated users from [randomuser.me](https://randomuser.me). 3 | 4 | ![RandomUsers App](preview.jpg) 5 | 6 | ## Documentation 7 | All important aspects and implementions are documented in the source code. Starting from [RandomUsersApp.swift](Shared/RandomUsersApp.swift), you can follow the numbered documentation to get a tour of the app's routing logic. 8 | 9 | If you are new to path-based routing and/or [SwiftUI Router](https://github.com/frzi/SwiftUIRouter) then this is a great example to discover and learn the basics. 10 | 11 | This example demonstrates: 12 | * A way to structure your routes 13 | * Route parameters (aka placeholders) 14 | * Route parameter validation and transforming 15 | * Fallback routes 16 | * Navigating with `NavLink` -------------------------------------------------------------------------------- /RandomUsers/RandomUsers.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 55; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | C0316B7C275243CF00BBE3D9 /* RandomUsersApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0316B54275243CC00BBE3D9 /* RandomUsersApp.swift */; }; 11 | C0316B7D275243CF00BBE3D9 /* RandomUsersApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0316B54275243CC00BBE3D9 /* RandomUsersApp.swift */; }; 12 | C0316B7E275243CF00BBE3D9 /* RootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0316B55275243CC00BBE3D9 /* RootView.swift */; }; 13 | C0316B7F275243CF00BBE3D9 /* RootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0316B55275243CC00BBE3D9 /* RootView.swift */; }; 14 | C0316B80275243CF00BBE3D9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C0316B56275243CE00BBE3D9 /* Assets.xcassets */; }; 15 | C0316B81275243CF00BBE3D9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C0316B56275243CE00BBE3D9 /* Assets.xcassets */; }; 16 | C0316B922752444800BBE3D9 /* randomusers.json in Resources */ = {isa = PBXBuildFile; fileRef = C0316B912752444800BBE3D9 /* randomusers.json */; }; 17 | C0316B932752444800BBE3D9 /* randomusers.json in Resources */ = {isa = PBXBuildFile; fileRef = C0316B912752444800BBE3D9 /* randomusers.json */; }; 18 | C0316B9C2752451E00BBE3D9 /* UsersData.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0316B9B2752451E00BBE3D9 /* UsersData.swift */; }; 19 | C0316B9D2752451E00BBE3D9 /* UsersData.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0316B9B2752451E00BBE3D9 /* UsersData.swift */; }; 20 | C0316B9F275245CD00BBE3D9 /* UserModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0316B9E275245CD00BBE3D9 /* UserModel.swift */; }; 21 | C0316BA0275245CD00BBE3D9 /* UserModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0316B9E275245CD00BBE3D9 /* UserModel.swift */; }; 22 | C0316BA32752491E00BBE3D9 /* UsersScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0316BA22752491E00BBE3D9 /* UsersScreen.swift */; }; 23 | C0316BA42752491E00BBE3D9 /* UsersScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0316BA22752491E00BBE3D9 /* UsersScreen.swift */; }; 24 | C0316BA627525F3800BBE3D9 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0316BA527525F3800BBE3D9 /* Extensions.swift */; }; 25 | C0316BA727525F3800BBE3D9 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0316BA527525F3800BBE3D9 /* Extensions.swift */; }; 26 | C0316BAF275263F700BBE3D9 /* UserDetailScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0316BAE275263F700BBE3D9 /* UserDetailScreen.swift */; }; 27 | C0316BB0275263F700BBE3D9 /* UserDetailScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0316BAE275263F700BBE3D9 /* UserDetailScreen.swift */; }; 28 | C0316BB22752690900BBE3D9 /* ShortcutsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0316BB12752690900BBE3D9 /* ShortcutsScreen.swift */; }; 29 | C0316BB32752690900BBE3D9 /* ShortcutsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0316BB12752690900BBE3D9 /* ShortcutsScreen.swift */; }; 30 | C0316BB5275274FC00BBE3D9 /* UserLocationScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0316BB4275274FC00BBE3D9 /* UserLocationScreen.swift */; }; 31 | C0316BB6275274FC00BBE3D9 /* UserLocationScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0316BB4275274FC00BBE3D9 /* UserLocationScreen.swift */; }; 32 | C0DAACD2275BF3DD001A4EB4 /* SwiftUIRouter in Frameworks */ = {isa = PBXBuildFile; productRef = C0DAACD1275BF3DD001A4EB4 /* SwiftUIRouter */; }; 33 | C0DAACD4275BF3E4001A4EB4 /* SwiftUIRouter in Frameworks */ = {isa = PBXBuildFile; productRef = C0DAACD3275BF3E4001A4EB4 /* SwiftUIRouter */; }; 34 | /* End PBXBuildFile section */ 35 | 36 | /* Begin PBXFileReference section */ 37 | C0316B54275243CC00BBE3D9 /* RandomUsersApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RandomUsersApp.swift; sourceTree = ""; }; 38 | C0316B55275243CC00BBE3D9 /* RootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootView.swift; sourceTree = ""; }; 39 | C0316B56275243CE00BBE3D9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 40 | C0316B5B275243CE00BBE3D9 /* RandomUsers.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RandomUsers.app; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | C0316B61275243CE00BBE3D9 /* RandomUsers.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RandomUsers.app; sourceTree = BUILT_PRODUCTS_DIR; }; 42 | C0316B63275243CE00BBE3D9 /* macOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = macOS.entitlements; sourceTree = ""; }; 43 | C0316B912752444800BBE3D9 /* randomusers.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = randomusers.json; sourceTree = ""; }; 44 | C0316B9B2752451E00BBE3D9 /* UsersData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UsersData.swift; sourceTree = ""; }; 45 | C0316B9E275245CD00BBE3D9 /* UserModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserModel.swift; sourceTree = ""; }; 46 | C0316BA22752491E00BBE3D9 /* UsersScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UsersScreen.swift; sourceTree = ""; }; 47 | C0316BA527525F3800BBE3D9 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; 48 | C0316BAE275263F700BBE3D9 /* UserDetailScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDetailScreen.swift; sourceTree = ""; }; 49 | C0316BB12752690900BBE3D9 /* ShortcutsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutsScreen.swift; sourceTree = ""; }; 50 | C0316BB4275274FC00BBE3D9 /* UserLocationScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserLocationScreen.swift; sourceTree = ""; }; 51 | /* End PBXFileReference section */ 52 | 53 | /* Begin PBXFrameworksBuildPhase section */ 54 | C0316B58275243CE00BBE3D9 /* Frameworks */ = { 55 | isa = PBXFrameworksBuildPhase; 56 | buildActionMask = 2147483647; 57 | files = ( 58 | C0DAACD2275BF3DD001A4EB4 /* SwiftUIRouter in Frameworks */, 59 | ); 60 | runOnlyForDeploymentPostprocessing = 0; 61 | }; 62 | C0316B5E275243CE00BBE3D9 /* Frameworks */ = { 63 | isa = PBXFrameworksBuildPhase; 64 | buildActionMask = 2147483647; 65 | files = ( 66 | C0DAACD4275BF3E4001A4EB4 /* SwiftUIRouter in Frameworks */, 67 | ); 68 | runOnlyForDeploymentPostprocessing = 0; 69 | }; 70 | /* End PBXFrameworksBuildPhase section */ 71 | 72 | /* Begin PBXGroup section */ 73 | C0316B4E275243CC00BBE3D9 = { 74 | isa = PBXGroup; 75 | children = ( 76 | C0316B53275243CC00BBE3D9 /* Shared */, 77 | C0316B62275243CE00BBE3D9 /* macOS */, 78 | C0316B5C275243CE00BBE3D9 /* Products */, 79 | C0316B97275244BD00BBE3D9 /* Frameworks */, 80 | ); 81 | sourceTree = ""; 82 | }; 83 | C0316B53275243CC00BBE3D9 /* Shared */ = { 84 | isa = PBXGroup; 85 | children = ( 86 | C0316B54275243CC00BBE3D9 /* RandomUsersApp.swift */, 87 | C0316B55275243CC00BBE3D9 /* RootView.swift */, 88 | C0316BA527525F3800BBE3D9 /* Extensions.swift */, 89 | C0316BA12752491000BBE3D9 /* Screens */, 90 | C0316B9A2752450B00BBE3D9 /* Data */, 91 | C0316B902752444800BBE3D9 /* Resources */, 92 | C0316B56275243CE00BBE3D9 /* Assets.xcassets */, 93 | ); 94 | path = Shared; 95 | sourceTree = ""; 96 | }; 97 | C0316B5C275243CE00BBE3D9 /* Products */ = { 98 | isa = PBXGroup; 99 | children = ( 100 | C0316B5B275243CE00BBE3D9 /* RandomUsers.app */, 101 | C0316B61275243CE00BBE3D9 /* RandomUsers.app */, 102 | ); 103 | name = Products; 104 | sourceTree = ""; 105 | }; 106 | C0316B62275243CE00BBE3D9 /* macOS */ = { 107 | isa = PBXGroup; 108 | children = ( 109 | C0316B63275243CE00BBE3D9 /* macOS.entitlements */, 110 | ); 111 | path = macOS; 112 | sourceTree = ""; 113 | }; 114 | C0316B902752444800BBE3D9 /* Resources */ = { 115 | isa = PBXGroup; 116 | children = ( 117 | C0316B912752444800BBE3D9 /* randomusers.json */, 118 | ); 119 | path = Resources; 120 | sourceTree = ""; 121 | }; 122 | C0316B97275244BD00BBE3D9 /* Frameworks */ = { 123 | isa = PBXGroup; 124 | children = ( 125 | ); 126 | name = Frameworks; 127 | sourceTree = ""; 128 | }; 129 | C0316B9A2752450B00BBE3D9 /* Data */ = { 130 | isa = PBXGroup; 131 | children = ( 132 | C0316B9E275245CD00BBE3D9 /* UserModel.swift */, 133 | C0316B9B2752451E00BBE3D9 /* UsersData.swift */, 134 | ); 135 | path = Data; 136 | sourceTree = ""; 137 | }; 138 | C0316BA12752491000BBE3D9 /* Screens */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | C0316BA22752491E00BBE3D9 /* UsersScreen.swift */, 142 | C0316BAE275263F700BBE3D9 /* UserDetailScreen.swift */, 143 | C0316BB4275274FC00BBE3D9 /* UserLocationScreen.swift */, 144 | C0316BB12752690900BBE3D9 /* ShortcutsScreen.swift */, 145 | ); 146 | path = Screens; 147 | sourceTree = ""; 148 | }; 149 | /* End PBXGroup section */ 150 | 151 | /* Begin PBXNativeTarget section */ 152 | C0316B5A275243CE00BBE3D9 /* RandomUsers (iOS) */ = { 153 | isa = PBXNativeTarget; 154 | buildConfigurationList = C0316B84275243CF00BBE3D9 /* Build configuration list for PBXNativeTarget "RandomUsers (iOS)" */; 155 | buildPhases = ( 156 | C0316B57275243CE00BBE3D9 /* Sources */, 157 | C0316B58275243CE00BBE3D9 /* Frameworks */, 158 | C0316B59275243CE00BBE3D9 /* Resources */, 159 | ); 160 | buildRules = ( 161 | ); 162 | dependencies = ( 163 | ); 164 | name = "RandomUsers (iOS)"; 165 | packageProductDependencies = ( 166 | C0DAACD1275BF3DD001A4EB4 /* SwiftUIRouter */, 167 | ); 168 | productName = "RandomUsers (iOS)"; 169 | productReference = C0316B5B275243CE00BBE3D9 /* RandomUsers.app */; 170 | productType = "com.apple.product-type.application"; 171 | }; 172 | C0316B60275243CE00BBE3D9 /* RandomUsers (macOS) */ = { 173 | isa = PBXNativeTarget; 174 | buildConfigurationList = C0316B87275243CF00BBE3D9 /* Build configuration list for PBXNativeTarget "RandomUsers (macOS)" */; 175 | buildPhases = ( 176 | C0316B5D275243CE00BBE3D9 /* Sources */, 177 | C0316B5E275243CE00BBE3D9 /* Frameworks */, 178 | C0316B5F275243CE00BBE3D9 /* Resources */, 179 | ); 180 | buildRules = ( 181 | ); 182 | dependencies = ( 183 | ); 184 | name = "RandomUsers (macOS)"; 185 | packageProductDependencies = ( 186 | C0DAACD3275BF3E4001A4EB4 /* SwiftUIRouter */, 187 | ); 188 | productName = "RandomUsers (macOS)"; 189 | productReference = C0316B61275243CE00BBE3D9 /* RandomUsers.app */; 190 | productType = "com.apple.product-type.application"; 191 | }; 192 | /* End PBXNativeTarget section */ 193 | 194 | /* Begin PBXProject section */ 195 | C0316B4F275243CC00BBE3D9 /* Project object */ = { 196 | isa = PBXProject; 197 | attributes = { 198 | BuildIndependentTargetsInParallel = 1; 199 | LastSwiftUpdateCheck = 1320; 200 | LastUpgradeCheck = 1320; 201 | TargetAttributes = { 202 | C0316B5A275243CE00BBE3D9 = { 203 | CreatedOnToolsVersion = 13.2; 204 | }; 205 | C0316B60275243CE00BBE3D9 = { 206 | CreatedOnToolsVersion = 13.2; 207 | }; 208 | }; 209 | }; 210 | buildConfigurationList = C0316B52275243CC00BBE3D9 /* Build configuration list for PBXProject "RandomUsers" */; 211 | compatibilityVersion = "Xcode 13.0"; 212 | developmentRegion = en; 213 | hasScannedForEncodings = 0; 214 | knownRegions = ( 215 | en, 216 | Base, 217 | ); 218 | mainGroup = C0316B4E275243CC00BBE3D9; 219 | packageReferences = ( 220 | C0DAACD0275BF3DD001A4EB4 /* XCRemoteSwiftPackageReference "SwiftUIRouter" */, 221 | ); 222 | productRefGroup = C0316B5C275243CE00BBE3D9 /* Products */; 223 | projectDirPath = ""; 224 | projectRoot = ""; 225 | targets = ( 226 | C0316B5A275243CE00BBE3D9 /* RandomUsers (iOS) */, 227 | C0316B60275243CE00BBE3D9 /* RandomUsers (macOS) */, 228 | ); 229 | }; 230 | /* End PBXProject section */ 231 | 232 | /* Begin PBXResourcesBuildPhase section */ 233 | C0316B59275243CE00BBE3D9 /* Resources */ = { 234 | isa = PBXResourcesBuildPhase; 235 | buildActionMask = 2147483647; 236 | files = ( 237 | C0316B80275243CF00BBE3D9 /* Assets.xcassets in Resources */, 238 | C0316B922752444800BBE3D9 /* randomusers.json in Resources */, 239 | ); 240 | runOnlyForDeploymentPostprocessing = 0; 241 | }; 242 | C0316B5F275243CE00BBE3D9 /* Resources */ = { 243 | isa = PBXResourcesBuildPhase; 244 | buildActionMask = 2147483647; 245 | files = ( 246 | C0316B81275243CF00BBE3D9 /* Assets.xcassets in Resources */, 247 | C0316B932752444800BBE3D9 /* randomusers.json in Resources */, 248 | ); 249 | runOnlyForDeploymentPostprocessing = 0; 250 | }; 251 | /* End PBXResourcesBuildPhase section */ 252 | 253 | /* Begin PBXSourcesBuildPhase section */ 254 | C0316B57275243CE00BBE3D9 /* Sources */ = { 255 | isa = PBXSourcesBuildPhase; 256 | buildActionMask = 2147483647; 257 | files = ( 258 | C0316B7E275243CF00BBE3D9 /* RootView.swift in Sources */, 259 | C0316BB5275274FC00BBE3D9 /* UserLocationScreen.swift in Sources */, 260 | C0316BA627525F3800BBE3D9 /* Extensions.swift in Sources */, 261 | C0316BA32752491E00BBE3D9 /* UsersScreen.swift in Sources */, 262 | C0316B9C2752451E00BBE3D9 /* UsersData.swift in Sources */, 263 | C0316BAF275263F700BBE3D9 /* UserDetailScreen.swift in Sources */, 264 | C0316B9F275245CD00BBE3D9 /* UserModel.swift in Sources */, 265 | C0316B7C275243CF00BBE3D9 /* RandomUsersApp.swift in Sources */, 266 | C0316BB22752690900BBE3D9 /* ShortcutsScreen.swift in Sources */, 267 | ); 268 | runOnlyForDeploymentPostprocessing = 0; 269 | }; 270 | C0316B5D275243CE00BBE3D9 /* Sources */ = { 271 | isa = PBXSourcesBuildPhase; 272 | buildActionMask = 2147483647; 273 | files = ( 274 | C0316B7F275243CF00BBE3D9 /* RootView.swift in Sources */, 275 | C0316BB6275274FC00BBE3D9 /* UserLocationScreen.swift in Sources */, 276 | C0316BA727525F3800BBE3D9 /* Extensions.swift in Sources */, 277 | C0316BA42752491E00BBE3D9 /* UsersScreen.swift in Sources */, 278 | C0316B9D2752451E00BBE3D9 /* UsersData.swift in Sources */, 279 | C0316BB0275263F700BBE3D9 /* UserDetailScreen.swift in Sources */, 280 | C0316BA0275245CD00BBE3D9 /* UserModel.swift in Sources */, 281 | C0316B7D275243CF00BBE3D9 /* RandomUsersApp.swift in Sources */, 282 | C0316BB32752690900BBE3D9 /* ShortcutsScreen.swift in Sources */, 283 | ); 284 | runOnlyForDeploymentPostprocessing = 0; 285 | }; 286 | /* End PBXSourcesBuildPhase section */ 287 | 288 | /* Begin XCBuildConfiguration section */ 289 | C0316B82275243CF00BBE3D9 /* Debug */ = { 290 | isa = XCBuildConfiguration; 291 | buildSettings = { 292 | ALWAYS_SEARCH_USER_PATHS = NO; 293 | CLANG_ANALYZER_NONNULL = YES; 294 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 295 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 296 | CLANG_CXX_LIBRARY = "libc++"; 297 | CLANG_ENABLE_MODULES = YES; 298 | CLANG_ENABLE_OBJC_ARC = YES; 299 | CLANG_ENABLE_OBJC_WEAK = YES; 300 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 301 | CLANG_WARN_BOOL_CONVERSION = YES; 302 | CLANG_WARN_COMMA = YES; 303 | CLANG_WARN_CONSTANT_CONVERSION = YES; 304 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 305 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 306 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 307 | CLANG_WARN_EMPTY_BODY = YES; 308 | CLANG_WARN_ENUM_CONVERSION = YES; 309 | CLANG_WARN_INFINITE_RECURSION = YES; 310 | CLANG_WARN_INT_CONVERSION = YES; 311 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 312 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 313 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 314 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 315 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 316 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 317 | CLANG_WARN_STRICT_PROTOTYPES = YES; 318 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 319 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 320 | CLANG_WARN_UNREACHABLE_CODE = YES; 321 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 322 | COPY_PHASE_STRIP = NO; 323 | DEBUG_INFORMATION_FORMAT = dwarf; 324 | ENABLE_STRICT_OBJC_MSGSEND = YES; 325 | ENABLE_TESTABILITY = YES; 326 | GCC_C_LANGUAGE_STANDARD = gnu11; 327 | GCC_DYNAMIC_NO_PIC = NO; 328 | GCC_NO_COMMON_BLOCKS = YES; 329 | GCC_OPTIMIZATION_LEVEL = 0; 330 | GCC_PREPROCESSOR_DEFINITIONS = ( 331 | "DEBUG=1", 332 | "$(inherited)", 333 | ); 334 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 335 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 336 | GCC_WARN_UNDECLARED_SELECTOR = YES; 337 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 338 | GCC_WARN_UNUSED_FUNCTION = YES; 339 | GCC_WARN_UNUSED_VARIABLE = YES; 340 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 341 | MTL_FAST_MATH = YES; 342 | ONLY_ACTIVE_ARCH = YES; 343 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 344 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 345 | }; 346 | name = Debug; 347 | }; 348 | C0316B83275243CF00BBE3D9 /* Release */ = { 349 | isa = XCBuildConfiguration; 350 | buildSettings = { 351 | ALWAYS_SEARCH_USER_PATHS = NO; 352 | CLANG_ANALYZER_NONNULL = YES; 353 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 354 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 355 | CLANG_CXX_LIBRARY = "libc++"; 356 | CLANG_ENABLE_MODULES = YES; 357 | CLANG_ENABLE_OBJC_ARC = YES; 358 | CLANG_ENABLE_OBJC_WEAK = YES; 359 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 360 | CLANG_WARN_BOOL_CONVERSION = YES; 361 | CLANG_WARN_COMMA = YES; 362 | CLANG_WARN_CONSTANT_CONVERSION = YES; 363 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 364 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 365 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 366 | CLANG_WARN_EMPTY_BODY = YES; 367 | CLANG_WARN_ENUM_CONVERSION = YES; 368 | CLANG_WARN_INFINITE_RECURSION = YES; 369 | CLANG_WARN_INT_CONVERSION = YES; 370 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 371 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 372 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 373 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 374 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 375 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 376 | CLANG_WARN_STRICT_PROTOTYPES = YES; 377 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 378 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 379 | CLANG_WARN_UNREACHABLE_CODE = YES; 380 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 381 | COPY_PHASE_STRIP = NO; 382 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 383 | ENABLE_NS_ASSERTIONS = NO; 384 | ENABLE_STRICT_OBJC_MSGSEND = YES; 385 | GCC_C_LANGUAGE_STANDARD = gnu11; 386 | GCC_NO_COMMON_BLOCKS = YES; 387 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 388 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 389 | GCC_WARN_UNDECLARED_SELECTOR = YES; 390 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 391 | GCC_WARN_UNUSED_FUNCTION = YES; 392 | GCC_WARN_UNUSED_VARIABLE = YES; 393 | MTL_ENABLE_DEBUG_INFO = NO; 394 | MTL_FAST_MATH = YES; 395 | SWIFT_COMPILATION_MODE = wholemodule; 396 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 397 | }; 398 | name = Release; 399 | }; 400 | C0316B85275243CF00BBE3D9 /* Debug */ = { 401 | isa = XCBuildConfiguration; 402 | buildSettings = { 403 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 404 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 405 | CODE_SIGN_STYLE = Automatic; 406 | CURRENT_PROJECT_VERSION = 1; 407 | DEVELOPMENT_TEAM = QSR4FL5D2K; 408 | ENABLE_PREVIEWS = YES; 409 | GENERATE_INFOPLIST_FILE = YES; 410 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 411 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 412 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 413 | INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait"; 414 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 415 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 416 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 417 | LD_RUNPATH_SEARCH_PATHS = ( 418 | "$(inherited)", 419 | "@executable_path/Frameworks", 420 | ); 421 | MARKETING_VERSION = 1.0; 422 | PRODUCT_BUNDLE_IDENTIFIER = com.frzi.RandomUsers; 423 | PRODUCT_NAME = RandomUsers; 424 | SDKROOT = iphoneos; 425 | SWIFT_EMIT_LOC_STRINGS = YES; 426 | SWIFT_VERSION = 5.0; 427 | TARGETED_DEVICE_FAMILY = "1,2"; 428 | }; 429 | name = Debug; 430 | }; 431 | C0316B86275243CF00BBE3D9 /* Release */ = { 432 | isa = XCBuildConfiguration; 433 | buildSettings = { 434 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 435 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 436 | CODE_SIGN_STYLE = Automatic; 437 | CURRENT_PROJECT_VERSION = 1; 438 | DEVELOPMENT_TEAM = QSR4FL5D2K; 439 | ENABLE_PREVIEWS = YES; 440 | GENERATE_INFOPLIST_FILE = YES; 441 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 442 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 443 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 444 | INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait"; 445 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 446 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 447 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 448 | LD_RUNPATH_SEARCH_PATHS = ( 449 | "$(inherited)", 450 | "@executable_path/Frameworks", 451 | ); 452 | MARKETING_VERSION = 1.0; 453 | PRODUCT_BUNDLE_IDENTIFIER = com.frzi.RandomUsers; 454 | PRODUCT_NAME = RandomUsers; 455 | SDKROOT = iphoneos; 456 | SWIFT_EMIT_LOC_STRINGS = YES; 457 | SWIFT_VERSION = 5.0; 458 | TARGETED_DEVICE_FAMILY = "1,2"; 459 | VALIDATE_PRODUCT = YES; 460 | }; 461 | name = Release; 462 | }; 463 | C0316B88275243CF00BBE3D9 /* Debug */ = { 464 | isa = XCBuildConfiguration; 465 | buildSettings = { 466 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 467 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 468 | CODE_SIGN_ENTITLEMENTS = macOS/macOS.entitlements; 469 | CODE_SIGN_STYLE = Automatic; 470 | COMBINE_HIDPI_IMAGES = YES; 471 | CURRENT_PROJECT_VERSION = 1; 472 | DEVELOPMENT_TEAM = QSR4FL5D2K; 473 | ENABLE_HARDENED_RUNTIME = YES; 474 | ENABLE_PREVIEWS = YES; 475 | GENERATE_INFOPLIST_FILE = YES; 476 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 477 | LD_RUNPATH_SEARCH_PATHS = ( 478 | "$(inherited)", 479 | "@executable_path/../Frameworks", 480 | ); 481 | MACOSX_DEPLOYMENT_TARGET = 12.0; 482 | MARKETING_VERSION = 1.0; 483 | PRODUCT_BUNDLE_IDENTIFIER = com.frzi.RandomUsers; 484 | PRODUCT_NAME = RandomUsers; 485 | SDKROOT = macosx; 486 | SWIFT_EMIT_LOC_STRINGS = YES; 487 | SWIFT_VERSION = 5.0; 488 | }; 489 | name = Debug; 490 | }; 491 | C0316B89275243CF00BBE3D9 /* Release */ = { 492 | isa = XCBuildConfiguration; 493 | buildSettings = { 494 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 495 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 496 | CODE_SIGN_ENTITLEMENTS = macOS/macOS.entitlements; 497 | CODE_SIGN_STYLE = Automatic; 498 | COMBINE_HIDPI_IMAGES = YES; 499 | CURRENT_PROJECT_VERSION = 1; 500 | DEVELOPMENT_TEAM = QSR4FL5D2K; 501 | ENABLE_HARDENED_RUNTIME = YES; 502 | ENABLE_PREVIEWS = YES; 503 | GENERATE_INFOPLIST_FILE = YES; 504 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 505 | LD_RUNPATH_SEARCH_PATHS = ( 506 | "$(inherited)", 507 | "@executable_path/../Frameworks", 508 | ); 509 | MACOSX_DEPLOYMENT_TARGET = 12.0; 510 | MARKETING_VERSION = 1.0; 511 | PRODUCT_BUNDLE_IDENTIFIER = com.frzi.RandomUsers; 512 | PRODUCT_NAME = RandomUsers; 513 | SDKROOT = macosx; 514 | SWIFT_EMIT_LOC_STRINGS = YES; 515 | SWIFT_VERSION = 5.0; 516 | }; 517 | name = Release; 518 | }; 519 | /* End XCBuildConfiguration section */ 520 | 521 | /* Begin XCConfigurationList section */ 522 | C0316B52275243CC00BBE3D9 /* Build configuration list for PBXProject "RandomUsers" */ = { 523 | isa = XCConfigurationList; 524 | buildConfigurations = ( 525 | C0316B82275243CF00BBE3D9 /* Debug */, 526 | C0316B83275243CF00BBE3D9 /* Release */, 527 | ); 528 | defaultConfigurationIsVisible = 0; 529 | defaultConfigurationName = Release; 530 | }; 531 | C0316B84275243CF00BBE3D9 /* Build configuration list for PBXNativeTarget "RandomUsers (iOS)" */ = { 532 | isa = XCConfigurationList; 533 | buildConfigurations = ( 534 | C0316B85275243CF00BBE3D9 /* Debug */, 535 | C0316B86275243CF00BBE3D9 /* Release */, 536 | ); 537 | defaultConfigurationIsVisible = 0; 538 | defaultConfigurationName = Release; 539 | }; 540 | C0316B87275243CF00BBE3D9 /* Build configuration list for PBXNativeTarget "RandomUsers (macOS)" */ = { 541 | isa = XCConfigurationList; 542 | buildConfigurations = ( 543 | C0316B88275243CF00BBE3D9 /* Debug */, 544 | C0316B89275243CF00BBE3D9 /* Release */, 545 | ); 546 | defaultConfigurationIsVisible = 0; 547 | defaultConfigurationName = Release; 548 | }; 549 | /* End XCConfigurationList section */ 550 | 551 | /* Begin XCRemoteSwiftPackageReference section */ 552 | C0DAACD0275BF3DD001A4EB4 /* XCRemoteSwiftPackageReference "SwiftUIRouter" */ = { 553 | isa = XCRemoteSwiftPackageReference; 554 | repositoryURL = "https://github.com/frzi/SwiftUIRouter"; 555 | requirement = { 556 | kind = upToNextMajorVersion; 557 | minimumVersion = 1.3.0; 558 | }; 559 | }; 560 | /* End XCRemoteSwiftPackageReference section */ 561 | 562 | /* Begin XCSwiftPackageProductDependency section */ 563 | C0DAACD1275BF3DD001A4EB4 /* SwiftUIRouter */ = { 564 | isa = XCSwiftPackageProductDependency; 565 | package = C0DAACD0275BF3DD001A4EB4 /* XCRemoteSwiftPackageReference "SwiftUIRouter" */; 566 | productName = SwiftUIRouter; 567 | }; 568 | C0DAACD3275BF3E4001A4EB4 /* SwiftUIRouter */ = { 569 | isa = XCSwiftPackageProductDependency; 570 | package = C0DAACD0275BF3DD001A4EB4 /* XCRemoteSwiftPackageReference "SwiftUIRouter" */; 571 | productName = SwiftUIRouter; 572 | }; 573 | /* End XCSwiftPackageProductDependency section */ 574 | }; 575 | rootObject = C0316B4F275243CC00BBE3D9 /* Project object */; 576 | } 577 | -------------------------------------------------------------------------------- /RandomUsers/RandomUsers.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /RandomUsers/RandomUsers.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /RandomUsers/RandomUsers.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "object": { 3 | "pins": [ 4 | { 5 | "package": "SwiftUIRouter", 6 | "repositoryURL": "https://github.com/frzi/SwiftUIRouter", 7 | "state": { 8 | "branch": null, 9 | "revision": "5e69c689ceaae3c8ed52ae535f294aeb262dc812", 10 | "version": "1.3.0" 11 | } 12 | } 13 | ] 14 | }, 15 | "version": 1 16 | } 17 | -------------------------------------------------------------------------------- /RandomUsers/Shared/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 | -------------------------------------------------------------------------------- /RandomUsers/Shared/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | }, 93 | { 94 | "idiom" : "mac", 95 | "scale" : "1x", 96 | "size" : "16x16" 97 | }, 98 | { 99 | "idiom" : "mac", 100 | "scale" : "2x", 101 | "size" : "16x16" 102 | }, 103 | { 104 | "idiom" : "mac", 105 | "scale" : "1x", 106 | "size" : "32x32" 107 | }, 108 | { 109 | "idiom" : "mac", 110 | "scale" : "2x", 111 | "size" : "32x32" 112 | }, 113 | { 114 | "idiom" : "mac", 115 | "scale" : "1x", 116 | "size" : "128x128" 117 | }, 118 | { 119 | "idiom" : "mac", 120 | "scale" : "2x", 121 | "size" : "128x128" 122 | }, 123 | { 124 | "idiom" : "mac", 125 | "scale" : "1x", 126 | "size" : "256x256" 127 | }, 128 | { 129 | "idiom" : "mac", 130 | "scale" : "2x", 131 | "size" : "256x256" 132 | }, 133 | { 134 | "idiom" : "mac", 135 | "scale" : "1x", 136 | "size" : "512x512" 137 | }, 138 | { 139 | "idiom" : "mac", 140 | "scale" : "2x", 141 | "size" : "512x512" 142 | } 143 | ], 144 | "info" : { 145 | "author" : "xcode", 146 | "version" : 1 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /RandomUsers/Shared/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /RandomUsers/Shared/Data/UserModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RandomUsers App 3 | // Created by Freek (github.com/frzi) 2021 4 | // 5 | 6 | import CoreLocation 7 | import Foundation 8 | 9 | struct UserModel: Decodable, Identifiable { 10 | let dob: DateOfBirth 11 | let email: String 12 | let gender: String 13 | let location: Location 14 | let login: Login 15 | let name: Name 16 | let picture: Picture 17 | 18 | // MARK: Computed values. 19 | var id: UUID { login.uuid } 20 | var fullName: String { 21 | name.title + " " + name.first + " " + name.last 22 | } 23 | 24 | // MARK: - Sub types 25 | struct DateOfBirth: Decodable { 26 | let age: Int 27 | let date: String 28 | } 29 | 30 | struct Location: Decodable { 31 | let city: String 32 | let coordinates: Coordinates 33 | let country: String 34 | let state: String 35 | 36 | struct Coordinates: Decodable { 37 | let latitude: String 38 | let longitude: String 39 | 40 | var clLocation: CLLocationCoordinate2D { 41 | CLLocationCoordinate2D( 42 | latitude: Double(latitude) ?? 51.532005, 43 | longitude: Double(longitude) ?? -0.177331 44 | ) 45 | } 46 | } 47 | 48 | struct Street: Decodable { 49 | let name: String 50 | let number: Int 51 | } 52 | } 53 | 54 | struct Login: Decodable { 55 | let username: String 56 | let uuid: UUID 57 | } 58 | 59 | struct Name: Decodable { 60 | let title: String 61 | let first: String 62 | let last: String 63 | } 64 | 65 | struct Picture: Decodable { 66 | let large: URL 67 | let medium: URL 68 | let thumbnail: URL 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /RandomUsers/Shared/Data/UsersData.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RandomUsers App 3 | // Created by Freek (github.com/frzi) 2021 4 | // 5 | 6 | import Combine 7 | import Foundation 8 | 9 | /// This code is unimportant and unrelated to the workings of SwiftUI Router. 10 | /// `UsersData` simply holds all the data we use throughout the app (loaded from a single JSON found in the bundle). 11 | /// We use an `ObservableObject` as an environment object as singletons (shared instances) are generally discouraged 12 | /// when working with data in SwiftUI. 13 | final class UsersData: ObservableObject { 14 | @Published private(set) var users: [UserModel] 15 | 16 | init() { 17 | let decoder = JSONDecoder() 18 | decoder.keyDecodingStrategy = .convertFromSnakeCase 19 | 20 | struct RandomUsersAPIResponse: Decodable { 21 | let results: [UserModel] 22 | } 23 | 24 | do { 25 | guard let jsonPath = Bundle.main.url(forResource: "randomusers", withExtension: "json") else { 26 | fatalError("Unable to load randomusers.json") 27 | } 28 | 29 | let jsonData = try Data(contentsOf: jsonPath) 30 | let json = try decoder.decode(RandomUsersAPIResponse.self, from: jsonData) 31 | users = json.results.sorted { left, right in 32 | left.name.last < right.name.last 33 | } 34 | } 35 | catch { 36 | print(error) 37 | fatalError() 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /RandomUsers/Shared/Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RandomUsers App 3 | // Created by Freek (github.com/frzi) 2021 4 | // 5 | 6 | import Foundation 7 | import SwiftUI 8 | import SwiftUIRouter 9 | 10 | // MARK: - Navigation transition view modifier 11 | extension View { 12 | func navigationTransition() -> some View { 13 | modifier(NavigationTransition()) 14 | } 15 | } 16 | 17 | private struct NavigationTransition: ViewModifier { 18 | @EnvironmentObject private var navigator: Navigator 19 | 20 | private func transition(for direction: NavigationAction.Direction?) -> AnyTransition { 21 | if direction == .deeper || direction == .sideways { 22 | return AnyTransition.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .leading)) 23 | } 24 | else { 25 | return AnyTransition.asymmetric(insertion: .move(edge: .leading), removal: .move(edge: .trailing)) 26 | } 27 | } 28 | 29 | func body(content: Content) -> some View { 30 | content 31 | .animation(.easeInOut, value: navigator.path) 32 | .transition(transition(for: navigator.lastAction?.direction)) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /RandomUsers/Shared/RandomUsersApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RandomUsers App 3 | // Created by Freek (github.com/frzi) 2021 4 | // 5 | 6 | import SwiftUI 7 | import SwiftUIRouter 8 | 9 | @main 10 | struct RandomUsersApp: App { 11 | @StateObject private var usersData = UsersData() 12 | 13 | var body: some Scene { 14 | WindowGroup { 15 | /// (1) This is the first and perhaps the most important step when using SwiftUI Router. 16 | /// The `Router` view initializes all necessary environment values and objects. Every view in the 17 | /// SwiftUI Router library works only inside a `Router`. 18 | /// 19 | /// Although it isn't necessary to put the `Router` at the `App` level, it is recommended to put it as 20 | /// high as possible in your View hierarchy. 21 | Router { 22 | RootView() 23 | } 24 | .environmentObject(usersData) 25 | #if os(macOS) 26 | .frame(minWidth: 400, maxWidth: .infinity, minHeight: 300, maxHeight: .infinity) 27 | #endif 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /RandomUsers/Shared/Resources/randomusers.json: -------------------------------------------------------------------------------- 1 | {"results":[{"gender":"female","name":{"title":"Ms","first":"Eloane","last":"Lopez"},"location":{"street":{"number":1156,"name":"Boulevard de la Duchère"},"city":"Caen","state":"Corrèze","country":"France","postcode":88154,"coordinates":{"latitude":"4.1348","longitude":"116.0508"},"timezone":{"offset":"+3:00","description":"Baghdad, Riyadh, Moscow, St. Petersburg"}},"email":"eloane.lopez@example.com","login":{"uuid":"49d81232-d546-4609-bd0e-d87ab8fe03fb","username":"whitesnake589","password":"1974","salt":"wpAAdJE1","md5":"ed0b4e8457b08d3d4c656c429b1050ea","sha1":"fdfe278b34d7d7af23cc6f23d3a1ea84eddcba87","sha256":"ce71615d298cde72fe9ac51e0a8d84098aa8f80e2ce042168f0c5920e3b00afd"},"dob":{"date":"1969-02-12T14:09:04.957Z","age":52},"registered":{"date":"2013-06-22T09:01:42.727Z","age":8},"phone":"03-99-02-97-97","cell":"06-74-15-03-50","id":{"name":"INSEE","value":"2NNaN95487664 27"},"picture":{"large":"https://randomuser.me/api/portraits/women/70.jpg","medium":"https://randomuser.me/api/portraits/med/women/70.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/70.jpg"},"nat":"FR"},{"gender":"male","name":{"title":"Mr","first":"Mike","last":"Stephens"},"location":{"street":{"number":3775,"name":"First Street"},"city":"Antioch","state":"Iowa","country":"United States","postcode":50744,"coordinates":{"latitude":"80.6946","longitude":"78.7962"},"timezone":{"offset":"-9:00","description":"Alaska"}},"email":"mike.stephens@example.com","login":{"uuid":"b7291681-f97d-4bb9-b4ef-0bd164047e0b","username":"goldenpeacock555","password":"freeuser","salt":"5aRmaLuu","md5":"bae583a1a18865070718e3971a722be1","sha1":"057b56fb8ed294c70931d906e253c4971578c867","sha256":"283f416c0dd3bc0380e0bbf5e01d7c75d33fca525c9d155e0761c029cc3c6572"},"dob":{"date":"1987-12-10T08:21:28.643Z","age":34},"registered":{"date":"2017-04-05T03:35:53.455Z","age":4},"phone":"(877)-031-6756","cell":"(934)-424-4462","id":{"name":"SSN","value":"374-16-2328"},"picture":{"large":"https://randomuser.me/api/portraits/men/66.jpg","medium":"https://randomuser.me/api/portraits/med/men/66.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/66.jpg"},"nat":"US"},{"gender":"female","name":{"title":"Mrs","first":"Erica","last":"Burns"},"location":{"street":{"number":6945,"name":"Bruce St"},"city":"Hobart","state":"Australian Capital Territory","country":"Australia","postcode":5006,"coordinates":{"latitude":"-54.3126","longitude":"-176.2773"},"timezone":{"offset":"+9:00","description":"Tokyo, Seoul, Osaka, Sapporo, Yakutsk"}},"email":"erica.burns@example.com","login":{"uuid":"95554c8c-dacb-4c05-a9c9-9f6764776945","username":"heavybutterfly690","password":"odyssey","salt":"ZGdy1I1w","md5":"49338b84fae8d0691fb51ce2c294d341","sha1":"c387d43e9eb6c68e0ff4926f6161bf0074ccc523","sha256":"c3849f115c75c99abdfb661d2b1dbf0bdf7c969b6533f3e08d8dcc52f8aa3b47"},"dob":{"date":"1991-10-22T11:06:35.974Z","age":30},"registered":{"date":"2006-01-16T22:49:20.547Z","age":15},"phone":"01-9721-0429","cell":"0499-686-045","id":{"name":"TFN","value":"548230117"},"picture":{"large":"https://randomuser.me/api/portraits/women/65.jpg","medium":"https://randomuser.me/api/portraits/med/women/65.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/65.jpg"},"nat":"AU"},{"gender":"male","name":{"title":"Mr","first":"Abdellah","last":"Versloot"},"location":{"street":{"number":6401,"name":"De Reimer"},"city":"Oranjewoud","state":"Utrecht","country":"Netherlands","postcode":48738,"coordinates":{"latitude":"45.8243","longitude":"-27.9526"},"timezone":{"offset":"0:00","description":"Western Europe Time, London, Lisbon, Casablanca"}},"email":"abdellah.versloot@example.com","login":{"uuid":"2a463d09-419e-4b17-99d8-06d8d5a71ad3","username":"redostrich518","password":"eastwood","salt":"jLDPasyG","md5":"2760ed3358985d221cb04c61b8fefaf5","sha1":"d575a514ee0a47c1290f7d876d8e10d6994b3500","sha256":"e4b5b408d9d33ed68bf5a7951e316d660f2778a6dd97dcaa0a7ddb067874088e"},"dob":{"date":"1981-09-02T11:47:52.522Z","age":40},"registered":{"date":"2013-02-15T17:21:06.729Z","age":8},"phone":"(706)-149-6373","cell":"(745)-114-2716","id":{"name":"BSN","value":"70865125"},"picture":{"large":"https://randomuser.me/api/portraits/men/94.jpg","medium":"https://randomuser.me/api/portraits/med/men/94.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/94.jpg"},"nat":"NL"},{"gender":"female","name":{"title":"Miss","first":"Abigail","last":"Novak"},"location":{"street":{"number":4784,"name":"Elgin St"},"city":"Cartwright","state":"Newfoundland and Labrador","country":"Canada","postcode":"O7E 6S8","coordinates":{"latitude":"32.4061","longitude":"-138.4246"},"timezone":{"offset":"-4:00","description":"Atlantic Time (Canada), Caracas, La Paz"}},"email":"abigail.novak@example.com","login":{"uuid":"ec42073f-eead-4a16-896d-45012b7c10e6","username":"orangemouse617","password":"menace","salt":"Jm3X6GoN","md5":"4cde98e6f9d19af485ff78acd9bf5b77","sha1":"31ad05bf2efbda6ba8b2d6e0f6081d6bb1d5180a","sha256":"3e95653136cbdbdd3ae4cda33da12a013b31a4f3f9d8eba32cd3b78e26dac9ec"},"dob":{"date":"1983-07-07T07:36:21.193Z","age":38},"registered":{"date":"2015-11-09T03:47:11.006Z","age":6},"phone":"003-569-0452","cell":"495-675-2497","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/women/52.jpg","medium":"https://randomuser.me/api/portraits/med/women/52.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/52.jpg"},"nat":"CA"},{"gender":"female","name":{"title":"Ms","first":"Lucy","last":"Hunt"},"location":{"street":{"number":8936,"name":"Church Road"},"city":"Carlow","state":"South Dublin","country":"Ireland","postcode":95798,"coordinates":{"latitude":"25.2130","longitude":"-45.9693"},"timezone":{"offset":"+7:00","description":"Bangkok, Hanoi, Jakarta"}},"email":"lucy.hunt@example.com","login":{"uuid":"ac6297a0-4685-4aa7-a9fc-0a26ea5b6b78","username":"goldenswan602","password":"chris1","salt":"11kyTUs9","md5":"51682a62903b8cfb788d6998b291f739","sha1":"d7b86698e622fb3baf54f80cc13ea5bdc93d2ae5","sha256":"7a5fb0534fb734641fafabe8d58fe0ac36230d861a3c855a87b1abea475f2681"},"dob":{"date":"1968-11-01T15:33:51.026Z","age":53},"registered":{"date":"2004-04-29T18:24:09.195Z","age":17},"phone":"051-753-4552","cell":"081-473-1447","id":{"name":"PPS","value":"3670603T"},"picture":{"large":"https://randomuser.me/api/portraits/women/6.jpg","medium":"https://randomuser.me/api/portraits/med/women/6.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/6.jpg"},"nat":"IE"},{"gender":"male","name":{"title":"Mr","first":"Gabe","last":"Rose"},"location":{"street":{"number":4807,"name":"North Street"},"city":"Londonderry","state":"Leicestershire","country":"United Kingdom","postcode":"C32 2ZP","coordinates":{"latitude":"-56.5286","longitude":"-136.6306"},"timezone":{"offset":"+3:00","description":"Baghdad, Riyadh, Moscow, St. Petersburg"}},"email":"gabe.rose@example.com","login":{"uuid":"74b19c1d-a914-492d-8b24-7726193ece83","username":"beautifulrabbit727","password":"jeter2","salt":"F5mmQdYg","md5":"9a307b9b8a20df67055b133f339fa0c1","sha1":"3027dd3c5b64c43f9db3beb716bca1f61cb307d3","sha256":"3d082a92a1591421c73b064d20624a7a17b3fd07f2df4644dba03ec73fb58e9e"},"dob":{"date":"1950-07-24T05:58:36.467Z","age":71},"registered":{"date":"2013-01-27T13:00:06.267Z","age":8},"phone":"015394 69507","cell":"0712-187-659","id":{"name":"NINO","value":"RE 35 62 38 T"},"picture":{"large":"https://randomuser.me/api/portraits/men/6.jpg","medium":"https://randomuser.me/api/portraits/med/men/6.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/6.jpg"},"nat":"GB"},{"gender":"female","name":{"title":"Mrs","first":"Ilona","last":"Huotari"},"location":{"street":{"number":8092,"name":"Pyynikintie"},"city":"Ristijärvi","state":"Finland Proper","country":"Finland","postcode":69462,"coordinates":{"latitude":"24.0061","longitude":"34.0640"},"timezone":{"offset":"+4:00","description":"Abu Dhabi, Muscat, Baku, Tbilisi"}},"email":"ilona.huotari@example.com","login":{"uuid":"8a9bc800-69af-4168-b6e8-ab837eb8c2ab","username":"ticklishswan475","password":"cartman","salt":"pLEAY0JL","md5":"1a443a3b49ed6e80f5738991503451c1","sha1":"74da7f153c4a4d3dd076d08a49c355286c1f0ac3","sha256":"ad6202adaf6504f36179b8d2f44b96087d8e32a1e5be09dc973e6b053e448047"},"dob":{"date":"1944-11-10T21:26:27.318Z","age":77},"registered":{"date":"2004-05-13T16:40:31.258Z","age":17},"phone":"05-146-557","cell":"042-475-42-39","id":{"name":"HETU","value":"NaNNA936undefined"},"picture":{"large":"https://randomuser.me/api/portraits/women/79.jpg","medium":"https://randomuser.me/api/portraits/med/women/79.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/79.jpg"},"nat":"FI"},{"gender":"female","name":{"title":"Ms","first":"Zara","last":"Taylor"},"location":{"street":{"number":193,"name":"Sherborne Street"},"city":"Wellington","state":"Southland","country":"New Zealand","postcode":89431,"coordinates":{"latitude":"63.5991","longitude":"46.8303"},"timezone":{"offset":"-5:00","description":"Eastern Time (US & Canada), Bogota, Lima"}},"email":"zara.taylor@example.com","login":{"uuid":"9a7bde12-dfdd-426b-84f3-5d87119b9578","username":"beautifulmeercat383","password":"lorenzo","salt":"ISsRN7yo","md5":"888a285251d3fb2fc8a1e11fc0f3cfef","sha1":"8cb48e7ad2abfdf976ec24abd7af010c729abbb8","sha256":"74efed73cde0273c9259800a487a364e365942f3544bc23bf1ab157e79865697"},"dob":{"date":"1997-11-03T04:29:59.016Z","age":24},"registered":{"date":"2013-09-22T08:03:58.743Z","age":8},"phone":"(588)-510-2296","cell":"(887)-102-7944","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/women/9.jpg","medium":"https://randomuser.me/api/portraits/med/women/9.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/9.jpg"},"nat":"NZ"},{"gender":"male","name":{"title":"Mr","first":"Sebastian","last":"Murphy"},"location":{"street":{"number":9163,"name":"Forest Ln"},"city":"Hervey Bay","state":"Victoria","country":"Australia","postcode":4056,"coordinates":{"latitude":"5.3307","longitude":"-103.0349"},"timezone":{"offset":"-1:00","description":"Azores, Cape Verde Islands"}},"email":"sebastian.murphy@example.com","login":{"uuid":"6b6276b6-ac1a-4159-a5c8-7889a8e33a0d","username":"ticklishtiger311","password":"longbow","salt":"8dSzNtuH","md5":"2ab73a3ba60d8dfb9491d5e55b371512","sha1":"daa42198332354d3f87a2cf38fa43888583dde53","sha256":"60460e6e08ad9d2a79e8f4097ad14738b786a493ee951802ed6335487d888e29"},"dob":{"date":"1988-06-04T00:09:19.359Z","age":33},"registered":{"date":"2009-12-15T07:05:55.079Z","age":12},"phone":"06-6029-0306","cell":"0420-239-442","id":{"name":"TFN","value":"829910259"},"picture":{"large":"https://randomuser.me/api/portraits/men/90.jpg","medium":"https://randomuser.me/api/portraits/med/men/90.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/90.jpg"},"nat":"AU"},{"gender":"male","name":{"title":"Mr","first":"Gerry","last":"Morris"},"location":{"street":{"number":6068,"name":"Dame Street"},"city":"Monaghan","state":"Waterford","country":"Ireland","postcode":74469,"coordinates":{"latitude":"-71.4322","longitude":"-5.2974"},"timezone":{"offset":"-6:00","description":"Central Time (US & Canada), Mexico City"}},"email":"gerry.morris@example.com","login":{"uuid":"1cb1913b-6f82-4dea-9555-46b69656b202","username":"orangeduck872","password":"llllllll","salt":"myGi4pmm","md5":"d3bf3581c5d3e0a03447421df54fdfb8","sha1":"577de2a68b6a56f0a6cf047e042dd7091a6cf493","sha256":"969aeae4c240a85d89294a295a48d7262f6a449f7f8ae70e4d244728f283fec3"},"dob":{"date":"1951-06-26T00:19:27.822Z","age":70},"registered":{"date":"2003-11-12T19:44:16.990Z","age":18},"phone":"021-302-3338","cell":"081-815-7397","id":{"name":"PPS","value":"0212675T"},"picture":{"large":"https://randomuser.me/api/portraits/men/7.jpg","medium":"https://randomuser.me/api/portraits/med/men/7.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/7.jpg"},"nat":"IE"},{"gender":"male","name":{"title":"Mr","first":"Eugenio","last":"Velasco"},"location":{"street":{"number":5036,"name":"Avenida de Salamanca"},"city":"Pozuelo de Alarcón","state":"Región de Murcia","country":"Spain","postcode":10087,"coordinates":{"latitude":"3.6140","longitude":"174.3576"},"timezone":{"offset":"-10:00","description":"Hawaii"}},"email":"eugenio.velasco@example.com","login":{"uuid":"93237ec4-0b50-4c92-a0dc-9f80cccd0157","username":"sadzebra230","password":"monroe","salt":"t8Mfmd7n","md5":"0cbc3118b2c25bcff61e102c3c950b92","sha1":"d48532f58d3599ebca55f6108238eb3ab9158aed","sha256":"2e3af1764cfca4267d4e497b10522bf45d0d15969668c2beadb1b7341b360f26"},"dob":{"date":"1978-11-03T22:29:15.276Z","age":43},"registered":{"date":"2010-06-24T03:14:31.310Z","age":11},"phone":"911-127-270","cell":"696-658-672","id":{"name":"DNI","value":"82413795-W"},"picture":{"large":"https://randomuser.me/api/portraits/men/0.jpg","medium":"https://randomuser.me/api/portraits/med/men/0.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/0.jpg"},"nat":"ES"},{"gender":"male","name":{"title":"Mr","first":"Samaritano","last":"Barros"},"location":{"street":{"number":9091,"name":"Rua Dezenove de Outubro"},"city":"Vitória","state":"Amapá","country":"Brazil","postcode":26695,"coordinates":{"latitude":"48.7700","longitude":"-96.1691"},"timezone":{"offset":"-3:30","description":"Newfoundland"}},"email":"samaritano.barros@example.com","login":{"uuid":"db040ad4-2323-4b69-82b4-2438dff79836","username":"angrywolf659","password":"bigdawg","salt":"JE2Lf1jA","md5":"1a34caaa7ce1f86227cb0c7bfef049a0","sha1":"caa65d74953deb4729184ce241daf1ecb8c94240","sha256":"4a902dda34fe862a5f1c34a569f7a878f5323933497bc14ec6fe8acd898d1a7b"},"dob":{"date":"1991-09-22T07:04:11.849Z","age":30},"registered":{"date":"2010-01-27T16:27:43.091Z","age":11},"phone":"(51) 2300-3493","cell":"(43) 1897-7191","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/men/87.jpg","medium":"https://randomuser.me/api/portraits/med/men/87.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/87.jpg"},"nat":"BR"},{"gender":"male","name":{"title":"Mr","first":"Oliver","last":"Miller"},"location":{"street":{"number":1946,"name":"West Ave"},"city":"St. George","state":"Saskatchewan","country":"Canada","postcode":"F3D 1B7","coordinates":{"latitude":"-76.8048","longitude":"26.7696"},"timezone":{"offset":"+3:00","description":"Baghdad, Riyadh, Moscow, St. Petersburg"}},"email":"oliver.miller@example.com","login":{"uuid":"f8247f59-69f9-44fc-9524-2eba9ed50294","username":"lazypeacock694","password":"grapes","salt":"TvwGoK2H","md5":"cc2a659e75864c398c2d010e4db885c6","sha1":"bf954ead139063599a66251d3dfd5ed608ac0cf7","sha256":"cb2ab28cd0892978974350842b5825ac7e3bfac90350d26c2e04f0ac050d76e1"},"dob":{"date":"1994-09-26T11:59:06.573Z","age":27},"registered":{"date":"2003-03-02T15:02:53.316Z","age":18},"phone":"076-981-8101","cell":"738-873-4621","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/men/70.jpg","medium":"https://randomuser.me/api/portraits/med/men/70.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/70.jpg"},"nat":"CA"},{"gender":"male","name":{"title":"Mr","first":"Hadrien","last":"David"},"location":{"street":{"number":3160,"name":"Rue de L'Abbé-Gillet"},"city":"Amiens","state":"Haute-Vienne","country":"France","postcode":44078,"coordinates":{"latitude":"-68.4909","longitude":"150.4656"},"timezone":{"offset":"-12:00","description":"Eniwetok, Kwajalein"}},"email":"hadrien.david@example.com","login":{"uuid":"8741644f-854f-4a73-a96d-478c0ff13b5a","username":"organicduck844","password":"eeeeeeee","salt":"SSCgxX08","md5":"6cfc6881e4da72f2d63fdae07c72e440","sha1":"2deed231edb3195170927bddc045acce29e64cbe","sha256":"af337195a543b6cab4f30fad62896ba988c55a0c9389dbb28548ef78354be58e"},"dob":{"date":"1976-11-29T10:54:00.725Z","age":45},"registered":{"date":"2005-04-18T13:47:32.414Z","age":16},"phone":"01-00-05-04-21","cell":"06-84-09-10-19","id":{"name":"INSEE","value":"1NNaN82152107 16"},"picture":{"large":"https://randomuser.me/api/portraits/men/0.jpg","medium":"https://randomuser.me/api/portraits/med/men/0.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/0.jpg"},"nat":"FR"},{"gender":"male","name":{"title":"Mr","first":"Mario","last":"Bradley"},"location":{"street":{"number":2891,"name":"W Gray St"},"city":"Bowral","state":"New South Wales","country":"Australia","postcode":3077,"coordinates":{"latitude":"-54.0445","longitude":"-41.2473"},"timezone":{"offset":"+1:00","description":"Brussels, Copenhagen, Madrid, Paris"}},"email":"mario.bradley@example.com","login":{"uuid":"8935dc6a-6359-4cab-aa39-76df993dd601","username":"bluelion301","password":"caesar","salt":"reWrUnG9","md5":"63821e64787701beb82fea4ebd953464","sha1":"d948459c1ba9986371578379a97b38a540059638","sha256":"8141a094b3b5a6ee11fc21d20c99559c831855e73c8951166ffc4c108afd001c"},"dob":{"date":"1998-09-03T05:02:45.958Z","age":23},"registered":{"date":"2013-04-30T18:40:53.239Z","age":8},"phone":"06-0331-4508","cell":"0493-644-358","id":{"name":"TFN","value":"986335519"},"picture":{"large":"https://randomuser.me/api/portraits/men/21.jpg","medium":"https://randomuser.me/api/portraits/med/men/21.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/21.jpg"},"nat":"AU"},{"gender":"female","name":{"title":"Miss","first":"Elizabeth","last":"Brown"},"location":{"street":{"number":530,"name":"Richmond Ave"},"city":"Inverness","state":"Alberta","country":"Canada","postcode":"R4F 2X6","coordinates":{"latitude":"57.3494","longitude":"-15.9357"},"timezone":{"offset":"+2:00","description":"Kaliningrad, South Africa"}},"email":"elizabeth.brown@example.com","login":{"uuid":"17b99b37-c864-45ff-9cde-fbd40ceae8b4","username":"happypeacock229","password":"qwerty12","salt":"6wC6DBv6","md5":"0a9fcdb30404bc07e65040fab0ca7169","sha1":"fac36136931de1851c0ba042b3d2ca86bb8b64dc","sha256":"6be78daf0bf0e6e6f60112129ac821ea81aa0fe8551ecca8e5e0933c1cc2b6f4"},"dob":{"date":"1998-04-13T04:44:07.683Z","age":23},"registered":{"date":"2014-11-11T11:14:23.952Z","age":7},"phone":"922-377-9309","cell":"055-113-4025","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/women/56.jpg","medium":"https://randomuser.me/api/portraits/med/women/56.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/56.jpg"},"nat":"CA"},{"gender":"male","name":{"title":"Mr","first":"Rudolfo","last":"Pinto"},"location":{"street":{"number":7074,"name":"Rua Santos Dumont "},"city":"Toledo","state":"Alagoas","country":"Brazil","postcode":88910,"coordinates":{"latitude":"37.7082","longitude":"47.3947"},"timezone":{"offset":"+5:45","description":"Kathmandu"}},"email":"rudolfo.pinto@example.com","login":{"uuid":"f638095f-a19d-4d93-943e-9ddb203be770","username":"purpleduck889","password":"casey","salt":"As7tNN68","md5":"412cfa65b29ccbe7811eb448efc3da6a","sha1":"317d8476a4ce624c8b1357850d48edbd6ec09849","sha256":"3c96d55214d3e11c916fbbdb21ba90a8aa7f6f800f6cb4a2cf1846f8c23bf6f7"},"dob":{"date":"1991-08-12T23:58:23.802Z","age":30},"registered":{"date":"2007-08-18T15:52:16.660Z","age":14},"phone":"(86) 8241-4735","cell":"(04) 3027-6905","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/men/25.jpg","medium":"https://randomuser.me/api/portraits/med/men/25.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/25.jpg"},"nat":"BR"},{"gender":"female","name":{"title":"Miss","first":"Scarlett","last":"Stone"},"location":{"street":{"number":5289,"name":"W Dallas St"},"city":"Kansas City","state":"Florida","country":"United States","postcode":72814,"coordinates":{"latitude":"-2.5109","longitude":"133.7705"},"timezone":{"offset":"+8:00","description":"Beijing, Perth, Singapore, Hong Kong"}},"email":"scarlett.stone@example.com","login":{"uuid":"a6e47d2f-0b6a-4558-8de3-c7e9b03f1609","username":"beautifulrabbit461","password":"mancity","salt":"B5ainJmH","md5":"d19b493faf053fc8d5d0393be009de90","sha1":"4a5b1b1b3e048ad230794b5c66caee1791c1488b","sha256":"897e57452d02469224aa38066f33f5fd9a11a6b5475dba613d8deff33d9bfe5f"},"dob":{"date":"1952-10-09T11:37:09.849Z","age":69},"registered":{"date":"2010-02-02T02:49:14.953Z","age":11},"phone":"(246)-790-3777","cell":"(375)-625-3143","id":{"name":"SSN","value":"169-89-6692"},"picture":{"large":"https://randomuser.me/api/portraits/women/92.jpg","medium":"https://randomuser.me/api/portraits/med/women/92.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/92.jpg"},"nat":"US"},{"gender":"female","name":{"title":"Mrs","first":"Coralie","last":"Pollemans"},"location":{"street":{"number":2538,"name":"Donderdonksedijk"},"city":"Welsum","state":"Groningen","country":"Netherlands","postcode":41099,"coordinates":{"latitude":"-40.6188","longitude":"-156.2029"},"timezone":{"offset":"-12:00","description":"Eniwetok, Kwajalein"}},"email":"coralie.pollemans@example.com","login":{"uuid":"35e674c3-ff20-449e-a936-a392aeb3682e","username":"smallkoala242","password":"cang","salt":"d788eThU","md5":"1b3b9d2ca001db44bdf4efc004a8130a","sha1":"5cad564b531f4c0ed148ae8e2655c345e6022e0e","sha256":"07e49481d8aa9c6ddd877f724ec312315ecc87dfcc29bd66a2bb3eedd681888c"},"dob":{"date":"1956-11-09T18:21:51.839Z","age":65},"registered":{"date":"2008-04-05T05:03:01.404Z","age":13},"phone":"(674)-658-8276","cell":"(021)-568-1317","id":{"name":"BSN","value":"03035754"},"picture":{"large":"https://randomuser.me/api/portraits/women/72.jpg","medium":"https://randomuser.me/api/portraits/med/women/72.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/72.jpg"},"nat":"NL"},{"gender":"female","name":{"title":"Miss","first":"Eva","last":"Novak"},"location":{"street":{"number":4339,"name":"Cedar St"},"city":"Kingston","state":"Newfoundland and Labrador","country":"Canada","postcode":"Y3Q 3K6","coordinates":{"latitude":"-45.2880","longitude":"-109.8304"},"timezone":{"offset":"-2:00","description":"Mid-Atlantic"}},"email":"eva.novak@example.com","login":{"uuid":"3893d211-3504-4554-9e39-b6fb13249b85","username":"smallmeercat459","password":"rugby1","salt":"TteNC2PB","md5":"2e6e48c87a735d07f903b98488bd71a1","sha1":"7a97991e22a3b7191ef3063ba1567f6d4c3ad0ba","sha256":"0de0f220770a1f2da26ccd9ff5dfd489924141b494834ee60cbde28607a95553"},"dob":{"date":"1951-08-02T17:13:47.768Z","age":70},"registered":{"date":"2011-04-04T14:33:31.747Z","age":10},"phone":"361-631-7407","cell":"255-383-6280","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/women/86.jpg","medium":"https://randomuser.me/api/portraits/med/women/86.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/86.jpg"},"nat":"CA"},{"gender":"male","name":{"title":"Mr","first":"Evan","last":"Burke"},"location":{"street":{"number":4741,"name":"High Street"},"city":"Skerries","state":"Wicklow","country":"Ireland","postcode":27950,"coordinates":{"latitude":"-76.1654","longitude":"-58.5719"},"timezone":{"offset":"-11:00","description":"Midway Island, Samoa"}},"email":"evan.burke@example.com","login":{"uuid":"f182bf05-f913-40f3-9bf2-a701223c3b0e","username":"organicbutterfly973","password":"dragons","salt":"hRAcumvX","md5":"8bc9e5fe3368219b54fef046b267c178","sha1":"d7edf435ce3220cf064c8f8ae81b67c6691bc261","sha256":"c36d51961bea82407b7acdd65d4272b018f9ed8464f60659765a7018288674a7"},"dob":{"date":"1952-09-03T13:23:14.237Z","age":69},"registered":{"date":"2005-08-10T18:25:08.498Z","age":16},"phone":"031-100-1594","cell":"081-099-8298","id":{"name":"PPS","value":"3744251T"},"picture":{"large":"https://randomuser.me/api/portraits/men/21.jpg","medium":"https://randomuser.me/api/portraits/med/men/21.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/21.jpg"},"nat":"IE"},{"gender":"female","name":{"title":"Mrs","first":"Vildan","last":"Korol"},"location":{"street":{"number":6066,"name":"Anafartalar Cd"},"city":"Ardahan","state":"Bartın","country":"Turkey","postcode":35186,"coordinates":{"latitude":"19.0500","longitude":"39.3510"},"timezone":{"offset":"+3:30","description":"Tehran"}},"email":"vildan.korol@example.com","login":{"uuid":"8dbc4d36-26ce-48d1-8d14-e4f1297d91d2","username":"greenmeercat301","password":"bestbuy","salt":"RZIFnZBZ","md5":"df4c804d0c1426b8bb2063d1c6827f65","sha1":"f1327670bf7920746ac63a59a11881628de1ff70","sha256":"db3d7e1e2834fb323fc1db1823bc01c40d191f8a2df66eac633e493aa5e5e40b"},"dob":{"date":"1972-09-04T21:11:58.983Z","age":49},"registered":{"date":"2016-03-13T22:54:00.997Z","age":5},"phone":"(391)-157-9415","cell":"(725)-119-8415","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/women/75.jpg","medium":"https://randomuser.me/api/portraits/med/women/75.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/75.jpg"},"nat":"TR"},{"gender":"male","name":{"title":"Monsieur","first":"Andri","last":"Bourgeois"},"location":{"street":{"number":9777,"name":"Rue de L'Abbé-Gillet"},"city":"Bretonnières","state":"Neuchâtel","country":"Switzerland","postcode":8318,"coordinates":{"latitude":"-12.1672","longitude":"-131.1370"},"timezone":{"offset":"-11:00","description":"Midway Island, Samoa"}},"email":"andri.bourgeois@example.com","login":{"uuid":"0f9d7e82-4500-457f-9662-dfcc2f221ba8","username":"blackbutterfly337","password":"anna","salt":"JrdzVEhy","md5":"540ccd1f14c558ed68ecb75e68480799","sha1":"7c851f016f12ab4a43f6938c164632be1e2b4a0a","sha256":"64fa42dcef3f2fbad6359aeeccefbae08a5f2512666de97df7088eaf3217c15e"},"dob":{"date":"1953-07-17T04:59:40.179Z","age":68},"registered":{"date":"2009-05-10T18:44:08.287Z","age":12},"phone":"076 763 68 27","cell":"077 767 78 49","id":{"name":"AVS","value":"756.6041.7252.12"},"picture":{"large":"https://randomuser.me/api/portraits/men/54.jpg","medium":"https://randomuser.me/api/portraits/med/men/54.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/54.jpg"},"nat":"CH"},{"gender":"male","name":{"title":"Mr","first":"Dominykas","last":"Vike"},"location":{"street":{"number":5120,"name":"Røahagan"},"city":"Torvikbukt","state":"Hedmark","country":"Norway","postcode":"6789","coordinates":{"latitude":"-54.9691","longitude":"168.7615"},"timezone":{"offset":"-6:00","description":"Central Time (US & Canada), Mexico City"}},"email":"dominykas.vike@example.com","login":{"uuid":"de6b5583-9d86-47ba-a0b0-cafd2d112b4d","username":"smallmeercat384","password":"1234qwer","salt":"wnyTx2jO","md5":"d515b0ba83bb60c934dbd90b5fd77f80","sha1":"c3789c24c53ce423e1df21141e4cc88d4b24fda8","sha256":"8b9d2d863d4b20a05d1b685af1a503c65d37539d4aaf768ee99f70a1f6e6599b"},"dob":{"date":"1967-05-25T09:51:58.995Z","age":54},"registered":{"date":"2019-09-22T10:13:49.522Z","age":2},"phone":"54903973","cell":"91464816","id":{"name":"FN","value":"25056730748"},"picture":{"large":"https://randomuser.me/api/portraits/men/22.jpg","medium":"https://randomuser.me/api/portraits/med/men/22.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/22.jpg"},"nat":"NO"},{"gender":"male","name":{"title":"Mr","first":"Mathis","last":"Clark"},"location":{"street":{"number":7297,"name":"Oak St"},"city":"Inwood","state":"Alberta","country":"Canada","postcode":"M5P 9Z6","coordinates":{"latitude":"56.2225","longitude":"82.3610"},"timezone":{"offset":"-1:00","description":"Azores, Cape Verde Islands"}},"email":"mathis.clark@example.com","login":{"uuid":"66a32352-20b7-4053-8580-66bb716cff59","username":"heavycat217","password":"smokie","salt":"jzAYIoRu","md5":"dd4fc0dd6ab59682b382b03a5e4a1f22","sha1":"eadb6123ad95a7d047c8a745cc07c99ed93b29ad","sha256":"6777ff25a7cd7c1fd72a14415954fb463f360a6f93e7861e1d0b8ef6a63e0a50"},"dob":{"date":"1950-06-06T16:53:33.254Z","age":71},"registered":{"date":"2010-08-13T07:07:24.026Z","age":11},"phone":"392-273-5886","cell":"183-397-5879","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/men/80.jpg","medium":"https://randomuser.me/api/portraits/med/men/80.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/80.jpg"},"nat":"CA"},{"gender":"male","name":{"title":"Mr","first":"Brian","last":"Steward"},"location":{"street":{"number":819,"name":"Albert Road"},"city":"St Davids","state":"Dyfed","country":"United Kingdom","postcode":"B2 5FG","coordinates":{"latitude":"-48.5000","longitude":"117.8856"},"timezone":{"offset":"-12:00","description":"Eniwetok, Kwajalein"}},"email":"brian.steward@example.com","login":{"uuid":"92001008-1631-4c70-b102-ed328320c1c0","username":"redswan656","password":"daman","salt":"nSIalT6v","md5":"299edcdeeaadd8308fc2a322d95b478b","sha1":"db7d728d73c1e297de14a0c2c25587c3acb04d2a","sha256":"918ab8d27406e30d9721488dc6c2d72087ea9c9cbba7e17b644255a14dc7db26"},"dob":{"date":"1998-02-23T18:20:44.593Z","age":23},"registered":{"date":"2017-06-27T04:49:02.763Z","age":4},"phone":"016973 80982","cell":"0760-095-760","id":{"name":"NINO","value":"JX 84 57 87 V"},"picture":{"large":"https://randomuser.me/api/portraits/men/3.jpg","medium":"https://randomuser.me/api/portraits/med/men/3.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/3.jpg"},"nat":"GB"},{"gender":"female","name":{"title":"Mrs","first":"Aurora","last":"Kumar"},"location":{"street":{"number":1614,"name":"Montreal Street"},"city":"Taupo","state":"Bay of Plenty","country":"New Zealand","postcode":86929,"coordinates":{"latitude":"-31.8064","longitude":"59.6104"},"timezone":{"offset":"+3:30","description":"Tehran"}},"email":"aurora.kumar@example.com","login":{"uuid":"174e22a4-1c4b-438f-b383-fa3a1661780d","username":"smallostrich409","password":"mister","salt":"2yHjQHH3","md5":"c8cc9308ac58ad08caf6be56e0eff7bc","sha1":"86c2696014c484ed29f564d7b8445f36f46e651f","sha256":"67ac295fa3304e9ce2f8682ec98785e5ae4be18b14ed02674442afe13660c168"},"dob":{"date":"1964-04-17T11:46:53.881Z","age":57},"registered":{"date":"2011-07-07T16:29:50.521Z","age":10},"phone":"(359)-495-8165","cell":"(127)-591-1658","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/women/34.jpg","medium":"https://randomuser.me/api/portraits/med/women/34.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/34.jpg"},"nat":"NZ"},{"gender":"female","name":{"title":"Mrs","first":"Siri","last":"Tobiassen"},"location":{"street":{"number":5911,"name":"Asbjørnsens vei"},"city":"Horten","state":"Rogaland","country":"Norway","postcode":"1303","coordinates":{"latitude":"76.7905","longitude":"-49.2748"},"timezone":{"offset":"-5:00","description":"Eastern Time (US & Canada), Bogota, Lima"}},"email":"siri.tobiassen@example.com","login":{"uuid":"a7758ded-a548-482f-82f5-2180c701e57e","username":"ticklishrabbit559","password":"ffffffff","salt":"oXgisuzU","md5":"578e0986ed76f56542c5ac24080d20a6","sha1":"8a45c578333c2900b0f00281b3ab565afd38bdae","sha256":"699d49ea5e1897d9d9a7cd353a36d6ca33c8e5dc9a507e9aff20f6798aa75672"},"dob":{"date":"1963-01-08T00:44:09.873Z","age":58},"registered":{"date":"2005-02-22T17:59:08.746Z","age":16},"phone":"71686016","cell":"48886447","id":{"name":"FN","value":"08016325865"},"picture":{"large":"https://randomuser.me/api/portraits/women/21.jpg","medium":"https://randomuser.me/api/portraits/med/women/21.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/21.jpg"},"nat":"NO"},{"gender":"male","name":{"title":"Mr","first":"Emre","last":"Elçiboğa"},"location":{"street":{"number":4923,"name":"Atatürk Sk"},"city":"Zonguldak","state":"Iğdır","country":"Turkey","postcode":52167,"coordinates":{"latitude":"-3.4842","longitude":"-17.8451"},"timezone":{"offset":"-6:00","description":"Central Time (US & Canada), Mexico City"}},"email":"emre.elciboga@example.com","login":{"uuid":"5eb6b2fb-9e34-45bb-a60e-0882267048a7","username":"smallwolf541","password":"420247","salt":"phyY9EV8","md5":"9f95f4d33d404990483381b4aa8918bb","sha1":"f8098a8bd173e639ff8ed3876a9b5958061f9fc1","sha256":"6ec35be06c144c6e6b40c376b9a9c0f5116ac6dc11bd85564c0c639232615186"},"dob":{"date":"1987-03-17T22:30:25.400Z","age":34},"registered":{"date":"2013-11-16T02:04:13.759Z","age":8},"phone":"(458)-433-1512","cell":"(198)-509-4663","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/men/12.jpg","medium":"https://randomuser.me/api/portraits/med/men/12.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/12.jpg"},"nat":"TR"},{"gender":"male","name":{"title":"Mr","first":"Charlie","last":"Mathes"},"location":{"street":{"number":340,"name":"Raiffeisenstraße"},"city":"Bernau Bei Berlin","state":"Thüringen","country":"Germany","postcode":59006,"coordinates":{"latitude":"-50.0200","longitude":"-84.7569"},"timezone":{"offset":"+9:30","description":"Adelaide, Darwin"}},"email":"charlie.mathes@example.com","login":{"uuid":"e914dcbb-be1e-464f-9aae-f3a3ed44e9d4","username":"smallkoala857","password":"broker","salt":"8gBlOAgt","md5":"78cd59a9d3a3ced2efd85e163070c1ff","sha1":"bdc743f7a12d05369119aebef45fb452f51be888","sha256":"5e4fef6f0e767ed13f2f3cb7e26ab1b3928849dc2219cdd3ba60121480be9f49"},"dob":{"date":"1983-10-19T17:28:17.769Z","age":38},"registered":{"date":"2002-08-31T10:10:28.874Z","age":19},"phone":"0574-1987494","cell":"0170-4164971","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/men/65.jpg","medium":"https://randomuser.me/api/portraits/med/men/65.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/65.jpg"},"nat":"DE"},{"gender":"male","name":{"title":"Mr","first":"Ovídio","last":"Duarte"},"location":{"street":{"number":6870,"name":"Avenida da Democracia"},"city":"Chapecó","state":"Bahia","country":"Brazil","postcode":12006,"coordinates":{"latitude":"-7.9264","longitude":"-118.6179"},"timezone":{"offset":"-5:00","description":"Eastern Time (US & Canada), Bogota, Lima"}},"email":"ovidio.duarte@example.com","login":{"uuid":"6b690750-4bbf-418f-ade0-d8e72b7e0239","username":"bluepanda796","password":"uuuuuuuu","salt":"vm0Yz3Ju","md5":"9e4a440abd133f4ab6b8e1c0b6982096","sha1":"f2b4c08f7cbdadbec95971b5d752c9deb37e770b","sha256":"96aa4238a55ae09b87ad9f983063a435a449bf775a92e679667d3c7862244c6a"},"dob":{"date":"1985-04-14T19:47:07.757Z","age":36},"registered":{"date":"2006-07-08T01:44:31.651Z","age":15},"phone":"(40) 8279-6623","cell":"(18) 5250-9134","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/men/78.jpg","medium":"https://randomuser.me/api/portraits/med/men/78.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/78.jpg"},"nat":"BR"},{"gender":"male","name":{"title":"Mr","first":"Sjoert","last":"Huiting"},"location":{"street":{"number":4537,"name":"Elburgkade"},"city":"Lucaswolde","state":"Limburg","country":"Netherlands","postcode":34974,"coordinates":{"latitude":"-53.7092","longitude":"16.1436"},"timezone":{"offset":"+11:00","description":"Magadan, Solomon Islands, New Caledonia"}},"email":"sjoert.huiting@example.com","login":{"uuid":"90c627f3-6ace-415c-bb5c-8a4862652aed","username":"purpleostrich573","password":"weird","salt":"2xybpcZx","md5":"e9d0cd389623e59078869dea8135f3dd","sha1":"0d83f68dfceab72ea22ca682f8850a83edad21bc","sha256":"5e8e7a7709e819cd1e3f729a4c2681e18c75776ac55c653ac66391b0cc77495e"},"dob":{"date":"1966-08-30T13:23:41.481Z","age":55},"registered":{"date":"2002-09-06T20:25:48.117Z","age":19},"phone":"(045)-715-8805","cell":"(248)-673-1075","id":{"name":"BSN","value":"18575330"},"picture":{"large":"https://randomuser.me/api/portraits/men/34.jpg","medium":"https://randomuser.me/api/portraits/med/men/34.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/34.jpg"},"nat":"NL"},{"gender":"female","name":{"title":"Mrs","first":"Olivia","last":"Christensen"},"location":{"street":{"number":2470,"name":"Strandgade"},"city":"Hornbæk","state":"Syddanmark","country":"Denmark","postcode":46076,"coordinates":{"latitude":"78.3185","longitude":"51.9012"},"timezone":{"offset":"+2:00","description":"Kaliningrad, South Africa"}},"email":"olivia.christensen@example.com","login":{"uuid":"ae4be28a-047e-4650-bff1-b2b3d7235cbb","username":"whitedog656","password":"caveman","salt":"UnNgi0Bu","md5":"a0df8113010cdd774cb0af0ccaa0acaf","sha1":"ac015be39942157bece12788a9a74b933a362153","sha256":"3419048c36323fb994e25183733a9c72b9d9d042b78881fb238535b36f2414c8"},"dob":{"date":"1959-02-12T13:27:51.316Z","age":62},"registered":{"date":"2011-09-30T18:16:06.887Z","age":10},"phone":"38618717","cell":"23147308","id":{"name":"CPR","value":"120259-7293"},"picture":{"large":"https://randomuser.me/api/portraits/women/79.jpg","medium":"https://randomuser.me/api/portraits/med/women/79.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/79.jpg"},"nat":"DK"},{"gender":"female","name":{"title":"Mrs","first":"Aiza","last":"Hodne"},"location":{"street":{"number":7566,"name":"Sigurd Syrs gate"},"city":"Seljord","state":"Møre og Romsdal","country":"Norway","postcode":"3652","coordinates":{"latitude":"-12.0905","longitude":"52.3006"},"timezone":{"offset":"+3:00","description":"Baghdad, Riyadh, Moscow, St. Petersburg"}},"email":"aiza.hodne@example.com","login":{"uuid":"9ed3ba03-28ae-4252-b160-48b872e6b166","username":"blueelephant865","password":"chivas","salt":"1PTGAlXL","md5":"f7da52f30fd9e6be307709bb0da9ad44","sha1":"d9300b7976d2bcf00ce3b223dd327d035ef220fb","sha256":"01e7035588a8ef219676af151d8ded464fc1972d42f3121ee4a6364180cfd624"},"dob":{"date":"1977-09-28T20:28:55.863Z","age":44},"registered":{"date":"2003-08-28T10:05:26.115Z","age":18},"phone":"72345103","cell":"42008152","id":{"name":"FN","value":"28097710041"},"picture":{"large":"https://randomuser.me/api/portraits/women/7.jpg","medium":"https://randomuser.me/api/portraits/med/women/7.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/7.jpg"},"nat":"NO"},{"gender":"female","name":{"title":"Ms","first":"Maeva","last":"Morin"},"location":{"street":{"number":3466,"name":"Wellington St"},"city":"Delisle","state":"Ontario","country":"Canada","postcode":"C3S 7G1","coordinates":{"latitude":"-48.6793","longitude":"2.8189"},"timezone":{"offset":"-10:00","description":"Hawaii"}},"email":"maeva.morin@example.com","login":{"uuid":"53b51a7d-a7cc-4962-8e59-2b52b70b4886","username":"blueladybug473","password":"lillian","salt":"Hw2SFO4h","md5":"3e14502ab9d85b42833e0c0ea3056426","sha1":"6eaf20e045550902647fef1417b9a1c046340ce2","sha256":"261b2bc9e879947898bf376459ac67b7328184fd64ae15bcee4e9d14402752a3"},"dob":{"date":"1966-04-06T06:49:25.251Z","age":55},"registered":{"date":"2013-07-29T03:01:26.281Z","age":8},"phone":"211-143-7966","cell":"038-347-6869","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/women/28.jpg","medium":"https://randomuser.me/api/portraits/med/women/28.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/28.jpg"},"nat":"CA"},{"gender":"female","name":{"title":"Mrs","first":"Nuria","last":"Sanz"},"location":{"street":{"number":1364,"name":"Calle de Téllez"},"city":"Guadalajara","state":"Aragón","country":"Spain","postcode":70516,"coordinates":{"latitude":"57.4628","longitude":"-59.8643"},"timezone":{"offset":"-3:00","description":"Brazil, Buenos Aires, Georgetown"}},"email":"nuria.sanz@example.com","login":{"uuid":"b3d1e5a5-6aa3-4510-b5df-31b60535c491","username":"ticklishswan570","password":"andreas","salt":"BY4csSjX","md5":"b9d41fa6eabbc6e2018b2e37ad860518","sha1":"00c9c73932744a5f31be2b0d36da2a9191303dad","sha256":"f63424ca4585e75cfe9d8c1287da60c9f53d195157d2fc91108772123c21d7cd"},"dob":{"date":"1981-07-05T12:56:53.534Z","age":40},"registered":{"date":"2003-12-07T05:49:11.841Z","age":18},"phone":"959-034-221","cell":"649-684-855","id":{"name":"DNI","value":"18257837-D"},"picture":{"large":"https://randomuser.me/api/portraits/women/35.jpg","medium":"https://randomuser.me/api/portraits/med/women/35.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/35.jpg"},"nat":"ES"},{"gender":"male","name":{"title":"Mr","first":"Sebastian","last":"Santana"},"location":{"street":{"number":5298,"name":"Avenida de América"},"city":"Móstoles","state":"Canarias","country":"Spain","postcode":64783,"coordinates":{"latitude":"84.7140","longitude":"-126.6024"},"timezone":{"offset":"+9:00","description":"Tokyo, Seoul, Osaka, Sapporo, Yakutsk"}},"email":"sebastian.santana@example.com","login":{"uuid":"33511019-f70f-4ed4-bd6c-77391e8f8a99","username":"heavysnake628","password":"auto","salt":"FLelYrjL","md5":"63662113f32319663cde1227313bd986","sha1":"3a5d6fe83f415f9235fb35040a2c4514e35d7dee","sha256":"b7b0acc88e7a3eac86b659be8aa520f7a0fde7d5b26ac439025ef98fd006a21c"},"dob":{"date":"1965-03-17T15:09:34.454Z","age":56},"registered":{"date":"2010-11-08T17:13:10.110Z","age":11},"phone":"974-536-125","cell":"676-423-591","id":{"name":"DNI","value":"49695365-S"},"picture":{"large":"https://randomuser.me/api/portraits/men/69.jpg","medium":"https://randomuser.me/api/portraits/med/men/69.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/69.jpg"},"nat":"ES"},{"gender":"female","name":{"title":"Miss","first":"Nori","last":"Telkamp"},"location":{"street":{"number":5176,"name":"Hoendiep Westzijde"},"city":"Makkum Fr","state":"Flevoland","country":"Netherlands","postcode":70125,"coordinates":{"latitude":"-70.1072","longitude":"157.1650"},"timezone":{"offset":"+9:30","description":"Adelaide, Darwin"}},"email":"nori.telkamp@example.com","login":{"uuid":"e4bd983d-6d26-4938-8c5e-218bf729c383","username":"silversnake166","password":"death1","salt":"T5XyCTCG","md5":"6696736e7d433a00a24e0107497354c6","sha1":"64906f6dc91bc5ee36b1d773c47dffe863f8dc0c","sha256":"e2a5b7c7c5dd631719ebb02f3b3d576221be00d4b0e4fb6cb029ae3e2c9d2cbb"},"dob":{"date":"1988-10-23T17:37:17.667Z","age":33},"registered":{"date":"2013-12-11T02:20:21.154Z","age":8},"phone":"(727)-815-6838","cell":"(482)-925-8315","id":{"name":"BSN","value":"08144820"},"picture":{"large":"https://randomuser.me/api/portraits/women/34.jpg","medium":"https://randomuser.me/api/portraits/med/women/34.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/34.jpg"},"nat":"NL"},{"gender":"female","name":{"title":"Miss","first":"Paige","last":"Jackson"},"location":{"street":{"number":8310,"name":"Queens Drive"},"city":"Porirua","state":"Bay of Plenty","country":"New Zealand","postcode":15596,"coordinates":{"latitude":"-56.2434","longitude":"152.1688"},"timezone":{"offset":"+2:00","description":"Kaliningrad, South Africa"}},"email":"paige.jackson@example.com","login":{"uuid":"e6283711-0f81-4769-806c-7161214268d5","username":"whiteelephant870","password":"sheng","salt":"DCgK8XeN","md5":"4cddaece7a776934cbd684f30df4a7ba","sha1":"800630e88fa37f40d8ab136890cb822ab9a0a966","sha256":"81d1ad6d7c29fb4a3707eaecada57bafa8981a6e0c23dea35c8e1504467660bd"},"dob":{"date":"1959-03-01T02:53:36.052Z","age":62},"registered":{"date":"2015-04-15T07:25:40.555Z","age":6},"phone":"(810)-754-8368","cell":"(527)-442-5893","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/women/77.jpg","medium":"https://randomuser.me/api/portraits/med/women/77.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/77.jpg"},"nat":"NZ"},{"gender":"male","name":{"title":"Mr","first":"Caleb","last":"Anderson"},"location":{"street":{"number":6171,"name":"Esk Street"},"city":"Gisborne","state":"Otago","country":"New Zealand","postcode":97849,"coordinates":{"latitude":"46.7599","longitude":"70.8234"},"timezone":{"offset":"0:00","description":"Western Europe Time, London, Lisbon, Casablanca"}},"email":"caleb.anderson@example.com","login":{"uuid":"6ae3b8ca-bbe6-4f90-b1b3-8423c63e38bd","username":"redsnake418","password":"pacman","salt":"PLWuPybt","md5":"449aefc2ad43cd6e8410be097958bd22","sha1":"d8d563f49df4b9a1cce9d66227f2bf57d267a816","sha256":"14b3a8aa9e0a1eed83348aaf97b09d8be61c3789516391ca0686d34798b66d70"},"dob":{"date":"1997-10-04T06:40:17.109Z","age":24},"registered":{"date":"2017-10-16T07:35:04.758Z","age":4},"phone":"(409)-451-8311","cell":"(130)-078-1623","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/men/36.jpg","medium":"https://randomuser.me/api/portraits/med/men/36.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/36.jpg"},"nat":"NZ"},{"gender":"female","name":{"title":"Miss","first":"Komal","last":"Berkelmans"},"location":{"street":{"number":2340,"name":"Aldemiede"},"city":"Noordwolde Gn","state":"Flevoland","country":"Netherlands","postcode":70449,"coordinates":{"latitude":"-37.6708","longitude":"-146.3949"},"timezone":{"offset":"-3:00","description":"Brazil, Buenos Aires, Georgetown"}},"email":"komal.berkelmans@example.com","login":{"uuid":"536b6d2a-0d95-46f3-96f1-5eb5e3796d1a","username":"redgorilla634","password":"hannibal","salt":"A9S3P8w9","md5":"dd8fe69057567431713a65df2604ad4b","sha1":"1755f9cdf5de46e533b7df9cc390f3a89b443236","sha256":"42229cd472b19e0bd2f2e665cf8cb00ec58f657c883d589071446e0dacdfde90"},"dob":{"date":"1986-07-13T18:42:54.039Z","age":35},"registered":{"date":"2004-01-21T07:43:29.300Z","age":17},"phone":"(640)-713-2078","cell":"(929)-048-1904","id":{"name":"BSN","value":"16175590"},"picture":{"large":"https://randomuser.me/api/portraits/women/35.jpg","medium":"https://randomuser.me/api/portraits/med/women/35.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/35.jpg"},"nat":"NL"},{"gender":"female","name":{"title":"Mrs","first":"یاسمن","last":"محمدخان"},"location":{"street":{"number":2708,"name":"شهید رحمانی"},"city":"مشهد","state":"آذربایجان غربی","country":"Iran","postcode":46093,"coordinates":{"latitude":"-20.9654","longitude":"80.7686"},"timezone":{"offset":"+7:00","description":"Bangkok, Hanoi, Jakarta"}},"email":"ysmn.mhmdkhn@example.com","login":{"uuid":"26a36ba7-0f26-46d8-bb5d-72217c5f43c5","username":"purplegorilla615","password":"andy","salt":"F6KhN9KE","md5":"12ca4357ac5596a9ea42b910e5f49ab5","sha1":"68131b90a671bf963d7c6ddc4dfe34921396c1ad","sha256":"d5f8f2e895d642bc05445f5da204b4de2f95c97bc1c8e10c15061b59bedf5d1a"},"dob":{"date":"1997-11-23T22:13:25.395Z","age":24},"registered":{"date":"2002-10-18T23:28:56.676Z","age":19},"phone":"075-45797323","cell":"0918-877-6630","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/women/20.jpg","medium":"https://randomuser.me/api/portraits/med/women/20.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/20.jpg"},"nat":"IR"},{"gender":"female","name":{"title":"Ms","first":"Isla","last":"Keto"},"location":{"street":{"number":9708,"name":"Tahmelantie"},"city":"Pudasjärvi","state":"Kainuu","country":"Finland","postcode":56077,"coordinates":{"latitude":"3.4501","longitude":"140.0938"},"timezone":{"offset":"-9:00","description":"Alaska"}},"email":"isla.keto@example.com","login":{"uuid":"ca1d55fc-8ecf-4789-afa8-61d010c523b8","username":"greencat517","password":"dream","salt":"G6hS5GbU","md5":"b33106e92c4ebc492643c625237a9755","sha1":"f89d2aabdc69d712a4ae0846ee8e2a969d6451d8","sha256":"5bb38aa44c05c5ee803ac5692f58d1ecca68d40098b650c303b09dcada2789de"},"dob":{"date":"1965-03-06T08:17:10.452Z","age":56},"registered":{"date":"2019-03-26T05:47:01.785Z","age":2},"phone":"05-807-033","cell":"049-985-78-07","id":{"name":"HETU","value":"NaNNA224undefined"},"picture":{"large":"https://randomuser.me/api/portraits/women/58.jpg","medium":"https://randomuser.me/api/portraits/med/women/58.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/58.jpg"},"nat":"FI"},{"gender":"male","name":{"title":"Mr","first":"Kornelius","last":"Hellmich"},"location":{"street":{"number":2506,"name":"Parkstraße"},"city":"Hohenleuben","state":"Niedersachsen","country":"Germany","postcode":77809,"coordinates":{"latitude":"-89.8782","longitude":"-111.3488"},"timezone":{"offset":"+1:00","description":"Brussels, Copenhagen, Madrid, Paris"}},"email":"kornelius.hellmich@example.com","login":{"uuid":"be54ad9f-d095-417f-b31d-c2a32cd21ab8","username":"blackkoala392","password":"katie","salt":"SiTTu5HV","md5":"5da4ab1f7e7e0c3f8b158d3da5f6baf7","sha1":"f554b9d87a76fa378680de2337f54fe192d47b51","sha256":"47fbb86db24ea3af15a5b9c2795ef69c27aace723d99392b5576fb9c3eeb102f"},"dob":{"date":"1953-07-17T01:04:06.736Z","age":68},"registered":{"date":"2009-02-15T21:06:44.914Z","age":12},"phone":"0930-3804582","cell":"0174-5883281","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/men/56.jpg","medium":"https://randomuser.me/api/portraits/med/men/56.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/56.jpg"},"nat":"DE"},{"gender":"male","name":{"title":"Mr","first":"Dariusz","last":"Birkholz"},"location":{"street":{"number":2198,"name":"Burgstraße"},"city":"Sulzbach/Saar","state":"Hessen","country":"Germany","postcode":71979,"coordinates":{"latitude":"-28.4936","longitude":"-1.3932"},"timezone":{"offset":"+7:00","description":"Bangkok, Hanoi, Jakarta"}},"email":"dariusz.birkholz@example.com","login":{"uuid":"dea1411a-187c-45f8-a870-3ef426618496","username":"heavycat808","password":"openup","salt":"RZxpkTCs","md5":"40f8d5cad7a783602d23f48f15d0fd97","sha1":"dd0ae7794bc92b9073df0ebfd0bf17a559c66e49","sha256":"37affb448bae07621272a0132a8ee9142f6400997d2dcaab1c77bb7c1dc21a3e"},"dob":{"date":"1975-06-16T23:42:48.875Z","age":46},"registered":{"date":"2003-08-10T14:28:29.144Z","age":18},"phone":"0091-4407372","cell":"0171-4507976","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/men/21.jpg","medium":"https://randomuser.me/api/portraits/med/men/21.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/21.jpg"},"nat":"DE"},{"gender":"male","name":{"title":"Mr","first":"Zackary","last":"Mitchell"},"location":{"street":{"number":5633,"name":"15th St"},"city":"Richmond","state":"Manitoba","country":"Canada","postcode":"Y5P 0R6","coordinates":{"latitude":"-61.0128","longitude":"-167.6098"},"timezone":{"offset":"-5:00","description":"Eastern Time (US & Canada), Bogota, Lima"}},"email":"zackary.mitchell@example.com","login":{"uuid":"123d0e0f-e470-46dc-9cc0-36f49c268c92","username":"smallpanda307","password":"brucelee","salt":"6Y7DpcnM","md5":"a2acc820ee0e06da5ddde7735494b5be","sha1":"83692302295bea003aa05f80a73bfe4948902c32","sha256":"60726d9362a1f234c69c1b71bf84a992d6bf64820d1bb708f74ea6d567cce4d0"},"dob":{"date":"1995-06-14T23:17:48.872Z","age":26},"registered":{"date":"2017-05-25T00:04:17.406Z","age":4},"phone":"679-927-8395","cell":"034-536-4159","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/men/70.jpg","medium":"https://randomuser.me/api/portraits/med/men/70.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/70.jpg"},"nat":"CA"},{"gender":"male","name":{"title":"Mr","first":"Bryan","last":"Lowe"},"location":{"street":{"number":1804,"name":"O'Connell Avenue"},"city":"Ballybofey-Stranorlar","state":"Cork City","country":"Ireland","postcode":27664,"coordinates":{"latitude":"79.9119","longitude":"-20.4914"},"timezone":{"offset":"+8:00","description":"Beijing, Perth, Singapore, Hong Kong"}},"email":"bryan.lowe@example.com","login":{"uuid":"5271484a-7b28-451e-a85d-a8a10e8b9013","username":"heavybear253","password":"susan1","salt":"3ADDiosn","md5":"98af703ad0551f1b7a51c0e34639159c","sha1":"9943b89b9b1e53558aa87cc08efb25462196c8a6","sha256":"f221b109bc026cf6adc2586f9ba820cdb8583b206974cf61e3a4964f3c59f9f0"},"dob":{"date":"1994-02-03T14:03:57.335Z","age":27},"registered":{"date":"2011-10-23T13:26:22.156Z","age":10},"phone":"051-409-6101","cell":"081-903-0139","id":{"name":"PPS","value":"8261917T"},"picture":{"large":"https://randomuser.me/api/portraits/men/94.jpg","medium":"https://randomuser.me/api/portraits/med/men/94.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/94.jpg"},"nat":"IE"},{"gender":"male","name":{"title":"Mr","first":"Jeffrey","last":"Peterson"},"location":{"street":{"number":6615,"name":"Miller Ave"},"city":"Australian Capital Territory","state":"South Australia","country":"Australia","postcode":4719,"coordinates":{"latitude":"15.7177","longitude":"-102.0069"},"timezone":{"offset":"+4:30","description":"Kabul"}},"email":"jeffrey.peterson@example.com","login":{"uuid":"4fa46c39-ecf9-44bb-8a90-4d083b2d3e5e","username":"bluegoose666","password":"lobster","salt":"7Yc0FyEs","md5":"6b4cc09fe7ba58d9561eab23dc616416","sha1":"7be75c7d4867d89680b195fc4b4b44c218b44753","sha256":"49102b39424e398ca94f2e38905a3ba08db27b926976f5b15dc7109a477f0845"},"dob":{"date":"1963-04-05T08:15:15.739Z","age":58},"registered":{"date":"2017-10-07T19:25:13.916Z","age":4},"phone":"03-8699-8510","cell":"0429-557-014","id":{"name":"TFN","value":"365780104"},"picture":{"large":"https://randomuser.me/api/portraits/men/75.jpg","medium":"https://randomuser.me/api/portraits/med/men/75.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/75.jpg"},"nat":"AU"},{"gender":"female","name":{"title":"Ms","first":"Ayşe","last":"Kasapoğlu"},"location":{"street":{"number":6862,"name":"Vatan Cd"},"city":"Giresun","state":"Kahramanmaraş","country":"Turkey","postcode":56149,"coordinates":{"latitude":"-40.1166","longitude":"20.2023"},"timezone":{"offset":"+7:00","description":"Bangkok, Hanoi, Jakarta"}},"email":"ayse.kasapoglu@example.com","login":{"uuid":"15dd79cd-cdde-4269-928b-1dd682a88e9d","username":"happyleopard450","password":"mybaby","salt":"7Cbd3D0n","md5":"6d40539a5809f14d2a1839bdf3768d56","sha1":"86f5560c67edcdbd2279f43e761c1c5d8c849e55","sha256":"d4889bfba0c34c5ad436bce69988f12f50a52ecd5a9fe4663173c0835cc23532"},"dob":{"date":"1993-10-23T23:45:42.876Z","age":28},"registered":{"date":"2010-04-11T09:13:17.324Z","age":11},"phone":"(671)-100-7823","cell":"(310)-638-5089","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/women/78.jpg","medium":"https://randomuser.me/api/portraits/med/women/78.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/78.jpg"},"nat":"TR"},{"gender":"male","name":{"title":"Monsieur","first":"Nick","last":"Hubert"},"location":{"street":{"number":5379,"name":"Rue de la Mairie"},"city":"Cormoret","state":"Nidwalden","country":"Switzerland","postcode":9317,"coordinates":{"latitude":"29.7417","longitude":"-56.3723"},"timezone":{"offset":"-12:00","description":"Eniwetok, Kwajalein"}},"email":"nick.hubert@example.com","login":{"uuid":"58559e6f-9d2b-4923-b8f2-199edcdd7390","username":"goldencat326","password":"bendover","salt":"odcVV86K","md5":"7f24c75b7281e8a652294c44337bd4a1","sha1":"71f1278e7e1204305798ad52060e2db977d25d02","sha256":"a2e475db447ce1f9534d478e24035e72067f76e29ed9687f9db179b29bd3a67f"},"dob":{"date":"1967-06-02T17:20:04.211Z","age":54},"registered":{"date":"2014-05-30T05:12:06.918Z","age":7},"phone":"078 205 22 68","cell":"079 812 79 17","id":{"name":"AVS","value":"756.6735.5365.47"},"picture":{"large":"https://randomuser.me/api/portraits/men/71.jpg","medium":"https://randomuser.me/api/portraits/med/men/71.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/71.jpg"},"nat":"CH"},{"gender":"female","name":{"title":"Miss","first":"Johanna","last":"Habers"},"location":{"street":{"number":6905,"name":"Kornelle"},"city":"Venlo","state":"Groningen","country":"Netherlands","postcode":46317,"coordinates":{"latitude":"-33.8903","longitude":"52.5099"},"timezone":{"offset":"+9:00","description":"Tokyo, Seoul, Osaka, Sapporo, Yakutsk"}},"email":"johanna.habers@example.com","login":{"uuid":"f3c12456-c5dc-4852-bd3a-c902a1ddea67","username":"redfrog236","password":"sinned","salt":"vV4cyQBW","md5":"7f5292bd37396d7a436511e50c7dbd66","sha1":"53ba84fcaed978598167613734113d7af457bcfa","sha256":"77d98b43ec68948e2e0c6c6689c44328609fe531f46de4b9264d70aeab327cd8"},"dob":{"date":"1986-08-22T07:02:40.037Z","age":35},"registered":{"date":"2015-03-27T08:13:18.049Z","age":6},"phone":"(416)-825-4431","cell":"(278)-720-9292","id":{"name":"BSN","value":"96192364"},"picture":{"large":"https://randomuser.me/api/portraits/women/10.jpg","medium":"https://randomuser.me/api/portraits/med/women/10.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/10.jpg"},"nat":"NL"},{"gender":"female","name":{"title":"Miss","first":"Melissa","last":"Ryan"},"location":{"street":{"number":9347,"name":"Victoria Road"},"city":"Newry","state":"Northamptonshire","country":"United Kingdom","postcode":"T5A 6FN","coordinates":{"latitude":"47.4443","longitude":"-6.8244"},"timezone":{"offset":"+8:00","description":"Beijing, Perth, Singapore, Hong Kong"}},"email":"melissa.ryan@example.com","login":{"uuid":"2e655370-df73-426c-b7cf-0df7ca169e64","username":"brownpeacock599","password":"teng","salt":"wcAd61ca","md5":"80688e1baebf78da6e08e88471e1e8c7","sha1":"87bebdb1ade64c76eb0e44b402d3fd4ab604783b","sha256":"915821dd2edcf138553344f4a4b21beed80769f388d02bc50560570e817847d5"},"dob":{"date":"1990-11-21T17:56:43.591Z","age":31},"registered":{"date":"2009-08-07T19:11:20.523Z","age":12},"phone":"016977 94479","cell":"0703-656-533","id":{"name":"NINO","value":"PW 08 21 44 J"},"picture":{"large":"https://randomuser.me/api/portraits/women/93.jpg","medium":"https://randomuser.me/api/portraits/med/women/93.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/93.jpg"},"nat":"GB"},{"gender":"male","name":{"title":"Mr","first":"Fatih","last":"Kocabıyık"},"location":{"street":{"number":9402,"name":"Kushimoto Sk"},"city":"Kahramanmaraş","state":"Trabzon","country":"Turkey","postcode":93662,"coordinates":{"latitude":"-25.5150","longitude":"-128.6270"},"timezone":{"offset":"-3:30","description":"Newfoundland"}},"email":"fatih.kocabiyik@example.com","login":{"uuid":"9242fe80-e699-4535-a9e0-c1f8f173a615","username":"beautifulostrich240","password":"anton","salt":"C6vUtZHh","md5":"b078335ac9a3b8deea3567525b981b2c","sha1":"226a9ebcb0decabd063a1f97eadcc64b3602bcd2","sha256":"1fd9cc6b4eac958c3e3f8dfdc7c63c2279548708836886be1c67fdfd5fe5d995"},"dob":{"date":"1993-03-08T06:29:33.350Z","age":28},"registered":{"date":"2011-03-04T10:51:08.784Z","age":10},"phone":"(806)-393-4381","cell":"(591)-569-7616","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/men/86.jpg","medium":"https://randomuser.me/api/portraits/med/men/86.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/86.jpg"},"nat":"TR"},{"gender":"female","name":{"title":"Ms","first":"May","last":"Bergstrøm"},"location":{"street":{"number":6880,"name":"Finnmarkgata"},"city":"Grua","state":"Hordaland","country":"Norway","postcode":"8181","coordinates":{"latitude":"-58.6223","longitude":"113.0504"},"timezone":{"offset":"+4:30","description":"Kabul"}},"email":"may.bergstrom@example.com","login":{"uuid":"7db0a8b6-2fdc-47f6-862a-7fb216c63a03","username":"heavyostrich146","password":"1a2b3c4d","salt":"u23rDmJV","md5":"108a5fb35aa3d814f6edd4501be9e6b1","sha1":"98ad44c239b86d69da7e9cbc036f533d65b390f2","sha256":"0633811cdcaaf40d8bf4869ac7d8b20f29d618770a02ad2f784fa675c4a7a319"},"dob":{"date":"1965-04-07T13:51:59.419Z","age":56},"registered":{"date":"2005-11-29T13:03:51.852Z","age":16},"phone":"84952761","cell":"42371016","id":{"name":"FN","value":"07046523231"},"picture":{"large":"https://randomuser.me/api/portraits/women/82.jpg","medium":"https://randomuser.me/api/portraits/med/women/82.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/82.jpg"},"nat":"NO"},{"gender":"male","name":{"title":"Mr","first":"Abbas","last":"Mydland"},"location":{"street":{"number":5859,"name":"Hammerstads gate"},"city":"Ekeberg","state":"Bergen","country":"Norway","postcode":"7791","coordinates":{"latitude":"-60.3183","longitude":"-171.9749"},"timezone":{"offset":"-10:00","description":"Hawaii"}},"email":"abbas.mydland@example.com","login":{"uuid":"53fd6e95-e2bc-4c3c-a0d4-cfaa352e9391","username":"ticklishsnake907","password":"testibil","salt":"Uk8bbCWb","md5":"266921d21a624aacc42bc08885fc7229","sha1":"3cabaca3a20611bb9e70cead51e3556b4610590a","sha256":"867a7b57424a0fa462c80988a580c4037e89f10fed734d236eda1d13c894a0de"},"dob":{"date":"1986-02-11T03:07:42.506Z","age":35},"registered":{"date":"2012-10-29T03:11:58.191Z","age":9},"phone":"71476357","cell":"93911840","id":{"name":"FN","value":"11028649586"},"picture":{"large":"https://randomuser.me/api/portraits/men/33.jpg","medium":"https://randomuser.me/api/portraits/med/men/33.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/33.jpg"},"nat":"NO"},{"gender":"male","name":{"title":"Mr","first":"John","last":"Hall"},"location":{"street":{"number":7955,"name":"W 6th St"},"city":"Tamworth","state":"Western Australia","country":"Australia","postcode":812,"coordinates":{"latitude":"75.4430","longitude":"-119.5802"},"timezone":{"offset":"-1:00","description":"Azores, Cape Verde Islands"}},"email":"john.hall@example.com","login":{"uuid":"57b4d5f7-8774-4d66-830d-6fab8605168c","username":"purpleswan372","password":"fantasy","salt":"Ky6PK3mQ","md5":"23a4594c3d392cf29fd999c843fe9546","sha1":"6d382d32bf5d72cd23b79a48b0c32c9903b0be71","sha256":"e998b72f35f4caeac4af1c1b81d6eea9ecb799a2905e575f1be0c4957ef21426"},"dob":{"date":"1947-07-25T00:06:36.942Z","age":74},"registered":{"date":"2002-09-28T16:02:56.026Z","age":19},"phone":"05-6740-9753","cell":"0453-511-431","id":{"name":"TFN","value":"253803558"},"picture":{"large":"https://randomuser.me/api/portraits/men/83.jpg","medium":"https://randomuser.me/api/portraits/med/men/83.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/83.jpg"},"nat":"AU"},{"gender":"male","name":{"title":"Mr","first":"Kasper","last":"Møller"},"location":{"street":{"number":4885,"name":"Ordrupvej"},"city":"København Ø","state":"Nordjylland","country":"Denmark","postcode":24214,"coordinates":{"latitude":"-68.2506","longitude":"35.5047"},"timezone":{"offset":"-7:00","description":"Mountain Time (US & Canada)"}},"email":"kasper.moller@example.com","login":{"uuid":"dd0946db-c420-4b81-99c9-5515ac1783c4","username":"brownduck421","password":"gonzalez","salt":"DytN4xfT","md5":"b186ec86696b6b402de7ec4b77e3c5c0","sha1":"e6ed5f3b9667af31b877cc6336eea32775632739","sha256":"02f30e9761fd35d577f92574a0860d7e080355dfac1a048d95deb9ca5a74aaa5"},"dob":{"date":"1959-12-02T00:18:24.123Z","age":62},"registered":{"date":"2013-03-25T05:14:02.474Z","age":8},"phone":"75484872","cell":"25219533","id":{"name":"CPR","value":"021259-4076"},"picture":{"large":"https://randomuser.me/api/portraits/men/32.jpg","medium":"https://randomuser.me/api/portraits/med/men/32.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/32.jpg"},"nat":"DK"},{"gender":"male","name":{"title":"Mr","first":"Felix","last":"Snyder"},"location":{"street":{"number":2139,"name":"Mcclellan Rd"},"city":"Albury","state":"South Australia","country":"Australia","postcode":5515,"coordinates":{"latitude":"85.2023","longitude":"-35.6942"},"timezone":{"offset":"-1:00","description":"Azores, Cape Verde Islands"}},"email":"felix.snyder@example.com","login":{"uuid":"c3a12f75-3e29-448d-9da1-dc2c3626b40d","username":"smallgoose905","password":"stargate","salt":"G0VZBgBC","md5":"f8e21eed45ba7c4c0419765232301fa6","sha1":"0681b6bac060aa54ddbde6a8ef3c5e2925685649","sha256":"cbc8ade0a76285ed465bcb80e640b4486c02b82da53fdd104b16b0d5805d4872"},"dob":{"date":"1972-10-25T07:49:54.059Z","age":49},"registered":{"date":"2007-06-24T16:33:21.889Z","age":14},"phone":"00-0093-4876","cell":"0472-997-722","id":{"name":"TFN","value":"431628425"},"picture":{"large":"https://randomuser.me/api/portraits/men/25.jpg","medium":"https://randomuser.me/api/portraits/med/men/25.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/25.jpg"},"nat":"AU"},{"gender":"female","name":{"title":"Ms","first":"Justine","last":"Roy"},"location":{"street":{"number":1699,"name":"Elgin St"},"city":"Trenton","state":"Northwest Territories","country":"Canada","postcode":"S2W 9K6","coordinates":{"latitude":"50.2238","longitude":"-104.8400"},"timezone":{"offset":"-9:00","description":"Alaska"}},"email":"justine.roy@example.com","login":{"uuid":"e5cf0598-cba6-48da-b862-c9334d911c35","username":"greendog323","password":"knicks","salt":"r26i5zDO","md5":"80d429d3ab83411d30b4e540be582df4","sha1":"4feb956185667c0b7e301a7503268d414ea24983","sha256":"5526aff804fe4d545147455710b7a4b999333c0be05b1918ed04e3e6df7d8ce1"},"dob":{"date":"1991-02-16T23:54:41.189Z","age":30},"registered":{"date":"2011-05-25T14:30:11.634Z","age":10},"phone":"327-651-0474","cell":"261-927-7865","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/women/61.jpg","medium":"https://randomuser.me/api/portraits/med/women/61.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/61.jpg"},"nat":"CA"},{"gender":"female","name":{"title":"Miss","first":"Jen","last":"Fisher"},"location":{"street":{"number":5917,"name":"School Lane"},"city":"Armagh","state":"Dorset","country":"United Kingdom","postcode":"I74 0TZ","coordinates":{"latitude":"-15.2710","longitude":"6.1135"},"timezone":{"offset":"+7:00","description":"Bangkok, Hanoi, Jakarta"}},"email":"jen.fisher@example.com","login":{"uuid":"1160400d-284c-462f-bac1-5f4b885db8ae","username":"sadostrich739","password":"frogman","salt":"RhPuOK8b","md5":"a801b58ec1ee3bff7951ffa17490a062","sha1":"71ae070b6ccd5ee3604d6ebb073cccf4464bfc38","sha256":"3f7e1549c37f578441e31a5731713e52e7b3a5b35ebc3d132c39aa67870c2316"},"dob":{"date":"1987-10-19T05:51:52.830Z","age":34},"registered":{"date":"2014-10-13T00:44:34.288Z","age":7},"phone":"015394 47276","cell":"0746-667-150","id":{"name":"NINO","value":"CN 16 46 41 C"},"picture":{"large":"https://randomuser.me/api/portraits/women/51.jpg","medium":"https://randomuser.me/api/portraits/med/women/51.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/51.jpg"},"nat":"GB"},{"gender":"female","name":{"title":"Miss","first":"Katie","last":"Dean"},"location":{"street":{"number":5648,"name":"West Street"},"city":"St Davids","state":"County Tyrone","country":"United Kingdom","postcode":"AX1U 5SW","coordinates":{"latitude":"-67.0207","longitude":"15.3252"},"timezone":{"offset":"-2:00","description":"Mid-Atlantic"}},"email":"katie.dean@example.com","login":{"uuid":"2766a443-2275-4bf9-a05d-57bae9f15bc4","username":"happydog462","password":"lakota","salt":"4E80pzkq","md5":"1a7cdc7ef5a1ddd93b9466b98ff762eb","sha1":"4915db9317e9b8658ca24b6af67661711d738dc0","sha256":"700f48e561fbb5f473f709af6e3fadcbc319364faa7b19e7fd4ec2d2bd095748"},"dob":{"date":"1974-08-13T15:06:03.079Z","age":47},"registered":{"date":"2013-07-10T00:24:32.387Z","age":8},"phone":"027 8423 7724","cell":"0751-014-776","id":{"name":"NINO","value":"PT 26 14 25 R"},"picture":{"large":"https://randomuser.me/api/portraits/women/32.jpg","medium":"https://randomuser.me/api/portraits/med/women/32.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/32.jpg"},"nat":"GB"},{"gender":"male","name":{"title":"Mr","first":"Arnaldo","last":"Nogueira"},"location":{"street":{"number":6883,"name":"Rua da Paz "},"city":"Taboão da Serra","state":"Bahia","country":"Brazil","postcode":27687,"coordinates":{"latitude":"-57.6106","longitude":"-35.3412"},"timezone":{"offset":"+6:00","description":"Almaty, Dhaka, Colombo"}},"email":"arnaldo.nogueira@example.com","login":{"uuid":"cbe652b5-0a7c-4e04-b2c1-dd8a159f1574","username":"crazywolf125","password":"property","salt":"f86MNWVw","md5":"dad0c7e7543db6d1d2cf33e540fcb8b7","sha1":"9111e3c99c61bd7f7c3702925afc25ebcfb3ea07","sha256":"66d175423b03639d7fcd35754de34e11908f8320da1b09743d6cffe26d2b6352"},"dob":{"date":"1948-03-24T04:21:47.218Z","age":73},"registered":{"date":"2008-04-14T21:36:28.763Z","age":13},"phone":"(70) 7353-3367","cell":"(10) 4713-0499","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/men/30.jpg","medium":"https://randomuser.me/api/portraits/med/men/30.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/30.jpg"},"nat":"BR"},{"gender":"female","name":{"title":"Mrs","first":"Esther","last":"Myers"},"location":{"street":{"number":9053,"name":"Mockingbird Hill"},"city":"Frisco","state":"Connecticut","country":"United States","postcode":63650,"coordinates":{"latitude":"-41.0383","longitude":"-120.5588"},"timezone":{"offset":"+3:30","description":"Tehran"}},"email":"esther.myers@example.com","login":{"uuid":"6eac7c98-2d38-4cd6-b265-fde809398912","username":"greenpanda976","password":"chipper","salt":"6cq0jby5","md5":"1cf88cfef038ef8c2c2edfcb204c8f5b","sha1":"be3c5b92f9a3ae594b6b50a4f02e009e9376cfea","sha256":"7d0838c28debcc540057e89cab7d78e6d0ea6a4776ab9fe850b0b3c3c2a01be5"},"dob":{"date":"1944-12-27T06:00:37.539Z","age":77},"registered":{"date":"2006-07-31T14:27:01.458Z","age":15},"phone":"(335)-837-4438","cell":"(190)-212-2225","id":{"name":"SSN","value":"661-81-3929"},"picture":{"large":"https://randomuser.me/api/portraits/women/89.jpg","medium":"https://randomuser.me/api/portraits/med/women/89.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/89.jpg"},"nat":"US"},{"gender":"female","name":{"title":"Miss","first":"Melinda","last":"Coleman"},"location":{"street":{"number":8001,"name":"Ranchview Dr"},"city":"Stanley","state":"Louisiana","country":"United States","postcode":58314,"coordinates":{"latitude":"56.0736","longitude":"-78.0937"},"timezone":{"offset":"+10:00","description":"Eastern Australia, Guam, Vladivostok"}},"email":"melinda.coleman@example.com","login":{"uuid":"2917d967-bc68-4591-b8cb-6468e16faf85","username":"smallbutterfly599","password":"saratoga","salt":"EolbX9eF","md5":"d77457ee34f2da21d96d07ba44e71c6a","sha1":"ed48185be8f84c6d054dd6c7a52d91d18183f31d","sha256":"ffbcc386566cc5b32d4797434f58dca69d210ec7cd7c87c65216e17cd94b5c30"},"dob":{"date":"1976-05-26T05:12:32.743Z","age":45},"registered":{"date":"2013-07-29T22:59:55.049Z","age":8},"phone":"(339)-141-4395","cell":"(782)-065-1103","id":{"name":"SSN","value":"487-67-6156"},"picture":{"large":"https://randomuser.me/api/portraits/women/22.jpg","medium":"https://randomuser.me/api/portraits/med/women/22.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/22.jpg"},"nat":"US"},{"gender":"female","name":{"title":"Miss","first":"Lea","last":"Christiansen"},"location":{"street":{"number":7091,"name":"Frederiksgade"},"city":"Gjerlev","state":"Hovedstaden","country":"Denmark","postcode":81749,"coordinates":{"latitude":"30.2818","longitude":"1.3470"},"timezone":{"offset":"0:00","description":"Western Europe Time, London, Lisbon, Casablanca"}},"email":"lea.christiansen@example.com","login":{"uuid":"bbebb1e8-b82a-4bec-a7b7-84bd1da5c4bd","username":"blackpeacock737","password":"awful","salt":"Mvg9avTw","md5":"15e7536754470a06c7d1ece6e8ccfda2","sha1":"96c3d40551ae842c5802498c4eb8e138925613d6","sha256":"41df86039c1d57fadfce542775a10a149aff717732539b751464c273b4b26f72"},"dob":{"date":"1961-02-28T23:26:07.869Z","age":60},"registered":{"date":"2016-08-22T02:50:11.777Z","age":5},"phone":"48068859","cell":"76635906","id":{"name":"CPR","value":"280261-4618"},"picture":{"large":"https://randomuser.me/api/portraits/women/9.jpg","medium":"https://randomuser.me/api/portraits/med/women/9.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/9.jpg"},"nat":"DK"},{"gender":"male","name":{"title":"Mr","first":"Vincent","last":"Bélanger"},"location":{"street":{"number":8517,"name":"Park Rd"},"city":"Sidney","state":"British Columbia","country":"Canada","postcode":"G3L 7B7","coordinates":{"latitude":"-54.8022","longitude":"34.0017"},"timezone":{"offset":"+9:30","description":"Adelaide, Darwin"}},"email":"vincent.belanger@example.com","login":{"uuid":"9d5c7d3e-48d4-4181-9267-e41d8c448dba","username":"silverfrog407","password":"bernie","salt":"I9YsGMYg","md5":"86a32c8e2d92ce369a2a9d714836544b","sha1":"01bb8d338d35bb155ca4a9a1d3c798cd55d92f80","sha256":"0e9c875e830e219a45e608e0f343d20e86295ca5c074a7f54f817d9d37760c70"},"dob":{"date":"1950-01-08T06:42:35.576Z","age":71},"registered":{"date":"2016-07-14T07:56:23.768Z","age":5},"phone":"549-163-9296","cell":"832-047-0921","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/men/30.jpg","medium":"https://randomuser.me/api/portraits/med/men/30.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/30.jpg"},"nat":"CA"},{"gender":"male","name":{"title":"Mr","first":"Edvaldo","last":"Araújo"},"location":{"street":{"number":981,"name":"Rua Mato Grosso "},"city":"Varginha","state":"Goiás","country":"Brazil","postcode":21880,"coordinates":{"latitude":"-68.0300","longitude":"-157.6147"},"timezone":{"offset":"-1:00","description":"Azores, Cape Verde Islands"}},"email":"edvaldo.araujo@example.com","login":{"uuid":"7719fc1a-ce3d-44bc-931b-87e69e83c673","username":"brownmeercat721","password":"161616","salt":"OY3pAOm0","md5":"92e5996757d6fb58ea39af31b05c54cd","sha1":"8edd0bae2e2f30a894fc5ecb4c9d0a509e497b9b","sha256":"30c9dddc389e5c2e5f236e59459333cff3299215e34fcda9254cb39133c48a3d"},"dob":{"date":"1974-09-02T00:42:51.111Z","age":47},"registered":{"date":"2018-10-09T02:08:50.379Z","age":3},"phone":"(53) 5691-5243","cell":"(46) 7811-8069","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/men/78.jpg","medium":"https://randomuser.me/api/portraits/med/men/78.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/78.jpg"},"nat":"BR"},{"gender":"male","name":{"title":"Mr","first":"Gabriel","last":"Nogueira"},"location":{"street":{"number":5247,"name":"Rua São Pedro "},"city":"Codó","state":"Amapá","country":"Brazil","postcode":60176,"coordinates":{"latitude":"7.4103","longitude":"136.7956"},"timezone":{"offset":"+6:00","description":"Almaty, Dhaka, Colombo"}},"email":"gabriel.nogueira@example.com","login":{"uuid":"f5d63079-439f-4a9c-9a60-5aad5fe570e7","username":"purplepanda825","password":"kajak","salt":"x7hdwzya","md5":"3a593b5764fe1d0b0db7e070973555ca","sha1":"2edd4af2cea2d67a106d52904ca41135b813bb81","sha256":"836af6fa2898fba396456102915bbac1555e3a12b78e97ba5af944c294472e3b"},"dob":{"date":"1952-11-25T23:31:02.064Z","age":69},"registered":{"date":"2010-12-18T16:39:44.956Z","age":11},"phone":"(02) 5343-1902","cell":"(93) 9253-4303","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/men/77.jpg","medium":"https://randomuser.me/api/portraits/med/men/77.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/77.jpg"},"nat":"BR"},{"gender":"female","name":{"title":"Ms","first":"Julie","last":"Carpentier"},"location":{"street":{"number":4502,"name":"Rue de L'Abbé-Rousselot"},"city":"Orléans","state":"Aisne","country":"France","postcode":78814,"coordinates":{"latitude":"15.3736","longitude":"-111.0813"},"timezone":{"offset":"-5:00","description":"Eastern Time (US & Canada), Bogota, Lima"}},"email":"julie.carpentier@example.com","login":{"uuid":"d5112510-be2a-436b-8801-53092a6fbeaf","username":"happygoose155","password":"tyson","salt":"X8ACTLFo","md5":"ed6d00db1a80c6c1337f744737f27bac","sha1":"fb9a13d5e6df46ea595a43fe4ea6efd917ede1dc","sha256":"2d3674bb35c5674e61dd086a551c9291c8ca014fb372dd9340f9eaf7ccba3f79"},"dob":{"date":"1994-05-31T08:09:53.113Z","age":27},"registered":{"date":"2006-11-16T15:32:35.128Z","age":15},"phone":"05-67-59-22-99","cell":"06-52-43-54-55","id":{"name":"INSEE","value":"2NNaN51747573 96"},"picture":{"large":"https://randomuser.me/api/portraits/women/80.jpg","medium":"https://randomuser.me/api/portraits/med/women/80.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/80.jpg"},"nat":"FR"},{"gender":"female","name":{"title":"Miss","first":"Eva","last":"Mccoy"},"location":{"street":{"number":6388,"name":"Manchester Road"},"city":"Swansea","state":"South Glamorgan","country":"United Kingdom","postcode":"Q54 2TD","coordinates":{"latitude":"-24.3546","longitude":"168.6662"},"timezone":{"offset":"-7:00","description":"Mountain Time (US & Canada)"}},"email":"eva.mccoy@example.com","login":{"uuid":"6b69c159-70b2-4531-bde4-f07d1f063a1c","username":"goldenduck690","password":"prosper","salt":"dviJ80eV","md5":"f56a74c0666eb677d10e4fe04d607cf6","sha1":"08cfbcb272d28817fe329552db9291d97fcd69ef","sha256":"9ee0e2e54b8810d825f6f8d05ce08f70658fbdc83260e915c97c85aa250128cb"},"dob":{"date":"1974-09-27T23:42:40.619Z","age":47},"registered":{"date":"2005-03-07T00:08:12.812Z","age":16},"phone":"016974 04276","cell":"0739-481-744","id":{"name":"NINO","value":"BR 77 74 13 K"},"picture":{"large":"https://randomuser.me/api/portraits/women/44.jpg","medium":"https://randomuser.me/api/portraits/med/women/44.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/44.jpg"},"nat":"GB"},{"gender":"female","name":{"title":"Mrs","first":"Agnieszka","last":"Dobber"},"location":{"street":{"number":1881,"name":"Brugsteen"},"city":"Sint Maartensvlotbrug","state":"Noord-Brabant","country":"Netherlands","postcode":88488,"coordinates":{"latitude":"16.7147","longitude":"9.1406"},"timezone":{"offset":"-7:00","description":"Mountain Time (US & Canada)"}},"email":"agnieszka.dobber@example.com","login":{"uuid":"f1aae98d-46b0-468e-91af-971a69f03b86","username":"angrybutterfly508","password":"123457","salt":"GnKO3GxG","md5":"ed134554e1235f0fb2ea5b7a0ab7e513","sha1":"f434be0320ba0c7109de14f2bea5200c9c622469","sha256":"75696bc2668865cf5ee5dc5fd19b21abd2832cc435c3521d921b2dddd6fe0b1b"},"dob":{"date":"1969-06-22T15:30:32.660Z","age":52},"registered":{"date":"2014-06-02T11:31:35.985Z","age":7},"phone":"(237)-407-3742","cell":"(056)-023-4129","id":{"name":"BSN","value":"00907412"},"picture":{"large":"https://randomuser.me/api/portraits/women/1.jpg","medium":"https://randomuser.me/api/portraits/med/women/1.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/1.jpg"},"nat":"NL"},{"gender":"male","name":{"title":"Mr","first":"Nathaniel","last":"Caldwell"},"location":{"street":{"number":2176,"name":"Lovers Ln"},"city":"Bundaberg","state":"Queensland","country":"Australia","postcode":1333,"coordinates":{"latitude":"7.1232","longitude":"95.7873"},"timezone":{"offset":"-11:00","description":"Midway Island, Samoa"}},"email":"nathaniel.caldwell@example.com","login":{"uuid":"fc6353de-bbaa-4506-864d-1fda288e1be8","username":"goldenladybug965","password":"poohbear","salt":"bOdhzGeb","md5":"59a3fff1be08258fb9119517337748a7","sha1":"41542157b39268f8f8ee8392247a9df9dc5b458f","sha256":"8711b8c5ed883766fef030b733b7cfa539d98408b4c96b04ce90b8f598509ad9"},"dob":{"date":"1971-11-15T19:15:09.018Z","age":50},"registered":{"date":"2013-04-11T05:15:47.326Z","age":8},"phone":"07-6886-7903","cell":"0425-179-360","id":{"name":"TFN","value":"257617138"},"picture":{"large":"https://randomuser.me/api/portraits/men/86.jpg","medium":"https://randomuser.me/api/portraits/med/men/86.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/86.jpg"},"nat":"AU"},{"gender":"female","name":{"title":"Mrs","first":"Maria","last":"Sørensen"},"location":{"street":{"number":8435,"name":"Byvangen"},"city":"Esbjerg V","state":"Syddanmark","country":"Denmark","postcode":20334,"coordinates":{"latitude":"-86.8788","longitude":"90.9681"},"timezone":{"offset":"+11:00","description":"Magadan, Solomon Islands, New Caledonia"}},"email":"maria.sorensen@example.com","login":{"uuid":"45176f96-d0c0-466f-bd9c-d0c446469574","username":"happysnake754","password":"bootie","salt":"1ECY3obl","md5":"6eb402952ff6a8f8cc3881c43179716c","sha1":"8b11bb2beb11debb6ce2309fe8399fa4eb4cb35d","sha256":"7db1f8a54ae25f42966674c2b6ff61a42d53b7e44c98b80142e3d31ba863c66e"},"dob":{"date":"1945-01-09T18:36:17.624Z","age":76},"registered":{"date":"2010-05-26T08:38:43.024Z","age":11},"phone":"67057930","cell":"78537303","id":{"name":"CPR","value":"090145-7907"},"picture":{"large":"https://randomuser.me/api/portraits/women/34.jpg","medium":"https://randomuser.me/api/portraits/med/women/34.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/34.jpg"},"nat":"DK"},{"gender":"male","name":{"title":"Mr","first":"Gregory","last":"Bishop"},"location":{"street":{"number":1169,"name":"Park Avenue"},"city":"Tralee","state":"Carlow","country":"Ireland","postcode":81141,"coordinates":{"latitude":"44.1833","longitude":"-37.9988"},"timezone":{"offset":"+7:00","description":"Bangkok, Hanoi, Jakarta"}},"email":"gregory.bishop@example.com","login":{"uuid":"8cb2bb5e-8c82-4652-a9e5-06e179e368ed","username":"browngoose950","password":"kahlua","salt":"YHNdXy8A","md5":"fd5175161fa5dacebb86e05c2688e665","sha1":"66ff5c02202b40aabd9aed4830dd592afb5afda8","sha256":"8c0705edca141ac31e4d334b20b902d6050cfa18f51267802b110a9d43c7b64b"},"dob":{"date":"1957-12-06T13:26:15.687Z","age":64},"registered":{"date":"2006-04-26T07:14:17.227Z","age":15},"phone":"041-735-0534","cell":"081-455-5751","id":{"name":"PPS","value":"8770565T"},"picture":{"large":"https://randomuser.me/api/portraits/men/5.jpg","medium":"https://randomuser.me/api/portraits/med/men/5.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/5.jpg"},"nat":"IE"},{"gender":"female","name":{"title":"Mrs","first":"Elizabeth","last":"Grewal"},"location":{"street":{"number":6152,"name":"Lake of Bays Road"},"city":"Shelbourne","state":"Nunavut","country":"Canada","postcode":"C8H 2I9","coordinates":{"latitude":"-28.5566","longitude":"-90.9217"},"timezone":{"offset":"-12:00","description":"Eniwetok, Kwajalein"}},"email":"elizabeth.grewal@example.com","login":{"uuid":"d23120d3-3d6b-4bd5-b2b7-4a72c9130f26","username":"tinybear885","password":"rufus","salt":"jKYbz7qk","md5":"3651b484edb49308223f7e28984304c4","sha1":"58dfe43ce7f7ac1074925d593e0d1df66ba78e7c","sha256":"b43dc2272f0475fb2abe5f86be21ba2e8428ea24ddcee0ba66484d97d31c227b"},"dob":{"date":"1988-12-01T20:20:27.593Z","age":33},"registered":{"date":"2012-11-26T07:22:03.280Z","age":9},"phone":"049-636-8909","cell":"465-132-9681","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/women/95.jpg","medium":"https://randomuser.me/api/portraits/med/women/95.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/95.jpg"},"nat":"CA"},{"gender":"male","name":{"title":"Mr","first":"Larry","last":"Jensen"},"location":{"street":{"number":6948,"name":"Highfield Road"},"city":"Mallow","state":"Mayo","country":"Ireland","postcode":36483,"coordinates":{"latitude":"-3.9633","longitude":"-178.9777"},"timezone":{"offset":"+5:00","description":"Ekaterinburg, Islamabad, Karachi, Tashkent"}},"email":"larry.jensen@example.com","login":{"uuid":"c4c41690-cfcb-427f-a490-b29edf7403a2","username":"goldenbird646","password":"audrey","salt":"R9alVirL","md5":"58f6da0a5029e6c60bb742c07114ddfe","sha1":"7fdb7361163ac18e9e9051fa9bc66f9fcccb61d3","sha256":"08e3dd6017420547fa9d8a50ec9ab61937996a591a7c3756c83f441ce602ab4a"},"dob":{"date":"1954-01-22T21:30:30.525Z","age":67},"registered":{"date":"2017-01-31T02:43:48.519Z","age":4},"phone":"071-813-6808","cell":"081-641-1598","id":{"name":"PPS","value":"6255761T"},"picture":{"large":"https://randomuser.me/api/portraits/men/13.jpg","medium":"https://randomuser.me/api/portraits/med/men/13.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/13.jpg"},"nat":"IE"},{"gender":"female","name":{"title":"Mrs","first":"Leone","last":"Lieftink"},"location":{"street":{"number":302,"name":"Hendrik Idostraat"},"city":"Nieuw-Beerta","state":"Overijssel","country":"Netherlands","postcode":41918,"coordinates":{"latitude":"52.0025","longitude":"73.1569"},"timezone":{"offset":"+11:00","description":"Magadan, Solomon Islands, New Caledonia"}},"email":"leone.lieftink@example.com","login":{"uuid":"3fdbacff-4bd5-4f91-9695-a639ef890aaa","username":"organicsnake334","password":"getting","salt":"UoH67f7Y","md5":"54d81a3b6ac39006a677a1a142e4a268","sha1":"c8fb09f386d96aeefbb1ce15f79f88ae09cdd569","sha256":"b7564793f905354800f1b4b053253d1456dfce44ca3f567702efdfe966f02ab3"},"dob":{"date":"1977-07-20T05:50:29.442Z","age":44},"registered":{"date":"2007-04-25T05:46:01.241Z","age":14},"phone":"(848)-265-6076","cell":"(975)-218-5909","id":{"name":"BSN","value":"90345718"},"picture":{"large":"https://randomuser.me/api/portraits/women/17.jpg","medium":"https://randomuser.me/api/portraits/med/women/17.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/17.jpg"},"nat":"NL"},{"gender":"male","name":{"title":"Mr","first":"Acílio","last":"Nogueira"},"location":{"street":{"number":5972,"name":"Rua São Jorge "},"city":"Parnamirim","state":"Pernambuco","country":"Brazil","postcode":92605,"coordinates":{"latitude":"-81.4829","longitude":"-135.6538"},"timezone":{"offset":"+2:00","description":"Kaliningrad, South Africa"}},"email":"acilio.nogueira@example.com","login":{"uuid":"8d28123e-6772-4343-a702-e8f971fa103f","username":"heavycat538","password":"lopez","salt":"wAWtVdQg","md5":"70db281dc70cee681359380d8d892901","sha1":"4ecb5f9a657a25b1dc5c09a3a0172a7690415a5f","sha256":"bba065ee3db1730df06862cc8e5650a41cd9b39e071289db4c17252b83eb157e"},"dob":{"date":"1967-07-19T06:42:51.746Z","age":54},"registered":{"date":"2002-08-24T12:22:38.805Z","age":19},"phone":"(81) 8581-6167","cell":"(50) 9368-3874","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/men/33.jpg","medium":"https://randomuser.me/api/portraits/med/men/33.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/33.jpg"},"nat":"BR"},{"gender":"female","name":{"title":"Mrs","first":"Connie","last":"Baker"},"location":{"street":{"number":6568,"name":"W Sherman Dr"},"city":"Lubbock","state":"South Carolina","country":"United States","postcode":61013,"coordinates":{"latitude":"-72.7458","longitude":"-71.8347"},"timezone":{"offset":"-3:30","description":"Newfoundland"}},"email":"connie.baker@example.com","login":{"uuid":"025ee3b1-e1b0-407b-aa81-81fd0f867482","username":"lazyleopard834","password":"dddd","salt":"EqUb1rXK","md5":"f583c751e7da6426c4eae9c13e4301e4","sha1":"a00e182cc859e7e0125049d8b34248d4311bb323","sha256":"c1f95102108d1381e1d63fb56bc4255fa5ef52b460e98f07680ae561d2bd77ed"},"dob":{"date":"1996-11-18T09:41:20.660Z","age":25},"registered":{"date":"2008-12-11T22:53:18.287Z","age":13},"phone":"(951)-124-5686","cell":"(778)-078-6106","id":{"name":"SSN","value":"070-21-6724"},"picture":{"large":"https://randomuser.me/api/portraits/women/9.jpg","medium":"https://randomuser.me/api/portraits/med/women/9.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/9.jpg"},"nat":"US"},{"gender":"female","name":{"title":"Mrs","first":"Joelle","last":"Schijvens"},"location":{"street":{"number":8657,"name":"Houterveld"},"city":"Ohe en Laak","state":"Utrecht","country":"Netherlands","postcode":42711,"coordinates":{"latitude":"-24.3082","longitude":"46.4339"},"timezone":{"offset":"-3:00","description":"Brazil, Buenos Aires, Georgetown"}},"email":"joelle.schijvens@example.com","login":{"uuid":"5ec4daff-d810-43e8-9b12-65b9cd02177e","username":"greenkoala392","password":"bradley","salt":"Flshk8ov","md5":"7ed178083afeb72f5084bb4b0c977c0c","sha1":"b6d9cefcddc35cb85f675bcd0f94e1ed630a8f67","sha256":"0913967114a949755dc0d21385eebfe8a0438300d211ac6e9241536d1caed12e"},"dob":{"date":"1960-02-26T03:54:06.733Z","age":61},"registered":{"date":"2011-05-28T07:26:55.225Z","age":10},"phone":"(615)-248-9823","cell":"(310)-427-0134","id":{"name":"BSN","value":"78795004"},"picture":{"large":"https://randomuser.me/api/portraits/women/2.jpg","medium":"https://randomuser.me/api/portraits/med/women/2.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/2.jpg"},"nat":"NL"},{"gender":"female","name":{"title":"Miss","first":"Anna","last":"Olsen"},"location":{"street":{"number":9207,"name":"Helsingevej"},"city":"Lundby","state":"Sjælland","country":"Denmark","postcode":94132,"coordinates":{"latitude":"50.8961","longitude":"-176.8461"},"timezone":{"offset":"+8:00","description":"Beijing, Perth, Singapore, Hong Kong"}},"email":"anna.olsen@example.com","login":{"uuid":"7adaf598-f700-4e7f-ba68-6e7d9c2200bd","username":"greencat525","password":"surprise","salt":"42VDejZ6","md5":"517ba74ecee91f5f8266c680d686ea7d","sha1":"89b035e8223b25503e8ee4a3b043356bb661ed35","sha256":"34299cb7aa4e1c3c194d9d826e980bf762d4819dcd5210415c175365c7fbdf9a"},"dob":{"date":"1946-03-26T11:53:05.204Z","age":75},"registered":{"date":"2012-06-18T18:11:38.396Z","age":9},"phone":"48268566","cell":"22581115","id":{"name":"CPR","value":"260346-9805"},"picture":{"large":"https://randomuser.me/api/portraits/women/87.jpg","medium":"https://randomuser.me/api/portraits/med/women/87.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/87.jpg"},"nat":"DK"},{"gender":"male","name":{"title":"Mr","first":"Jean","last":"Marie"},"location":{"street":{"number":6206,"name":"Rue de la Gare"},"city":"Lyon","state":"Hauts-de-Seine","country":"France","postcode":35660,"coordinates":{"latitude":"-44.9682","longitude":"-44.8879"},"timezone":{"offset":"+11:00","description":"Magadan, Solomon Islands, New Caledonia"}},"email":"jean.marie@example.com","login":{"uuid":"620a6d80-de33-4b70-8a38-2300ccfe9252","username":"orangeswan487","password":"1001","salt":"GfkMif4R","md5":"4c682c4b3b23f8aa059c5b50234b0400","sha1":"6696cee352750880b667d87bfd0fd71cf0a9f428","sha256":"0cb5d5a0b4a88a4ccc293d29308ab46c320326f1163895fa08ef78b8a6dcfda9"},"dob":{"date":"1985-02-12T21:15:49.406Z","age":36},"registered":{"date":"2005-04-14T08:13:41.595Z","age":16},"phone":"03-60-75-82-73","cell":"06-17-19-06-86","id":{"name":"INSEE","value":"1NNaN10647947 92"},"picture":{"large":"https://randomuser.me/api/portraits/men/73.jpg","medium":"https://randomuser.me/api/portraits/med/men/73.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/73.jpg"},"nat":"FR"},{"gender":"male","name":{"title":"Mr","first":"Helge","last":"Lyse"},"location":{"street":{"number":6066,"name":"Vilberggrenda"},"city":"Dokka","state":"Akershus","country":"Norway","postcode":"6981","coordinates":{"latitude":"-44.6710","longitude":"-28.4880"},"timezone":{"offset":"-4:00","description":"Atlantic Time (Canada), Caracas, La Paz"}},"email":"helge.lyse@example.com","login":{"uuid":"bbea4083-4add-4e24-8f1b-ab5896a97bba","username":"blackdog405","password":"honolulu","salt":"A1fxNXqq","md5":"2b8fa96cfe006fa9676ad82024e93f7b","sha1":"16dff0e0d7123f58373f03a676a4548cd8767882","sha256":"556da372e47149db700fbd9b6ff947846b892394cba163498ff11ae0ee736ce5"},"dob":{"date":"1996-05-06T10:24:32.616Z","age":25},"registered":{"date":"2017-04-07T01:43:37.763Z","age":4},"phone":"69363107","cell":"97110651","id":{"name":"FN","value":"06059602126"},"picture":{"large":"https://randomuser.me/api/portraits/men/91.jpg","medium":"https://randomuser.me/api/portraits/med/men/91.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/91.jpg"},"nat":"NO"},{"gender":"female","name":{"title":"Mrs","first":"آدرینا","last":"سالاری"},"location":{"street":{"number":9746,"name":"میدان شهیدان رحیمی"},"city":"خمینی‌شهر","state":"فارس","country":"Iran","postcode":14581,"coordinates":{"latitude":"-8.8769","longitude":"-87.0712"},"timezone":{"offset":"+8:00","description":"Beijing, Perth, Singapore, Hong Kong"}},"email":"adryn.slry@example.com","login":{"uuid":"2ebfd665-ce06-4a7c-9a42-cb171ae48775","username":"blackduck701","password":"goodman","salt":"znpbiJH0","md5":"012b61b62bcb37f193526a2667350e4b","sha1":"618dd86498acc3e5dc44978dfb60e72510c6890b","sha256":"00adc9d1bfa2cf85c94d47de6638f84b2584f24decccff34ef2e5b77afde5d22"},"dob":{"date":"1984-07-13T21:08:46.138Z","age":37},"registered":{"date":"2018-01-13T19:34:11.269Z","age":3},"phone":"082-66120229","cell":"0976-859-4574","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/women/58.jpg","medium":"https://randomuser.me/api/portraits/med/women/58.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/58.jpg"},"nat":"IR"},{"gender":"male","name":{"title":"Mr","first":"Willard","last":"Myers"},"location":{"street":{"number":6569,"name":"Adams St"},"city":"Orange","state":"South Australia","country":"Australia","postcode":6105,"coordinates":{"latitude":"-59.9419","longitude":"-74.1866"},"timezone":{"offset":"+4:30","description":"Kabul"}},"email":"willard.myers@example.com","login":{"uuid":"ccb40f3f-4ea2-4e35-a688-bc3dee9a6506","username":"organickoala420","password":"sissy","salt":"EZPrTXL6","md5":"e912ba2bd7269c33de6475a73c2dff4d","sha1":"46c1c8725e1816aed4827e3f5bdbc2f65e5e0b2d","sha256":"9cc76fd690b4937a415b9a927e0088929c87d91c8c13097fb8ae52a6909332cc"},"dob":{"date":"1991-08-03T01:55:31.478Z","age":30},"registered":{"date":"2012-03-07T14:56:32.646Z","age":9},"phone":"01-7611-9378","cell":"0414-396-951","id":{"name":"TFN","value":"769243247"},"picture":{"large":"https://randomuser.me/api/portraits/men/66.jpg","medium":"https://randomuser.me/api/portraits/med/men/66.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/66.jpg"},"nat":"AU"},{"gender":"female","name":{"title":"Ms","first":"Eline","last":"Guerin"},"location":{"street":{"number":1304,"name":"Rue Pasteur"},"city":"Champigny-sur-Marne","state":"Corrèze","country":"France","postcode":22379,"coordinates":{"latitude":"-78.9531","longitude":"152.2866"},"timezone":{"offset":"+5:45","description":"Kathmandu"}},"email":"eline.guerin@example.com","login":{"uuid":"d00e4b8d-6f7f-4349-b5db-9cf94bf61af0","username":"tinypeacock402","password":"paragon","salt":"jT2xrU5q","md5":"039ff4920d123b5b3343212b216d655d","sha1":"7fab3c9cba987e777be11ad1e55c3c282d2a49b6","sha256":"3743531dc10f9af9bc797739947ae19866cd2b1989dacf7808013d956bf1e03d"},"dob":{"date":"1979-08-12T08:44:15.525Z","age":42},"registered":{"date":"2012-08-11T15:09:12.919Z","age":9},"phone":"04-30-37-32-15","cell":"06-25-03-02-51","id":{"name":"INSEE","value":"2NNaN15658548 53"},"picture":{"large":"https://randomuser.me/api/portraits/women/42.jpg","medium":"https://randomuser.me/api/portraits/med/women/42.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/42.jpg"},"nat":"FR"},{"gender":"female","name":{"title":"Miss","first":"النا","last":"رضاییان"},"location":{"street":{"number":3667,"name":"شهید محمد منتظری"},"city":"پاکدشت","state":"خراسان رضوی","country":"Iran","postcode":48182,"coordinates":{"latitude":"-14.9343","longitude":"127.7279"},"timezone":{"offset":"+1:00","description":"Brussels, Copenhagen, Madrid, Paris"}},"email":"ln.rdyyn@example.com","login":{"uuid":"38ecd61c-da01-4454-90c5-75d0d9580f9a","username":"tinygorilla237","password":"fossil","salt":"wjF20LIw","md5":"ce3ed3f33aa4f6ea244cf0bfb94a5b5b","sha1":"4389bac847b6ab4a8c6866425e4924e4c280179e","sha256":"d2006dac0cee666f873a2dd2dbb5b26454bdb4aa1382f8c89fe46dfa29a2bd03"},"dob":{"date":"1982-04-07T14:48:43.510Z","age":39},"registered":{"date":"2012-11-14T08:26:29.937Z","age":9},"phone":"093-50496433","cell":"0980-906-8841","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/women/4.jpg","medium":"https://randomuser.me/api/portraits/med/women/4.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/4.jpg"},"nat":"IR"},{"gender":"male","name":{"title":"Mr","first":"Siegbert","last":"Holland"},"location":{"street":{"number":1357,"name":"Mühlweg"},"city":"Titisee-Neustadt","state":"Bayern","country":"Germany","postcode":46995,"coordinates":{"latitude":"48.1976","longitude":"-53.1283"},"timezone":{"offset":"+11:00","description":"Magadan, Solomon Islands, New Caledonia"}},"email":"siegbert.holland@example.com","login":{"uuid":"92f89aee-8d6d-4828-9d39-e67bf05cf45f","username":"organicfish151","password":"catcat","salt":"qCIk6xMy","md5":"66db8d1afcde285fda949e43ddef53ae","sha1":"f5642758e709f58e30062df226e2de6d46826aaf","sha256":"7eab534fa594201d040b8a8e0033ba6cdfa2fc467ea7a6b72ec6cb894d7d76bf"},"dob":{"date":"1988-12-04T01:59:14.180Z","age":33},"registered":{"date":"2007-07-15T09:31:47.597Z","age":14},"phone":"0914-7278671","cell":"0176-3149434","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/men/28.jpg","medium":"https://randomuser.me/api/portraits/med/men/28.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/28.jpg"},"nat":"DE"},{"gender":"male","name":{"title":"Mr","first":"Jason","last":"Schmidt"},"location":{"street":{"number":1128,"name":"Groveland Terrace"},"city":"New Orleans","state":"Nebraska","country":"United States","postcode":57873,"coordinates":{"latitude":"2.9640","longitude":"134.2332"},"timezone":{"offset":"+5:30","description":"Bombay, Calcutta, Madras, New Delhi"}},"email":"jason.schmidt@example.com","login":{"uuid":"f92d70ba-9306-4adf-8327-1a05a8985690","username":"lazyostrich933","password":"mollie","salt":"PaXhJXOB","md5":"c4ccd4babe03b3e51dd36cd972d9556b","sha1":"bcd7cf4a4a95fb0dd95f5e93c2588bb9f9a78ade","sha256":"a58268a016263f4d53fd27e668cbc153555b208e54e66a57705baf803144467f"},"dob":{"date":"1995-06-30T07:31:31.427Z","age":26},"registered":{"date":"2012-07-06T01:46:42.642Z","age":9},"phone":"(150)-508-9059","cell":"(677)-731-5961","id":{"name":"SSN","value":"452-43-7241"},"picture":{"large":"https://randomuser.me/api/portraits/men/87.jpg","medium":"https://randomuser.me/api/portraits/med/men/87.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/87.jpg"},"nat":"US"},{"gender":"female","name":{"title":"Ms","first":"Henny","last":"Frigstad"},"location":{"street":{"number":3501,"name":"Dalskroken"},"city":"Vennesla","state":"Hordaland","country":"Norway","postcode":"2839","coordinates":{"latitude":"82.8851","longitude":"-16.4630"},"timezone":{"offset":"-12:00","description":"Eniwetok, Kwajalein"}},"email":"henny.frigstad@example.com","login":{"uuid":"5aec52b3-0635-4150-8ae3-be139ac4b809","username":"blackrabbit766","password":"earl","salt":"Zwf7bi2G","md5":"1825e203f0d649673425c799fbbf2eb2","sha1":"d2601c97020db8f76b8e167c39b7180ce7db5992","sha256":"02cda6e9cb26e3837b9878baa0cf523b5600cd1ef4f1b3763c73aae4c034b631"},"dob":{"date":"1974-04-07T11:19:00.102Z","age":47},"registered":{"date":"2008-10-24T17:23:55.950Z","age":13},"phone":"33345284","cell":"95726144","id":{"name":"FN","value":"07047423249"},"picture":{"large":"https://randomuser.me/api/portraits/women/36.jpg","medium":"https://randomuser.me/api/portraits/med/women/36.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/36.jpg"},"nat":"NO"},{"gender":"female","name":{"title":"Ms","first":"Teja","last":"Skorstad"},"location":{"street":{"number":4889,"name":"Wessels gate"},"city":"Askim","state":"Hedmark","country":"Norway","postcode":"5464","coordinates":{"latitude":"-50.1197","longitude":"-12.8217"},"timezone":{"offset":"+7:00","description":"Bangkok, Hanoi, Jakarta"}},"email":"teja.skorstad@example.com","login":{"uuid":"f9c0d426-75e0-4685-b39c-e7e5b5d8111a","username":"happyostrich693","password":"kiss","salt":"RzJb6zFk","md5":"a39c01b71a5c05b8784f13f58aaa0b5e","sha1":"3b98c783f60e929dd81ec0282c725e5c72e15dfa","sha256":"87648d54df7bbd6ac3fa06f18d4b3f0566966e4d54f0db7a80fa0f731459df9b"},"dob":{"date":"1950-07-26T23:55:41.782Z","age":71},"registered":{"date":"2008-01-30T19:05:06.933Z","age":13},"phone":"70883837","cell":"98389505","id":{"name":"FN","value":"26075028007"},"picture":{"large":"https://randomuser.me/api/portraits/women/95.jpg","medium":"https://randomuser.me/api/portraits/med/women/95.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/95.jpg"},"nat":"NO"},{"gender":"male","name":{"title":"Monsieur","first":"Yves","last":"Boyer"},"location":{"street":{"number":7010,"name":"Rue Victor-Hugo"},"city":"Rossa","state":"Graubünden","country":"Switzerland","postcode":9308,"coordinates":{"latitude":"-61.8199","longitude":"142.9664"},"timezone":{"offset":"-5:00","description":"Eastern Time (US & Canada), Bogota, Lima"}},"email":"yves.boyer@example.com","login":{"uuid":"8de0a5f6-74d1-49f2-9afc-a3bdfa0fab33","username":"angrytiger903","password":"2626","salt":"CBsFDxqB","md5":"af075ce5959756f3fc56bbca9cb7c44c","sha1":"591688ac0e901f63330c63d9f7cf459b4f60b32a","sha256":"49a3a8958cfb6685265b65370395d4ccc2b3c4fdabd391967cd6786646299755"},"dob":{"date":"1982-02-26T20:04:32.139Z","age":39},"registered":{"date":"2002-04-23T13:28:49.971Z","age":19},"phone":"079 164 86 89","cell":"075 398 36 90","id":{"name":"AVS","value":"756.9774.9100.54"},"picture":{"large":"https://randomuser.me/api/portraits/men/1.jpg","medium":"https://randomuser.me/api/portraits/med/men/1.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/1.jpg"},"nat":"CH"},{"gender":"male","name":{"title":"Monsieur","first":"Joel","last":"Leroux"},"location":{"street":{"number":3457,"name":"Rue de la Fontaine"},"city":"Halten","state":"Glarus","country":"Switzerland","postcode":4880,"coordinates":{"latitude":"-29.9917","longitude":"27.9004"},"timezone":{"offset":"+8:00","description":"Beijing, Perth, Singapore, Hong Kong"}},"email":"joel.leroux@example.com","login":{"uuid":"5de4739c-07a0-463d-b7e9-4ca3544b202a","username":"happybear806","password":"johndeer","salt":"pJgLxzSt","md5":"a083f004af3877de58a34d00d4b1a517","sha1":"76fb464fe671f35a1393c1711c181167ac55bd15","sha256":"e376993c18109018b887cfa5425038ff63a99fecc41c6f25306e6f7fd37e5d6f"},"dob":{"date":"1984-12-28T23:35:24.390Z","age":37},"registered":{"date":"2015-07-14T16:19:01.769Z","age":6},"phone":"079 225 46 70","cell":"076 915 81 40","id":{"name":"AVS","value":"756.4447.1182.01"},"picture":{"large":"https://randomuser.me/api/portraits/men/2.jpg","medium":"https://randomuser.me/api/portraits/med/men/2.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/2.jpg"},"nat":"CH"},{"gender":"male","name":{"title":"Mr","first":"Batur","last":"Tüzün"},"location":{"street":{"number":5292,"name":"Şehitler Cd"},"city":"Bitlis","state":"Iğdır","country":"Turkey","postcode":50041,"coordinates":{"latitude":"6.3960","longitude":"132.4001"},"timezone":{"offset":"+8:00","description":"Beijing, Perth, Singapore, Hong Kong"}},"email":"batur.tuzun@example.com","login":{"uuid":"d4091942-17b2-4f00-bc0e-ddec95d16ba5","username":"ticklishsnake493","password":"temppass","salt":"2ImKJa3s","md5":"348e3dd73259c6023027923b32997b7f","sha1":"b40ac085cfc6c2d7eb690e9755e05f04124ae873","sha256":"7a21dc8ea66c71772a8d45ac048472128fd3068dd594ec6c89217ed30ccb08f4"},"dob":{"date":"1945-09-28T03:49:37.880Z","age":76},"registered":{"date":"2009-06-04T06:59:39.147Z","age":12},"phone":"(793)-147-5376","cell":"(444)-206-1368","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/men/9.jpg","medium":"https://randomuser.me/api/portraits/med/men/9.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/9.jpg"},"nat":"TR"},{"gender":"female","name":{"title":"Ms","first":"Mina","last":"Koers"},"location":{"street":{"number":6307,"name":"Amsteloord"},"city":"Ooij","state":"Utrecht","country":"Netherlands","postcode":12201,"coordinates":{"latitude":"10.3303","longitude":"100.5135"},"timezone":{"offset":"-9:00","description":"Alaska"}},"email":"mina.koers@example.com","login":{"uuid":"c5f12e61-c0d0-4485-acdd-fa96ea9e3a5a","username":"heavypanda144","password":"skinner","salt":"qqZdTdas","md5":"06e8df54d419442745b5ab0a93254d70","sha1":"f4704cdef556a9a45ee51f8ba59251ace915f3e3","sha256":"2e8d0478b8b35dca838d4e5a6f7f6e7d94fd422fd1ca9bdd05724e05198a1587"},"dob":{"date":"1961-02-12T04:48:11.561Z","age":60},"registered":{"date":"2008-08-19T10:47:54.726Z","age":13},"phone":"(390)-509-4899","cell":"(209)-952-1230","id":{"name":"BSN","value":"87112415"},"picture":{"large":"https://randomuser.me/api/portraits/women/41.jpg","medium":"https://randomuser.me/api/portraits/med/women/41.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/41.jpg"},"nat":"NL"},{"gender":"male","name":{"title":"Mr","first":"Valtteri","last":"Neva"},"location":{"street":{"number":3739,"name":"Aleksanterinkatu"},"city":"Kuortane","state":"Uusimaa","country":"Finland","postcode":15213,"coordinates":{"latitude":"65.9678","longitude":"-71.0725"},"timezone":{"offset":"+2:00","description":"Kaliningrad, South Africa"}},"email":"valtteri.neva@example.com","login":{"uuid":"00d8ac60-fc86-4859-9266-3485d1598d14","username":"beautifulleopard849","password":"standard","salt":"PsTw9Hbh","md5":"acb1c30ae46bdeaaab1e7240f9579804","sha1":"fb11c85c18f8f687882507278ba6bb8607d45852","sha256":"d2a2be73e6f317233e5bc4ca6ae3e5d3641998ad234c23c1a5d583ae585c58b8"},"dob":{"date":"1990-07-10T05:42:36.073Z","age":31},"registered":{"date":"2013-02-14T08:38:09.261Z","age":8},"phone":"06-082-582","cell":"041-908-43-23","id":{"name":"HETU","value":"NaNNA277undefined"},"picture":{"large":"https://randomuser.me/api/portraits/men/25.jpg","medium":"https://randomuser.me/api/portraits/med/men/25.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/25.jpg"},"nat":"FI"},{"gender":"female","name":{"title":"Ms","first":"Luna","last":"Mercier"},"location":{"street":{"number":4358,"name":"Rue Victor-Hugo"},"city":"Besançon","state":"Haute-Vienne","country":"France","postcode":20172,"coordinates":{"latitude":"-18.3781","longitude":"-9.2685"},"timezone":{"offset":"+5:30","description":"Bombay, Calcutta, Madras, New Delhi"}},"email":"luna.mercier@example.com","login":{"uuid":"92797927-64ae-461b-a335-4a5c87e7dc33","username":"purplerabbit999","password":"bill","salt":"qAR7FI84","md5":"b68756fa0bd7b82586f9afd2aa46ccfb","sha1":"aad0e91ad180f5c9e00d294d8f2d297512ea0a7e","sha256":"b014ebd6126fb778def55794c65e244780912a56b6f70f6e7e2c4a3c6b95ad63"},"dob":{"date":"1983-11-24T13:23:02.577Z","age":38},"registered":{"date":"2007-10-20T04:34:48.545Z","age":14},"phone":"01-19-20-81-99","cell":"06-91-14-60-15","id":{"name":"INSEE","value":"2NNaN97920746 90"},"picture":{"large":"https://randomuser.me/api/portraits/women/86.jpg","medium":"https://randomuser.me/api/portraits/med/women/86.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/86.jpg"},"nat":"FR"},{"gender":"male","name":{"title":"Mr","first":"سهیل","last":"رضایی"},"location":{"street":{"number":6252,"name":"هویزه"},"city":"بابل","state":"چهارمحال و بختیاری","country":"Iran","postcode":59374,"coordinates":{"latitude":"3.0872","longitude":"-92.1987"},"timezone":{"offset":"-3:30","description":"Newfoundland"}},"email":"shyl.rdyy@example.com","login":{"uuid":"2f85571c-a055-4d63-b09f-8fcd7177dc5e","username":"purplesnake325","password":"tian","salt":"RAHc4tdK","md5":"e0e07b4b38f1c7e250e802945d91fcc2","sha1":"d6899a8dd58db1a662cd926f8fa8aac0d444477e","sha256":"1627f80e268fd8a70576748902957e4686fa6ee3341cc9f8678a996437340fe7"},"dob":{"date":"1971-03-18T21:15:20.899Z","age":50},"registered":{"date":"2014-03-16T13:57:50.563Z","age":7},"phone":"043-61040816","cell":"0918-699-1846","id":{"name":"","value":null},"picture":{"large":"https://randomuser.me/api/portraits/men/74.jpg","medium":"https://randomuser.me/api/portraits/med/men/74.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/74.jpg"},"nat":"IR"},{"gender":"male","name":{"title":"Mr","first":"Rémy","last":"Andre"},"location":{"street":{"number":4778,"name":"Place de L'Église"},"city":"Strasbourg","state":"Cantal","country":"France","postcode":30249,"coordinates":{"latitude":"3.7167","longitude":"-71.8789"},"timezone":{"offset":"+5:30","description":"Bombay, Calcutta, Madras, New Delhi"}},"email":"remy.andre@example.com","login":{"uuid":"4101f67c-cbb3-4ffc-8336-6193d64882ca","username":"ticklishleopard505","password":"nuan","salt":"teb7iSGO","md5":"54cd5df6c9a8ef0bcfade3edaef01de9","sha1":"b2cdd32890a1596caff8372ad30bab65016ef533","sha256":"fff92849510ef88280ed71f70e237d2864b8b0685f593b6d8505afb96425bbdc"},"dob":{"date":"1980-01-21T03:52:33.162Z","age":41},"registered":{"date":"2012-05-13T23:24:38.654Z","age":9},"phone":"01-18-42-25-40","cell":"06-32-47-53-43","id":{"name":"INSEE","value":"1NNaN28596414 63"},"picture":{"large":"https://randomuser.me/api/portraits/men/32.jpg","medium":"https://randomuser.me/api/portraits/med/men/32.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/32.jpg"},"nat":"FR"}],"info":{"seed":"982aec686336d126","results":100,"page":1,"version":"1.3"}} -------------------------------------------------------------------------------- /RandomUsers/Shared/RootView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RandomUsers App 3 | // Created by Freek (github.com/frzi) 2021 4 | // 5 | 6 | import SwiftUI 7 | import SwiftUIRouter 8 | 9 | struct RootView: View { 10 | @EnvironmentObject private var navigator: Navigator 11 | 12 | var body: some View { 13 | VStack { 14 | #if os(iOS) 15 | HStack { 16 | Spacer() 17 | toolbarContents() 18 | .buttonStyle(.borderedProminent) 19 | } 20 | .padding(.horizontal, 20) 21 | #endif 22 | /// (2) Render the top level routes. See (3). 23 | RootRoutes() 24 | TabBar() 25 | } 26 | #if os(macOS) 27 | .toolbar { 28 | toolbarContents() 29 | } 30 | #endif 31 | /// To better keep track of the current path we'll print it to the console every time it changes. 32 | /// This would also be a great time to store the current path to UserDefaults/AppStorage, or send it to a 33 | /// backend for analytic reasons. 34 | .onChange(of: navigator.path) { newPath in 35 | print("Current path:", newPath) 36 | } 37 | } 38 | 39 | @ViewBuilder 40 | private func toolbarContents() -> some View { 41 | Button(action: { navigator.goBack() }) { 42 | Image(systemName: "arrow.left") 43 | } 44 | .disabled(!navigator.canGoBack) 45 | .help("Go back") 46 | 47 | Button(action: { navigator.goForward() }) { 48 | Image(systemName: "arrow.right") 49 | } 50 | .disabled(!navigator.canGoForward) 51 | .help("Go forward") 52 | 53 | Button(action: { navigator.clear() }) { 54 | Image(systemName: "clear") 55 | } 56 | .disabled(!navigator.canGoBack && !navigator.canGoForward) 57 | .help("Clear history stacks") 58 | 59 | Button(action: { navigator.navigate("..") }) { 60 | Image(systemName: "arrow.turn.left.up") 61 | } 62 | .disabled(navigator.path == "/users" || navigator.path == "/shortcuts") 63 | .help("Go to parent") 64 | } 65 | } 66 | 67 | // MARK: - Routes 68 | /// (3) The only purpose of this view is to determine what to render depending on the path. 69 | /// By using a simple view like this we can better separate our routing logic without obfuscating it with unrelated 70 | /// code. 71 | /// A component like this is called a 'Routes view', or simply 'Middleware'. 72 | private struct RootRoutes: View { 73 | var body: some View { 74 | /// (4) A `SwitchRoutes` is like a `switch`, but for routes. Only the first matching `Route` will be rendered. 75 | /// This allows you to create 'fallback' routes (shown below), as well as gain potentional performance boost: 76 | /// once a route has been matched, any following routes can immediately skip any work on path matching. 77 | SwitchRoutes { 78 | /// (5) The first defined route. If the current path is `/shortcuts`, the `ShortcutsScreen` view will be 79 | /// rendered. Note the lack of `/` in the defined path. This is due to all paths in SwiftUI Router being 80 | /// relative to the first parent route. (In this case that would be the `Router`) 81 | Route("shortcuts", content: ShortcutsScreen()) 82 | 83 | /// (6) A wildcard (`*`) is used in this path to indicate this route should also render `UsersScreen` for 84 | /// deeper paths (e.g. `/users/foobar/etc`). We will handle the routing logic for deeper paths in 85 | /// `UsersScreen`. 86 | Route("users/*", content: UsersScreen()) 87 | 88 | /// (7) By default a `Route` has `*` as its path, meaning it will always match, regardless of the current 89 | /// path. However, since this route is declared in a `SwitchRoutes`, once a preceding route has already 90 | /// matched this route will get ignored. This route is a so-called 'fallback route'. You can use this 91 | /// to show a "404 not found" message. Or redirect to another path; as shown below: 92 | Route { 93 | /// (8) Immediately redirect the user to `/users` once this view is rendered. An alternative could be 94 | /// to render an error message. 95 | Navigate(to: "/users", replace: true) 96 | } 97 | } 98 | .navigationTransition() 99 | } 100 | } 101 | 102 | // MARK: - Custom Tab bar 103 | /// (9) Because SwiftUI Router uses its own states for navigation it's not made to work with SwiftUI's builtin TabView. 104 | /// Though one can get both TabView and SwiftUI Router to work together, with a little bit of extra code. 105 | /// However, in the interest of keeping things straightforward, we use a custom tab bar to utilize SwiftUI Router's 106 | /// `NavLink` button. 107 | private struct TabBar: View { 108 | @EnvironmentObject private var navigator: Navigator 109 | 110 | var body: some View { 111 | HStack { 112 | TabBarButton(path: "/users", systemImage: "person.2", title: "User list") 113 | TabBarButton(path: "/shortcuts", systemImage: "arrow.up.right.square", title: "Shortcuts") 114 | } 115 | .font(.system(size: 16)) 116 | .buttonStyle(.plain) 117 | .frame(height: 70) 118 | } 119 | 120 | private func TabBarButton(path: String, systemImage: String, title: String) -> some View { 121 | /// (10) A `NavLink` is a wrapper around a Button that, when pressed, will navigate to the given path. 122 | /// A `NavLink` passes down a `Bool` to its child views to indicate whether its path matches that of the current 123 | /// path. This gives you the opportunity to stylize your `NavLink`s accordingly. 124 | NavLink(to: path) { active in 125 | VStack { 126 | Image(systemName: active ? systemImage + ".fill" : systemImage) 127 | .font(.system(size: 20)) 128 | Text(title) 129 | .fontWeight(active ? .bold : .regular) 130 | } 131 | } 132 | .frame(maxWidth: .infinity) 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /RandomUsers/Shared/Screens/ShortcutsScreen.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RandomUsers App 3 | // Created by Freek (github.com/frzi) 2021 4 | // 5 | 6 | import Foundation 7 | import SwiftUI 8 | import SwiftUIRouter 9 | 10 | /// (18) This screen was added to demonstrate how easy it is to navigate to another parth of the app, as well as the 11 | /// results of navigating to a path that doesn't exist, or isn't valid 12 | struct ShortcutsScreen: View { 13 | @EnvironmentObject private var usersData: UsersData 14 | 15 | var body: some View { 16 | let firstUser = usersData.users[0] 17 | let secondUser = usersData.users[1] 18 | 19 | return GeometryReader { _ in 20 | List { 21 | Text("Shortcuts") 22 | .font(.title) 23 | 24 | Text( 25 | """ 26 | This screen demonstrates the flexibility of working with path-based routing. 27 | Below are several links to different screens. 28 | """ 29 | ) 30 | .font(.body) 31 | 32 | /// Navigates to the detail screen of a user. 33 | RowButton(path: "/users/" + firstUser.id.uuidString) { 34 | Text("Go to **\(firstUser.fullName)**'s page") 35 | } 36 | 37 | /// Navgiates to the map screen (`UserLocationScreen`) of a user. A screen that, hierarchy wise, is 38 | /// several layers deep. Yet, with a single path we can navigate to it, effortlessly! 39 | RowButton(path: "/users/" + secondUser.id.uuidString + "/location") { 40 | Text("Go to **\(secondUser.fullName)**'s map") 41 | } 42 | 43 | /// Navigates to a user that doesn't exist. In `UsersScreen` we programmed a fallback for invalid paths 44 | /// to users (see (12), (13) and (14)). 45 | RowButton(path: "/users/fakeuuid") { 46 | Text("Go to a non-existent user") 47 | } 48 | 49 | /// Navigates to a path that's completely non-existent. In `RootRoutes` we programmed a fallback route 50 | /// that redirects the user back to `/users` (see (7)). 51 | RowButton(path: "/foo/bar") { 52 | Text("Go to `/foo/bar`, a non-existent path.") 53 | } 54 | } 55 | .listStyle(.plain) 56 | } 57 | } 58 | 59 | private func RowButton(path: String, @ViewBuilder content: @escaping () -> Content) -> some View { 60 | NavLink(to: path) { 61 | HStack { 62 | content() 63 | Spacer() 64 | Image(systemName: "chevron.right") 65 | } 66 | .padding(.vertical, 6) 67 | } 68 | .buttonStyle(.bordered) 69 | .frame(maxWidth: .infinity) 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /RandomUsers/Shared/Screens/UserDetailScreen.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RandomUsers App 3 | // Created by Freek (github.com/frzi) 2021 4 | // 5 | 6 | import Foundation 7 | import SwiftUI 8 | import SwiftUIRouter 9 | 10 | /// (17) Again a very simple view with nothing but a `SwitchRoutes` and some routes. 11 | struct UserDetailScreen: View { 12 | let user: UserModel 13 | 14 | var body: some View { 15 | SwitchRoutes { 16 | Route("location") { 17 | UserLocationScreen(location: user.location) 18 | } 19 | Route { 20 | UserDetails(user: user) 21 | } 22 | } 23 | } 24 | } 25 | 26 | // MARK: - 27 | private struct UserDetails: View { 28 | let user: UserModel 29 | 30 | var body: some View { 31 | GeometryReader { _ in 32 | VStack(alignment: .leading, spacing: 10) { 33 | HStack(spacing: 20) { 34 | AsyncImage(url: user.picture.large) 35 | .cornerRadius(40) 36 | .frame(width: 140, height: 140) 37 | 38 | VStack(alignment: .leading, spacing: 4) { 39 | Text(user.name.title) 40 | Text(user.name.first + " " + user.name.last) 41 | .font(.system(size: 40)) 42 | .fontWeight(.bold) 43 | } 44 | } 45 | 46 | DetailRow(title: "Email", systemImage: "envelope") { 47 | Text(user.email) 48 | } 49 | 50 | DetailRow(title: "Date of Birth", systemImage: "calendar") { 51 | Text(user.dob.date) 52 | } 53 | 54 | DetailRow(title: "Location", systemImage: "pin") { 55 | NavLink(to: "location") { 56 | HStack { 57 | Text(user.location.city + ", " + user.location.country) 58 | Image(systemName: "chevron.right") 59 | } 60 | } 61 | } 62 | } 63 | } 64 | .padding(20) 65 | } 66 | 67 | private func DetailRow( 68 | title: String, 69 | systemImage: String, 70 | @ViewBuilder content: () -> Content 71 | ) -> some View { 72 | HStack { 73 | Label(title, systemImage: systemImage) 74 | .font(.system(size: 16, weight: .bold)) 75 | Spacer() 76 | content() 77 | } 78 | .font(.system(size: 16)) 79 | .padding(.vertical, 6) 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /RandomUsers/Shared/Screens/UserLocationScreen.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RandomUsers App 3 | // Created by Freek (github.com/frzi) 2021 4 | // 5 | 6 | import Foundation 7 | import MapKit 8 | import SwiftUI 9 | 10 | struct UserLocationScreen: View { 11 | let location: UserModel.Location 12 | 13 | @State private var uuid = UUID() 14 | @State private var region: MKCoordinateRegion 15 | 16 | init(location: UserModel.Location) { 17 | self._region = State(initialValue: MKCoordinateRegion( 18 | center: location.coordinates.clLocation, 19 | latitudinalMeters: 1e4, 20 | longitudinalMeters: 1e4 21 | )) 22 | 23 | self.location = location 24 | } 25 | 26 | private var pin: LocationPin { 27 | LocationPin(id: uuid, location: location.coordinates.clLocation) 28 | } 29 | 30 | var body: some View { 31 | ZStack(alignment: .topTrailing) { 32 | Map(coordinateRegion: $region, annotationItems: [pin]) { pin in 33 | MapPin(coordinate: pin.location, tint: .blue) 34 | } 35 | 36 | Text("*Note:* coordinates generated by randomuser.me tend to be pretty bogus.") 37 | .foregroundColor(.white) 38 | .padding(6) 39 | .background(Color.black.opacity(0.5)) 40 | } 41 | } 42 | 43 | private struct LocationPin: Identifiable { 44 | let id: UUID 45 | let location: CLLocationCoordinate2D 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /RandomUsers/Shared/Screens/UsersScreen.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RandomUsers App 3 | // Created by Freek (github.com/frzi) 2021 4 | // 5 | 6 | import Foundation 7 | import SwiftUI 8 | import SwiftUIRouter 9 | 10 | /// (11) Another view whose only job is to define routes, though this time it comes with some additional logic. 11 | struct UsersScreen: View { 12 | @EnvironmentObject private var routeInformation: RouteInformation 13 | @EnvironmentObject private var usersData: UsersData 14 | 15 | var body: some View { 16 | SwitchRoutes { 17 | /// (12) A route with a parameter (aka a placeholder). The `:uuid` placeholder can be anything. 18 | /// We use the `validator` option to add an extra layer of validation to our route (see (15)). If the 19 | /// validator function returns `nil`, the route will be ignored. This time we want to make sure the `:uuid` 20 | /// placeholder contains a valid UUID as well as make sure the UUID is associated with an actual user. 21 | /// If the validator found a matching user, said user will be passed down to the child views. We then 22 | /// render the `UserDetailScreen` view, passing it the user found via the validator. 23 | Route(":uuid/*", validator: findUser) { user in 24 | UserDetailScreen(user: user) 25 | } 26 | 27 | /// (13) If the previous route failed, but the path still contains more component than we need, redirect 28 | /// the user to the path this view is defined in. (In this case `/users`) 29 | Route(":anything/*") { route in 30 | Navigate(to: routeInformation.path) 31 | .onAppear { 32 | print("Path \(route.path) doesn't exist. Redirecting to \(routeInformation.path)") 33 | } 34 | } 35 | 36 | /// (14) Render the default view: `UsersList`. 37 | Route(content: UsersList()) 38 | } 39 | } 40 | 41 | /// (15) A validator function called by a `Route` (see (12)). It first checks whether the UUID in the path is a 42 | /// valid UUID. It then checks if there are any users with said UUID. If either checks fail we return `nil`. 43 | /// If there *is* a user with this UUID, we pass along said user. 44 | private func findUser(route: RouteInformation) -> UserModel? { 45 | if let parameter = route.parameters["uuid"], 46 | let uuid = UUID(uuidString: parameter) 47 | { 48 | return usersData.users.first { $0.id == uuid } 49 | } 50 | return nil 51 | } 52 | } 53 | 54 | // MARK: - 55 | private struct UsersList: View { 56 | @EnvironmentObject private var usersData: UsersData 57 | 58 | var body: some View { 59 | List { 60 | Text("User list") 61 | .font(.title) 62 | 63 | ForEach(usersData.users) { user in 64 | UsersListCell(user: user) 65 | } 66 | } 67 | .listStyle(.plain) 68 | } 69 | 70 | private func UsersListCell(user: UserModel) -> some View { 71 | /// (16) Link to `/users/{user uuid}`. Keep in mind that paths in SwiftUI Router are always relative. This 72 | /// `NavLink` is being rendered inside a `Route` with path `/users/*` (see (6)). 73 | NavLink(to: user.id.uuidString) { 74 | HStack { 75 | AsyncImage(url: user.picture.thumbnail) 76 | .cornerRadius(20) 77 | .frame(width: 60, height: 60) 78 | 79 | VStack(alignment: .leading, spacing: 7) { 80 | Text(user.name.first + " " + user.name.last) 81 | .font(.title2) 82 | 83 | Label(user.location.country, systemImage: "location") 84 | } 85 | 86 | Spacer() 87 | 88 | Image(systemName: "chevron.right") 89 | } 90 | .padding(.vertical, 2) 91 | } 92 | .buttonStyle(.plain) 93 | .frame(maxWidth: .infinity) 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /RandomUsers/macOS/macOS.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | com.apple.security.network.client 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /RandomUsers/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frzi/SwiftUIRouter-Examples/69f7302da8d909a3cc252aee74784ff6439ac6ff/RandomUsers/preview.jpg -------------------------------------------------------------------------------- /Swiping/README.md: -------------------------------------------------------------------------------- 1 | # Swiping example 2 | > Creating a similar swipe-to-go-back effect on iOS. 3 | 4 | ![Swipe demonstration](preview.gif) 5 | 6 | Because [SwiftUI Router](https://github.com/frzi/SwiftUIRouter) doesn't work with SwiftUI's `NavigationView`, you do not get the swipe-from-the-side-to-go-back UX for free. This sample project showcases a possible way to create a similar experience, with two different visual effects. -------------------------------------------------------------------------------- /Swiping/Swiping.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 55; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | C0B1C5472752BEBD002DD942 /* SwipingApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0B1C5462752BEBD002DD942 /* SwipingApp.swift */; }; 11 | C0B1C5492752BEBD002DD942 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0B1C5482752BEBD002DD942 /* ContentView.swift */; }; 12 | C0B1C54B2752BEC1002DD942 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C0B1C54A2752BEC1002DD942 /* Assets.xcassets */; }; 13 | C0B1C54E2752BEC1002DD942 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C0B1C54D2752BEC1002DD942 /* Preview Assets.xcassets */; }; 14 | C0B1C5552752BF04002DD942 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0B1C5542752BF04002DD942 /* Extensions.swift */; }; 15 | C0B1C5582752BF31002DD942 /* SwiftUIRouter in Frameworks */ = {isa = PBXBuildFile; productRef = C0B1C5572752BF31002DD942 /* SwiftUIRouter */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXFileReference section */ 19 | C0B1C5432752BEBD002DD942 /* Swiping.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Swiping.app; sourceTree = BUILT_PRODUCTS_DIR; }; 20 | C0B1C5462752BEBD002DD942 /* SwipingApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwipingApp.swift; sourceTree = ""; }; 21 | C0B1C5482752BEBD002DD942 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 22 | C0B1C54A2752BEC1002DD942 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 23 | C0B1C54D2752BEC1002DD942 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 24 | C0B1C5542752BF04002DD942 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; 25 | /* End PBXFileReference section */ 26 | 27 | /* Begin PBXFrameworksBuildPhase section */ 28 | C0B1C5402752BEBD002DD942 /* Frameworks */ = { 29 | isa = PBXFrameworksBuildPhase; 30 | buildActionMask = 2147483647; 31 | files = ( 32 | C0B1C5582752BF31002DD942 /* SwiftUIRouter in Frameworks */, 33 | ); 34 | runOnlyForDeploymentPostprocessing = 0; 35 | }; 36 | /* End PBXFrameworksBuildPhase section */ 37 | 38 | /* Begin PBXGroup section */ 39 | C0B1C53A2752BEBD002DD942 = { 40 | isa = PBXGroup; 41 | children = ( 42 | C0B1C5452752BEBD002DD942 /* Swiping */, 43 | C0B1C5442752BEBD002DD942 /* Products */, 44 | ); 45 | sourceTree = ""; 46 | }; 47 | C0B1C5442752BEBD002DD942 /* Products */ = { 48 | isa = PBXGroup; 49 | children = ( 50 | C0B1C5432752BEBD002DD942 /* Swiping.app */, 51 | ); 52 | name = Products; 53 | sourceTree = ""; 54 | }; 55 | C0B1C5452752BEBD002DD942 /* Swiping */ = { 56 | isa = PBXGroup; 57 | children = ( 58 | C0B1C5462752BEBD002DD942 /* SwipingApp.swift */, 59 | C0B1C5482752BEBD002DD942 /* ContentView.swift */, 60 | C0B1C5542752BF04002DD942 /* Extensions.swift */, 61 | C0B1C54A2752BEC1002DD942 /* Assets.xcassets */, 62 | C0B1C54C2752BEC1002DD942 /* Preview Content */, 63 | ); 64 | path = Swiping; 65 | sourceTree = ""; 66 | }; 67 | C0B1C54C2752BEC1002DD942 /* Preview Content */ = { 68 | isa = PBXGroup; 69 | children = ( 70 | C0B1C54D2752BEC1002DD942 /* Preview Assets.xcassets */, 71 | ); 72 | path = "Preview Content"; 73 | sourceTree = ""; 74 | }; 75 | /* End PBXGroup section */ 76 | 77 | /* Begin PBXNativeTarget section */ 78 | C0B1C5422752BEBD002DD942 /* Swiping */ = { 79 | isa = PBXNativeTarget; 80 | buildConfigurationList = C0B1C5512752BEC1002DD942 /* Build configuration list for PBXNativeTarget "Swiping" */; 81 | buildPhases = ( 82 | C0B1C53F2752BEBD002DD942 /* Sources */, 83 | C0B1C5402752BEBD002DD942 /* Frameworks */, 84 | C0B1C5412752BEBD002DD942 /* Resources */, 85 | ); 86 | buildRules = ( 87 | ); 88 | dependencies = ( 89 | ); 90 | name = Swiping; 91 | packageProductDependencies = ( 92 | C0B1C5572752BF31002DD942 /* SwiftUIRouter */, 93 | ); 94 | productName = Swiping; 95 | productReference = C0B1C5432752BEBD002DD942 /* Swiping.app */; 96 | productType = "com.apple.product-type.application"; 97 | }; 98 | /* End PBXNativeTarget section */ 99 | 100 | /* Begin PBXProject section */ 101 | C0B1C53B2752BEBD002DD942 /* Project object */ = { 102 | isa = PBXProject; 103 | attributes = { 104 | BuildIndependentTargetsInParallel = 1; 105 | LastSwiftUpdateCheck = 1320; 106 | LastUpgradeCheck = 1320; 107 | TargetAttributes = { 108 | C0B1C5422752BEBD002DD942 = { 109 | CreatedOnToolsVersion = 13.2; 110 | }; 111 | }; 112 | }; 113 | buildConfigurationList = C0B1C53E2752BEBD002DD942 /* Build configuration list for PBXProject "Swiping" */; 114 | compatibilityVersion = "Xcode 13.0"; 115 | developmentRegion = en; 116 | hasScannedForEncodings = 0; 117 | knownRegions = ( 118 | en, 119 | Base, 120 | ); 121 | mainGroup = C0B1C53A2752BEBD002DD942; 122 | packageReferences = ( 123 | C0B1C5562752BF31002DD942 /* XCRemoteSwiftPackageReference "SwiftUIRouter" */, 124 | ); 125 | productRefGroup = C0B1C5442752BEBD002DD942 /* Products */; 126 | projectDirPath = ""; 127 | projectRoot = ""; 128 | targets = ( 129 | C0B1C5422752BEBD002DD942 /* Swiping */, 130 | ); 131 | }; 132 | /* End PBXProject section */ 133 | 134 | /* Begin PBXResourcesBuildPhase section */ 135 | C0B1C5412752BEBD002DD942 /* Resources */ = { 136 | isa = PBXResourcesBuildPhase; 137 | buildActionMask = 2147483647; 138 | files = ( 139 | C0B1C54E2752BEC1002DD942 /* Preview Assets.xcassets in Resources */, 140 | C0B1C54B2752BEC1002DD942 /* Assets.xcassets in Resources */, 141 | ); 142 | runOnlyForDeploymentPostprocessing = 0; 143 | }; 144 | /* End PBXResourcesBuildPhase section */ 145 | 146 | /* Begin PBXSourcesBuildPhase section */ 147 | C0B1C53F2752BEBD002DD942 /* Sources */ = { 148 | isa = PBXSourcesBuildPhase; 149 | buildActionMask = 2147483647; 150 | files = ( 151 | C0B1C5492752BEBD002DD942 /* ContentView.swift in Sources */, 152 | C0B1C5552752BF04002DD942 /* Extensions.swift in Sources */, 153 | C0B1C5472752BEBD002DD942 /* SwipingApp.swift in Sources */, 154 | ); 155 | runOnlyForDeploymentPostprocessing = 0; 156 | }; 157 | /* End PBXSourcesBuildPhase section */ 158 | 159 | /* Begin XCBuildConfiguration section */ 160 | C0B1C54F2752BEC1002DD942 /* Debug */ = { 161 | isa = XCBuildConfiguration; 162 | buildSettings = { 163 | ALWAYS_SEARCH_USER_PATHS = NO; 164 | CLANG_ANALYZER_NONNULL = YES; 165 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 166 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 167 | CLANG_CXX_LIBRARY = "libc++"; 168 | CLANG_ENABLE_MODULES = YES; 169 | CLANG_ENABLE_OBJC_ARC = YES; 170 | CLANG_ENABLE_OBJC_WEAK = YES; 171 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 172 | CLANG_WARN_BOOL_CONVERSION = YES; 173 | CLANG_WARN_COMMA = YES; 174 | CLANG_WARN_CONSTANT_CONVERSION = YES; 175 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 176 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 177 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 178 | CLANG_WARN_EMPTY_BODY = YES; 179 | CLANG_WARN_ENUM_CONVERSION = YES; 180 | CLANG_WARN_INFINITE_RECURSION = YES; 181 | CLANG_WARN_INT_CONVERSION = YES; 182 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 183 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 184 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 185 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 186 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 187 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 188 | CLANG_WARN_STRICT_PROTOTYPES = YES; 189 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 190 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 191 | CLANG_WARN_UNREACHABLE_CODE = YES; 192 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 193 | COPY_PHASE_STRIP = NO; 194 | DEBUG_INFORMATION_FORMAT = dwarf; 195 | ENABLE_STRICT_OBJC_MSGSEND = YES; 196 | ENABLE_TESTABILITY = YES; 197 | GCC_C_LANGUAGE_STANDARD = gnu11; 198 | GCC_DYNAMIC_NO_PIC = NO; 199 | GCC_NO_COMMON_BLOCKS = YES; 200 | GCC_OPTIMIZATION_LEVEL = 0; 201 | GCC_PREPROCESSOR_DEFINITIONS = ( 202 | "DEBUG=1", 203 | "$(inherited)", 204 | ); 205 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 206 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 207 | GCC_WARN_UNDECLARED_SELECTOR = YES; 208 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 209 | GCC_WARN_UNUSED_FUNCTION = YES; 210 | GCC_WARN_UNUSED_VARIABLE = YES; 211 | IPHONEOS_DEPLOYMENT_TARGET = 15.2; 212 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 213 | MTL_FAST_MATH = YES; 214 | ONLY_ACTIVE_ARCH = YES; 215 | SDKROOT = iphoneos; 216 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 217 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 218 | }; 219 | name = Debug; 220 | }; 221 | C0B1C5502752BEC1002DD942 /* Release */ = { 222 | isa = XCBuildConfiguration; 223 | buildSettings = { 224 | ALWAYS_SEARCH_USER_PATHS = NO; 225 | CLANG_ANALYZER_NONNULL = YES; 226 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 227 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 228 | CLANG_CXX_LIBRARY = "libc++"; 229 | CLANG_ENABLE_MODULES = YES; 230 | CLANG_ENABLE_OBJC_ARC = YES; 231 | CLANG_ENABLE_OBJC_WEAK = YES; 232 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 233 | CLANG_WARN_BOOL_CONVERSION = YES; 234 | CLANG_WARN_COMMA = YES; 235 | CLANG_WARN_CONSTANT_CONVERSION = YES; 236 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 237 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 238 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 239 | CLANG_WARN_EMPTY_BODY = YES; 240 | CLANG_WARN_ENUM_CONVERSION = YES; 241 | CLANG_WARN_INFINITE_RECURSION = YES; 242 | CLANG_WARN_INT_CONVERSION = YES; 243 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 244 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 245 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 246 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 247 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 248 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 249 | CLANG_WARN_STRICT_PROTOTYPES = YES; 250 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 251 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 252 | CLANG_WARN_UNREACHABLE_CODE = YES; 253 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 254 | COPY_PHASE_STRIP = NO; 255 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 256 | ENABLE_NS_ASSERTIONS = NO; 257 | ENABLE_STRICT_OBJC_MSGSEND = YES; 258 | GCC_C_LANGUAGE_STANDARD = gnu11; 259 | GCC_NO_COMMON_BLOCKS = YES; 260 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 261 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 262 | GCC_WARN_UNDECLARED_SELECTOR = YES; 263 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 264 | GCC_WARN_UNUSED_FUNCTION = YES; 265 | GCC_WARN_UNUSED_VARIABLE = YES; 266 | IPHONEOS_DEPLOYMENT_TARGET = 15.2; 267 | MTL_ENABLE_DEBUG_INFO = NO; 268 | MTL_FAST_MATH = YES; 269 | SDKROOT = iphoneos; 270 | SWIFT_COMPILATION_MODE = wholemodule; 271 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 272 | VALIDATE_PRODUCT = YES; 273 | }; 274 | name = Release; 275 | }; 276 | C0B1C5522752BEC1002DD942 /* Debug */ = { 277 | isa = XCBuildConfiguration; 278 | buildSettings = { 279 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 280 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 281 | CODE_SIGN_STYLE = Automatic; 282 | CURRENT_PROJECT_VERSION = 1; 283 | DEVELOPMENT_ASSET_PATHS = "\"Swiping/Preview Content\""; 284 | DEVELOPMENT_TEAM = QSR4FL5D2K; 285 | ENABLE_PREVIEWS = YES; 286 | GENERATE_INFOPLIST_FILE = YES; 287 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 288 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 289 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 290 | INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 291 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 292 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 293 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 294 | LD_RUNPATH_SEARCH_PATHS = ( 295 | "$(inherited)", 296 | "@executable_path/Frameworks", 297 | ); 298 | MARKETING_VERSION = 1.0; 299 | PRODUCT_BUNDLE_IDENTIFIER = com.frzi.Swiping; 300 | PRODUCT_NAME = "$(TARGET_NAME)"; 301 | SWIFT_EMIT_LOC_STRINGS = YES; 302 | SWIFT_VERSION = 5.0; 303 | TARGETED_DEVICE_FAMILY = "1,2"; 304 | }; 305 | name = Debug; 306 | }; 307 | C0B1C5532752BEC1002DD942 /* Release */ = { 308 | isa = XCBuildConfiguration; 309 | buildSettings = { 310 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 311 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 312 | CODE_SIGN_STYLE = Automatic; 313 | CURRENT_PROJECT_VERSION = 1; 314 | DEVELOPMENT_ASSET_PATHS = "\"Swiping/Preview Content\""; 315 | DEVELOPMENT_TEAM = QSR4FL5D2K; 316 | ENABLE_PREVIEWS = YES; 317 | GENERATE_INFOPLIST_FILE = YES; 318 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 319 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 320 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 321 | INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 322 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 323 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 324 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 325 | LD_RUNPATH_SEARCH_PATHS = ( 326 | "$(inherited)", 327 | "@executable_path/Frameworks", 328 | ); 329 | MARKETING_VERSION = 1.0; 330 | PRODUCT_BUNDLE_IDENTIFIER = com.frzi.Swiping; 331 | PRODUCT_NAME = "$(TARGET_NAME)"; 332 | SWIFT_EMIT_LOC_STRINGS = YES; 333 | SWIFT_VERSION = 5.0; 334 | TARGETED_DEVICE_FAMILY = "1,2"; 335 | }; 336 | name = Release; 337 | }; 338 | /* End XCBuildConfiguration section */ 339 | 340 | /* Begin XCConfigurationList section */ 341 | C0B1C53E2752BEBD002DD942 /* Build configuration list for PBXProject "Swiping" */ = { 342 | isa = XCConfigurationList; 343 | buildConfigurations = ( 344 | C0B1C54F2752BEC1002DD942 /* Debug */, 345 | C0B1C5502752BEC1002DD942 /* Release */, 346 | ); 347 | defaultConfigurationIsVisible = 0; 348 | defaultConfigurationName = Release; 349 | }; 350 | C0B1C5512752BEC1002DD942 /* Build configuration list for PBXNativeTarget "Swiping" */ = { 351 | isa = XCConfigurationList; 352 | buildConfigurations = ( 353 | C0B1C5522752BEC1002DD942 /* Debug */, 354 | C0B1C5532752BEC1002DD942 /* Release */, 355 | ); 356 | defaultConfigurationIsVisible = 0; 357 | defaultConfigurationName = Release; 358 | }; 359 | /* End XCConfigurationList section */ 360 | 361 | /* Begin XCRemoteSwiftPackageReference section */ 362 | C0B1C5562752BF31002DD942 /* XCRemoteSwiftPackageReference "SwiftUIRouter" */ = { 363 | isa = XCRemoteSwiftPackageReference; 364 | repositoryURL = "https://github.com/frzi/SwiftUIRouter"; 365 | requirement = { 366 | kind = upToNextMajorVersion; 367 | minimumVersion = 1.3.0; 368 | }; 369 | }; 370 | /* End XCRemoteSwiftPackageReference section */ 371 | 372 | /* Begin XCSwiftPackageProductDependency section */ 373 | C0B1C5572752BF31002DD942 /* SwiftUIRouter */ = { 374 | isa = XCSwiftPackageProductDependency; 375 | package = C0B1C5562752BF31002DD942 /* XCRemoteSwiftPackageReference "SwiftUIRouter" */; 376 | productName = SwiftUIRouter; 377 | }; 378 | /* End XCSwiftPackageProductDependency section */ 379 | }; 380 | rootObject = C0B1C53B2752BEBD002DD942 /* Project object */; 381 | } 382 | -------------------------------------------------------------------------------- /Swiping/Swiping.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Swiping/Swiping.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Swiping/Swiping.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "object": { 3 | "pins": [ 4 | { 5 | "package": "SwiftUIRouter", 6 | "repositoryURL": "https://github.com/frzi/SwiftUIRouter", 7 | "state": { 8 | "branch": null, 9 | "revision": "5e69c689ceaae3c8ed52ae535f294aeb262dc812", 10 | "version": "1.3.0" 11 | } 12 | } 13 | ] 14 | }, 15 | "version": 1 16 | } 17 | -------------------------------------------------------------------------------- /Swiping/Swiping/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 | -------------------------------------------------------------------------------- /Swiping/Swiping/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | } 93 | ], 94 | "info" : { 95 | "author" : "xcode", 96 | "version" : 1 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /Swiping/Swiping/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Swiping/Swiping/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Swiping 3 | // Created by Freek (github.com/frzi) 2021 4 | // 5 | 6 | import SwiftUI 7 | import SwiftUIRouter 8 | 9 | struct ContentView: View { 10 | var body: some View { 11 | GeometryReader { _ in 12 | SwitchRoutes { 13 | Route("one", content: SecondScreen()) 14 | .swipeableBack(action: .up) 15 | 16 | Route("one/two", content: ThirdScreen()) 17 | .swipeableBackAlt(action: .up) 18 | 19 | Route(content: FirstScreen()) 20 | .swipeableBack(action: .up) 21 | } 22 | .ignoresSafeArea(.all, edges: .all) 23 | .navigationTransition() 24 | .buttonStyle(.borderedProminent) 25 | } 26 | } 27 | } 28 | 29 | private struct FirstScreen: View { 30 | var body: some View { 31 | VStack { 32 | Text("First screen") 33 | .font(.title) 34 | .padding() 35 | 36 | NavLink(to: "one") { 37 | Text("Go to second screen") 38 | } 39 | } 40 | .frame(maxWidth: .infinity, maxHeight: .infinity) 41 | .background(Color.orange) 42 | } 43 | } 44 | 45 | private struct SecondScreen: View { 46 | var body: some View { 47 | VStack { 48 | Text("Second screen") 49 | .font(.title) 50 | .padding() 51 | 52 | Text("Try swiping from the screen's left edge to the right. After dragging beyond a certain threshold, either a `goBack` or `../` (one up) navigation will commit.") 53 | .padding() 54 | 55 | NavLink(to: "two") { 56 | Text("Go to third screen") 57 | } 58 | 59 | BackButton() 60 | } 61 | .frame(maxWidth: .infinity, maxHeight: .infinity) 62 | .background(Color.yellow) 63 | } 64 | } 65 | 66 | private struct ThirdScreen: View { 67 | var body: some View { 68 | VStack { 69 | Text("Third screen") 70 | .font(.title) 71 | .padding() 72 | 73 | Text("Swiping from the screen's left edge will result in a different effect here! Try it!") 74 | 75 | BackButton() 76 | } 77 | .frame(maxWidth: .infinity, maxHeight: .infinity) 78 | .background(Color.green) 79 | } 80 | } 81 | 82 | private struct BackButton: View { 83 | @EnvironmentObject private var navigator: Navigator 84 | 85 | var body: some View { 86 | Button(action: { navigator.goBack() }) { 87 | Text("Go back") 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /Swiping/Swiping/Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Swiping 3 | // Created by Freek (github.com/frzi) 2021 4 | // 5 | 6 | import Foundation 7 | import SwiftUI 8 | import SwiftUIRouter 9 | 10 | // MARK: - Navigation transition 11 | private struct NavigationTransition: ViewModifier { 12 | @EnvironmentObject private var navigator: Navigator 13 | 14 | func body(content: Content) -> some View { 15 | content 16 | .animation(.easeInOut, value: navigator.path) 17 | .transition( 18 | navigator.lastAction?.direction == .deeper || navigator.lastAction?.direction == .sideways 19 | ? AnyTransition.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .leading)) 20 | : AnyTransition.asymmetric(insertion: .move(edge: .leading), removal: .move(edge: .trailing)) 21 | ) 22 | } 23 | } 24 | 25 | extension View { 26 | func navigationTransition() -> some View { 27 | modifier(NavigationTransition()) 28 | } 29 | } 30 | 31 | // MARK: - Swipeable modifier. 32 | /** 33 | * Modifier to allow draggin from the screen's left edge to go back/up. 34 | * The current view will move along with the drag gesture, revealing a black background. 35 | */ 36 | struct SwipeableBack: ViewModifier { 37 | enum Action { 38 | case back 39 | case up 40 | } 41 | 42 | @EnvironmentObject private var navigator: Navigator 43 | @State private var dragOffset: CGFloat = 0 44 | 45 | let action: Action 46 | let threshold: CGFloat 47 | 48 | private var dragGesture: some Gesture { 49 | DragGesture() 50 | .onChanged { value in 51 | if (action == .back && navigator.canGoBack && value.startLocation.x < 20) 52 | || (action == .up && navigator.path != "/" && value.startLocation.x < 20) 53 | { 54 | dragOffset = value.translation.width * 0.2 55 | } 56 | } 57 | .onEnded { value in 58 | if dragOffset > threshold { 59 | if action == .back { 60 | navigator.goBack() 61 | } 62 | else if action == .up { 63 | navigator.navigate("..") 64 | } 65 | } 66 | 67 | dragOffset = 0 68 | } 69 | } 70 | 71 | func body(content: Content) -> some View { 72 | content 73 | .offset(x: max(0, dragOffset)) 74 | .clipped() 75 | .background(Color.black) 76 | .gesture(dragGesture) 77 | } 78 | } 79 | 80 | extension View { 81 | func swipeableBack(action: SwipeableBack.Action = .back, threshold: CGFloat = 40) -> some View { 82 | modifier(SwipeableBack(action: action, threshold: threshold)) 83 | } 84 | } 85 | 86 | // MARK: - Swipeable modifier (alternative). 87 | /** 88 | * An alternative effect when swiping from the left edge. 89 | * Dragging from the edge will render an effect similar to Chrome's back/forward navigation. 90 | */ 91 | struct SwipeableBackAlternative: ViewModifier { 92 | @EnvironmentObject private var navigator: Navigator 93 | @State private var dragOffset: CGFloat = 0 94 | 95 | let action: SwipeableBack.Action 96 | let threshold: CGFloat 97 | private let graphicSize: CGFloat = 200 98 | 99 | private var dragGesture: some Gesture { 100 | DragGesture() 101 | .onChanged { value in 102 | if (action == .back && navigator.canGoBack && value.startLocation.x < 20) 103 | || (action == .up && navigator.path != "/" && value.startLocation.x < 20) 104 | { 105 | dragOffset = value.translation.width * 0.2 106 | } 107 | } 108 | .onEnded { value in 109 | if dragOffset > threshold { 110 | if action == .back { 111 | navigator.goBack() 112 | } 113 | else if action == .up { 114 | navigator.navigate("..") 115 | } 116 | } 117 | 118 | dragOffset = 0 119 | } 120 | } 121 | 122 | func body(content: Content) -> some View { 123 | content 124 | .overlay( 125 | ZStack(alignment: .trailing) { 126 | Circle() 127 | .fill(.black.opacity(dragOffset / threshold)) 128 | 129 | Image(systemName: "arrow.right") 130 | .foregroundColor(.white) 131 | .font(.system(size: 40)) 132 | .padding(.trailing, 10) 133 | } 134 | .frame(width: graphicSize, height: graphicSize) 135 | .offset(x: min(max(0, dragOffset), graphicSize / 2) - graphicSize), 136 | alignment: .leading 137 | ) 138 | .clipped() 139 | .gesture(dragGesture) 140 | } 141 | } 142 | 143 | extension View { 144 | func swipeableBackAlt(action: SwipeableBack.Action = .back, threshold: CGFloat = 40) -> some View { 145 | modifier(SwipeableBackAlternative(action: action, threshold: threshold)) 146 | } 147 | } 148 | 149 | -------------------------------------------------------------------------------- /Swiping/Swiping/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Swiping/Swiping/SwipingApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Swiping 3 | // Created by Freek (github.com/frzi) 2021 4 | // 5 | 6 | import SwiftUI 7 | import SwiftUIRouter 8 | 9 | @main 10 | struct SwipingApp: App { 11 | var body: some Scene { 12 | WindowGroup { 13 | Router { 14 | ContentView() 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Swiping/preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frzi/SwiftUIRouter-Examples/69f7302da8d909a3cc252aee74784ff6439ac6ff/Swiping/preview.gif -------------------------------------------------------------------------------- /TabViewRouting/README.md: -------------------------------------------------------------------------------- 1 | # TabView example 2 | > Combining *SwiftUI Router* and TabViews. 3 | 4 | [SwiftUI Router](https://github.com/frzi/SwiftUIRouter) does not work with SwiftUI's `TabView`s (and `List`s) out of the box, as they both use different forms of states. This sample project demonstrates how, with a little bit of extra code, you can combine both paradigms. -------------------------------------------------------------------------------- /TabViewRouting/Shared/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 | -------------------------------------------------------------------------------- /TabViewRouting/Shared/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | }, 93 | { 94 | "idiom" : "mac", 95 | "scale" : "1x", 96 | "size" : "16x16" 97 | }, 98 | { 99 | "idiom" : "mac", 100 | "scale" : "2x", 101 | "size" : "16x16" 102 | }, 103 | { 104 | "idiom" : "mac", 105 | "scale" : "1x", 106 | "size" : "32x32" 107 | }, 108 | { 109 | "idiom" : "mac", 110 | "scale" : "2x", 111 | "size" : "32x32" 112 | }, 113 | { 114 | "idiom" : "mac", 115 | "scale" : "1x", 116 | "size" : "128x128" 117 | }, 118 | { 119 | "idiom" : "mac", 120 | "scale" : "2x", 121 | "size" : "128x128" 122 | }, 123 | { 124 | "idiom" : "mac", 125 | "scale" : "1x", 126 | "size" : "256x256" 127 | }, 128 | { 129 | "idiom" : "mac", 130 | "scale" : "2x", 131 | "size" : "256x256" 132 | }, 133 | { 134 | "idiom" : "mac", 135 | "scale" : "1x", 136 | "size" : "512x512" 137 | }, 138 | { 139 | "idiom" : "mac", 140 | "scale" : "2x", 141 | "size" : "512x512" 142 | } 143 | ], 144 | "info" : { 145 | "author" : "xcode", 146 | "version" : 1 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /TabViewRouting/Shared/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /TabViewRouting/Shared/Screens.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TabViewRouting 3 | // Created by Freek (github.com/frzi) 2021 4 | // 5 | 6 | import SwiftUI 7 | import SwiftUIRouter 8 | 9 | // MARK: - Different screens 10 | struct MoviesScreen: View { 11 | var body: some View { 12 | GeometryReader { _ in 13 | VStack { 14 | Text("Movies") 15 | .font(.title) 16 | 17 | NavLink(to: "/Music") { 18 | Text("Take me to **Music**") 19 | } 20 | 21 | NavLink(to: "/Books") { 22 | Text("Take me to **Books**") 23 | } 24 | } 25 | } 26 | .padding() 27 | #if os(macOS) 28 | .background(Color.orange) 29 | #endif 30 | } 31 | } 32 | 33 | struct MusicScreen: View { 34 | var body: some View { 35 | GeometryReader { _ in 36 | VStack { 37 | Text("Music") 38 | .font(.title) 39 | 40 | NavLink(to: "/Movies") { 41 | Text("Take me to **Movies**") 42 | } 43 | 44 | NavLink(to: "/Books") { 45 | Text("Take me to **Books**") 46 | } 47 | } 48 | } 49 | .padding() 50 | #if os(macOS) 51 | .background(Color.yellow) 52 | #endif 53 | } 54 | } 55 | 56 | struct BooksScreen: View { 57 | var body: some View { 58 | GeometryReader { _ in 59 | VStack { 60 | Text("Books") 61 | .font(.title) 62 | 63 | NavLink(to: "/Movies") { 64 | Text("Take me to **Movies**") 65 | } 66 | 67 | NavLink(to: "/Music") { 68 | Text("Take me to **Music**") 69 | } 70 | } 71 | } 72 | .padding() 73 | #if os(macOS) 74 | .background(Color.green) 75 | #endif 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /TabViewRouting/Shared/TabViewRoutingApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TabViewRouting 3 | // Created by Freek (github.com/frzi) 2021 4 | // 5 | 6 | import SwiftUI 7 | import SwiftUIRouter 8 | 9 | @main 10 | struct TabViewRoutingApp: App { 11 | var body: some Scene { 12 | WindowGroup { 13 | Router { 14 | RootView() 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /TabViewRouting/TabViewRouting.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 55; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | C0B1C5712752E877002DD942 /* TabViewRoutingApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0B1C5612752E875002DD942 /* TabViewRoutingApp.swift */; }; 11 | C0B1C5722752E877002DD942 /* TabViewRoutingApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0B1C5612752E875002DD942 /* TabViewRoutingApp.swift */; }; 12 | C0B1C5742752E877002DD942 /* RootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0B1C5622752E875002DD942 /* RootView.swift */; }; 13 | C0B1C5752752E877002DD942 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C0B1C5632752E877002DD942 /* Assets.xcassets */; }; 14 | C0B1C5762752E877002DD942 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C0B1C5632752E877002DD942 /* Assets.xcassets */; }; 15 | C0B1C5882752F1FF002DD942 /* RootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0B1C5872752F1FF002DD942 /* RootView.swift */; }; 16 | C0B1C58B2752F2FB002DD942 /* SwiftUIRouter in Frameworks */ = {isa = PBXBuildFile; productRef = C0B1C58A2752F2FB002DD942 /* SwiftUIRouter */; }; 17 | C0B1C58D2752F301002DD942 /* SwiftUIRouter in Frameworks */ = {isa = PBXBuildFile; productRef = C0B1C58C2752F301002DD942 /* SwiftUIRouter */; }; 18 | C0E67C4027540AFC00F8EC58 /* Screens.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0E67C3F27540AFC00F8EC58 /* Screens.swift */; }; 19 | C0E67C4127540AFC00F8EC58 /* Screens.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0E67C3F27540AFC00F8EC58 /* Screens.swift */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXFileReference section */ 23 | C0B1C5612752E875002DD942 /* TabViewRoutingApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabViewRoutingApp.swift; sourceTree = ""; }; 24 | C0B1C5622752E875002DD942 /* RootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootView.swift; sourceTree = ""; }; 25 | C0B1C5632752E877002DD942 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 26 | C0B1C5682752E877002DD942 /* TabViewRouting.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TabViewRouting.app; sourceTree = BUILT_PRODUCTS_DIR; }; 27 | C0B1C56E2752E877002DD942 /* TabViewRouting.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TabViewRouting.app; sourceTree = BUILT_PRODUCTS_DIR; }; 28 | C0B1C5702752E877002DD942 /* macOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = macOS.entitlements; sourceTree = ""; }; 29 | C0B1C5872752F1FF002DD942 /* RootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootView.swift; sourceTree = ""; }; 30 | C0E67C3F27540AFC00F8EC58 /* Screens.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Screens.swift; sourceTree = ""; }; 31 | /* End PBXFileReference section */ 32 | 33 | /* Begin PBXFrameworksBuildPhase section */ 34 | C0B1C5652752E877002DD942 /* Frameworks */ = { 35 | isa = PBXFrameworksBuildPhase; 36 | buildActionMask = 2147483647; 37 | files = ( 38 | C0B1C58B2752F2FB002DD942 /* SwiftUIRouter in Frameworks */, 39 | ); 40 | runOnlyForDeploymentPostprocessing = 0; 41 | }; 42 | C0B1C56B2752E877002DD942 /* Frameworks */ = { 43 | isa = PBXFrameworksBuildPhase; 44 | buildActionMask = 2147483647; 45 | files = ( 46 | C0B1C58D2752F301002DD942 /* SwiftUIRouter in Frameworks */, 47 | ); 48 | runOnlyForDeploymentPostprocessing = 0; 49 | }; 50 | /* End PBXFrameworksBuildPhase section */ 51 | 52 | /* Begin PBXGroup section */ 53 | C0B1C55B2752E875002DD942 = { 54 | isa = PBXGroup; 55 | children = ( 56 | C0B1C5602752E875002DD942 /* Shared */, 57 | C0B1C5862752F1EF002DD942 /* iOS */, 58 | C0B1C56F2752E877002DD942 /* macOS */, 59 | C0B1C5802752E98D002DD942 /* Frameworks */, 60 | C0B1C5692752E877002DD942 /* Products */, 61 | ); 62 | sourceTree = ""; 63 | }; 64 | C0B1C5602752E875002DD942 /* Shared */ = { 65 | isa = PBXGroup; 66 | children = ( 67 | C0B1C5612752E875002DD942 /* TabViewRoutingApp.swift */, 68 | C0E67C3F27540AFC00F8EC58 /* Screens.swift */, 69 | C0B1C5632752E877002DD942 /* Assets.xcassets */, 70 | ); 71 | path = Shared; 72 | sourceTree = ""; 73 | }; 74 | C0B1C5692752E877002DD942 /* Products */ = { 75 | isa = PBXGroup; 76 | children = ( 77 | C0B1C5682752E877002DD942 /* TabViewRouting.app */, 78 | C0B1C56E2752E877002DD942 /* TabViewRouting.app */, 79 | ); 80 | name = Products; 81 | sourceTree = ""; 82 | }; 83 | C0B1C56F2752E877002DD942 /* macOS */ = { 84 | isa = PBXGroup; 85 | children = ( 86 | C0B1C5622752E875002DD942 /* RootView.swift */, 87 | C0B1C5702752E877002DD942 /* macOS.entitlements */, 88 | ); 89 | path = macOS; 90 | sourceTree = ""; 91 | }; 92 | C0B1C5802752E98D002DD942 /* Frameworks */ = { 93 | isa = PBXGroup; 94 | children = ( 95 | ); 96 | name = Frameworks; 97 | sourceTree = ""; 98 | }; 99 | C0B1C5862752F1EF002DD942 /* iOS */ = { 100 | isa = PBXGroup; 101 | children = ( 102 | C0B1C5872752F1FF002DD942 /* RootView.swift */, 103 | ); 104 | path = iOS; 105 | sourceTree = ""; 106 | }; 107 | /* End PBXGroup section */ 108 | 109 | /* Begin PBXNativeTarget section */ 110 | C0B1C5672752E877002DD942 /* TabViewRouting (iOS) */ = { 111 | isa = PBXNativeTarget; 112 | buildConfigurationList = C0B1C5792752E877002DD942 /* Build configuration list for PBXNativeTarget "TabViewRouting (iOS)" */; 113 | buildPhases = ( 114 | C0B1C5642752E877002DD942 /* Sources */, 115 | C0B1C5652752E877002DD942 /* Frameworks */, 116 | C0B1C5662752E877002DD942 /* Resources */, 117 | ); 118 | buildRules = ( 119 | ); 120 | dependencies = ( 121 | ); 122 | name = "TabViewRouting (iOS)"; 123 | packageProductDependencies = ( 124 | C0B1C58A2752F2FB002DD942 /* SwiftUIRouter */, 125 | ); 126 | productName = "TabViewRouting (iOS)"; 127 | productReference = C0B1C5682752E877002DD942 /* TabViewRouting.app */; 128 | productType = "com.apple.product-type.application"; 129 | }; 130 | C0B1C56D2752E877002DD942 /* TabViewRouting (macOS) */ = { 131 | isa = PBXNativeTarget; 132 | buildConfigurationList = C0B1C57C2752E877002DD942 /* Build configuration list for PBXNativeTarget "TabViewRouting (macOS)" */; 133 | buildPhases = ( 134 | C0B1C56A2752E877002DD942 /* Sources */, 135 | C0B1C56B2752E877002DD942 /* Frameworks */, 136 | C0B1C56C2752E877002DD942 /* Resources */, 137 | ); 138 | buildRules = ( 139 | ); 140 | dependencies = ( 141 | ); 142 | name = "TabViewRouting (macOS)"; 143 | packageProductDependencies = ( 144 | C0B1C58C2752F301002DD942 /* SwiftUIRouter */, 145 | ); 146 | productName = "TabViewRouting (macOS)"; 147 | productReference = C0B1C56E2752E877002DD942 /* TabViewRouting.app */; 148 | productType = "com.apple.product-type.application"; 149 | }; 150 | /* End PBXNativeTarget section */ 151 | 152 | /* Begin PBXProject section */ 153 | C0B1C55C2752E875002DD942 /* Project object */ = { 154 | isa = PBXProject; 155 | attributes = { 156 | BuildIndependentTargetsInParallel = 1; 157 | LastSwiftUpdateCheck = 1320; 158 | LastUpgradeCheck = 1320; 159 | TargetAttributes = { 160 | C0B1C5672752E877002DD942 = { 161 | CreatedOnToolsVersion = 13.2; 162 | }; 163 | C0B1C56D2752E877002DD942 = { 164 | CreatedOnToolsVersion = 13.2; 165 | }; 166 | }; 167 | }; 168 | buildConfigurationList = C0B1C55F2752E875002DD942 /* Build configuration list for PBXProject "TabViewRouting" */; 169 | compatibilityVersion = "Xcode 13.0"; 170 | developmentRegion = en; 171 | hasScannedForEncodings = 0; 172 | knownRegions = ( 173 | en, 174 | Base, 175 | ); 176 | mainGroup = C0B1C55B2752E875002DD942; 177 | packageReferences = ( 178 | C0B1C5892752F2FB002DD942 /* XCRemoteSwiftPackageReference "SwiftUIRouter" */, 179 | ); 180 | productRefGroup = C0B1C5692752E877002DD942 /* Products */; 181 | projectDirPath = ""; 182 | projectRoot = ""; 183 | targets = ( 184 | C0B1C5672752E877002DD942 /* TabViewRouting (iOS) */, 185 | C0B1C56D2752E877002DD942 /* TabViewRouting (macOS) */, 186 | ); 187 | }; 188 | /* End PBXProject section */ 189 | 190 | /* Begin PBXResourcesBuildPhase section */ 191 | C0B1C5662752E877002DD942 /* Resources */ = { 192 | isa = PBXResourcesBuildPhase; 193 | buildActionMask = 2147483647; 194 | files = ( 195 | C0B1C5752752E877002DD942 /* Assets.xcassets in Resources */, 196 | ); 197 | runOnlyForDeploymentPostprocessing = 0; 198 | }; 199 | C0B1C56C2752E877002DD942 /* Resources */ = { 200 | isa = PBXResourcesBuildPhase; 201 | buildActionMask = 2147483647; 202 | files = ( 203 | C0B1C5762752E877002DD942 /* Assets.xcassets in Resources */, 204 | ); 205 | runOnlyForDeploymentPostprocessing = 0; 206 | }; 207 | /* End PBXResourcesBuildPhase section */ 208 | 209 | /* Begin PBXSourcesBuildPhase section */ 210 | C0B1C5642752E877002DD942 /* Sources */ = { 211 | isa = PBXSourcesBuildPhase; 212 | buildActionMask = 2147483647; 213 | files = ( 214 | C0E67C4027540AFC00F8EC58 /* Screens.swift in Sources */, 215 | C0B1C5882752F1FF002DD942 /* RootView.swift in Sources */, 216 | C0B1C5712752E877002DD942 /* TabViewRoutingApp.swift in Sources */, 217 | ); 218 | runOnlyForDeploymentPostprocessing = 0; 219 | }; 220 | C0B1C56A2752E877002DD942 /* Sources */ = { 221 | isa = PBXSourcesBuildPhase; 222 | buildActionMask = 2147483647; 223 | files = ( 224 | C0E67C4127540AFC00F8EC58 /* Screens.swift in Sources */, 225 | C0B1C5742752E877002DD942 /* RootView.swift in Sources */, 226 | C0B1C5722752E877002DD942 /* TabViewRoutingApp.swift in Sources */, 227 | ); 228 | runOnlyForDeploymentPostprocessing = 0; 229 | }; 230 | /* End PBXSourcesBuildPhase section */ 231 | 232 | /* Begin XCBuildConfiguration section */ 233 | C0B1C5772752E877002DD942 /* Debug */ = { 234 | isa = XCBuildConfiguration; 235 | buildSettings = { 236 | ALWAYS_SEARCH_USER_PATHS = NO; 237 | CLANG_ANALYZER_NONNULL = YES; 238 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 239 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 240 | CLANG_CXX_LIBRARY = "libc++"; 241 | CLANG_ENABLE_MODULES = YES; 242 | CLANG_ENABLE_OBJC_ARC = YES; 243 | CLANG_ENABLE_OBJC_WEAK = YES; 244 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 245 | CLANG_WARN_BOOL_CONVERSION = YES; 246 | CLANG_WARN_COMMA = YES; 247 | CLANG_WARN_CONSTANT_CONVERSION = YES; 248 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 249 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 250 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 251 | CLANG_WARN_EMPTY_BODY = YES; 252 | CLANG_WARN_ENUM_CONVERSION = YES; 253 | CLANG_WARN_INFINITE_RECURSION = YES; 254 | CLANG_WARN_INT_CONVERSION = YES; 255 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 256 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 257 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 258 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 259 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 260 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 261 | CLANG_WARN_STRICT_PROTOTYPES = YES; 262 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 263 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 264 | CLANG_WARN_UNREACHABLE_CODE = YES; 265 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 266 | COPY_PHASE_STRIP = NO; 267 | DEBUG_INFORMATION_FORMAT = dwarf; 268 | ENABLE_STRICT_OBJC_MSGSEND = YES; 269 | ENABLE_TESTABILITY = YES; 270 | GCC_C_LANGUAGE_STANDARD = gnu11; 271 | GCC_DYNAMIC_NO_PIC = NO; 272 | GCC_NO_COMMON_BLOCKS = YES; 273 | GCC_OPTIMIZATION_LEVEL = 0; 274 | GCC_PREPROCESSOR_DEFINITIONS = ( 275 | "DEBUG=1", 276 | "$(inherited)", 277 | ); 278 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 279 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 280 | GCC_WARN_UNDECLARED_SELECTOR = YES; 281 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 282 | GCC_WARN_UNUSED_FUNCTION = YES; 283 | GCC_WARN_UNUSED_VARIABLE = YES; 284 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 285 | MTL_FAST_MATH = YES; 286 | ONLY_ACTIVE_ARCH = YES; 287 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 288 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 289 | }; 290 | name = Debug; 291 | }; 292 | C0B1C5782752E877002DD942 /* Release */ = { 293 | isa = XCBuildConfiguration; 294 | buildSettings = { 295 | ALWAYS_SEARCH_USER_PATHS = NO; 296 | CLANG_ANALYZER_NONNULL = YES; 297 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 298 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 299 | CLANG_CXX_LIBRARY = "libc++"; 300 | CLANG_ENABLE_MODULES = YES; 301 | CLANG_ENABLE_OBJC_ARC = YES; 302 | CLANG_ENABLE_OBJC_WEAK = YES; 303 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 304 | CLANG_WARN_BOOL_CONVERSION = YES; 305 | CLANG_WARN_COMMA = YES; 306 | CLANG_WARN_CONSTANT_CONVERSION = YES; 307 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 308 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 309 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 310 | CLANG_WARN_EMPTY_BODY = YES; 311 | CLANG_WARN_ENUM_CONVERSION = YES; 312 | CLANG_WARN_INFINITE_RECURSION = YES; 313 | CLANG_WARN_INT_CONVERSION = YES; 314 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 315 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 316 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 317 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 318 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 319 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 320 | CLANG_WARN_STRICT_PROTOTYPES = YES; 321 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 322 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 323 | CLANG_WARN_UNREACHABLE_CODE = YES; 324 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 325 | COPY_PHASE_STRIP = NO; 326 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 327 | ENABLE_NS_ASSERTIONS = NO; 328 | ENABLE_STRICT_OBJC_MSGSEND = YES; 329 | GCC_C_LANGUAGE_STANDARD = gnu11; 330 | GCC_NO_COMMON_BLOCKS = YES; 331 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 332 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 333 | GCC_WARN_UNDECLARED_SELECTOR = YES; 334 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 335 | GCC_WARN_UNUSED_FUNCTION = YES; 336 | GCC_WARN_UNUSED_VARIABLE = YES; 337 | MTL_ENABLE_DEBUG_INFO = NO; 338 | MTL_FAST_MATH = YES; 339 | SWIFT_COMPILATION_MODE = wholemodule; 340 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 341 | }; 342 | name = Release; 343 | }; 344 | C0B1C57A2752E877002DD942 /* Debug */ = { 345 | isa = XCBuildConfiguration; 346 | buildSettings = { 347 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 348 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 349 | CODE_SIGN_STYLE = Automatic; 350 | CURRENT_PROJECT_VERSION = 1; 351 | DEVELOPMENT_TEAM = QSR4FL5D2K; 352 | ENABLE_PREVIEWS = YES; 353 | GENERATE_INFOPLIST_FILE = YES; 354 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 355 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 356 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 357 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 358 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 359 | IPHONEOS_DEPLOYMENT_TARGET = 15.2; 360 | LD_RUNPATH_SEARCH_PATHS = ( 361 | "$(inherited)", 362 | "@executable_path/Frameworks", 363 | ); 364 | MARKETING_VERSION = 1.0; 365 | PRODUCT_BUNDLE_IDENTIFIER = com.frzi.TabViewRouting; 366 | PRODUCT_NAME = TabViewRouting; 367 | SDKROOT = iphoneos; 368 | SWIFT_EMIT_LOC_STRINGS = YES; 369 | SWIFT_VERSION = 5.0; 370 | TARGETED_DEVICE_FAMILY = "1,2"; 371 | }; 372 | name = Debug; 373 | }; 374 | C0B1C57B2752E877002DD942 /* Release */ = { 375 | isa = XCBuildConfiguration; 376 | buildSettings = { 377 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 378 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 379 | CODE_SIGN_STYLE = Automatic; 380 | CURRENT_PROJECT_VERSION = 1; 381 | DEVELOPMENT_TEAM = QSR4FL5D2K; 382 | ENABLE_PREVIEWS = YES; 383 | GENERATE_INFOPLIST_FILE = YES; 384 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 385 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 386 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 387 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 388 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 389 | IPHONEOS_DEPLOYMENT_TARGET = 15.2; 390 | LD_RUNPATH_SEARCH_PATHS = ( 391 | "$(inherited)", 392 | "@executable_path/Frameworks", 393 | ); 394 | MARKETING_VERSION = 1.0; 395 | PRODUCT_BUNDLE_IDENTIFIER = com.frzi.TabViewRouting; 396 | PRODUCT_NAME = TabViewRouting; 397 | SDKROOT = iphoneos; 398 | SWIFT_EMIT_LOC_STRINGS = YES; 399 | SWIFT_VERSION = 5.0; 400 | TARGETED_DEVICE_FAMILY = "1,2"; 401 | VALIDATE_PRODUCT = YES; 402 | }; 403 | name = Release; 404 | }; 405 | C0B1C57D2752E877002DD942 /* Debug */ = { 406 | isa = XCBuildConfiguration; 407 | buildSettings = { 408 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 409 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 410 | CODE_SIGN_ENTITLEMENTS = macOS/macOS.entitlements; 411 | CODE_SIGN_STYLE = Automatic; 412 | COMBINE_HIDPI_IMAGES = YES; 413 | CURRENT_PROJECT_VERSION = 1; 414 | DEVELOPMENT_TEAM = QSR4FL5D2K; 415 | ENABLE_HARDENED_RUNTIME = YES; 416 | ENABLE_PREVIEWS = YES; 417 | GENERATE_INFOPLIST_FILE = YES; 418 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 419 | LD_RUNPATH_SEARCH_PATHS = ( 420 | "$(inherited)", 421 | "@executable_path/../Frameworks", 422 | ); 423 | MACOSX_DEPLOYMENT_TARGET = 12.0; 424 | MARKETING_VERSION = 1.0; 425 | PRODUCT_BUNDLE_IDENTIFIER = com.frzi.TabViewRouting; 426 | PRODUCT_NAME = TabViewRouting; 427 | SDKROOT = macosx; 428 | SWIFT_EMIT_LOC_STRINGS = YES; 429 | SWIFT_VERSION = 5.0; 430 | }; 431 | name = Debug; 432 | }; 433 | C0B1C57E2752E877002DD942 /* Release */ = { 434 | isa = XCBuildConfiguration; 435 | buildSettings = { 436 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 437 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 438 | CODE_SIGN_ENTITLEMENTS = macOS/macOS.entitlements; 439 | CODE_SIGN_STYLE = Automatic; 440 | COMBINE_HIDPI_IMAGES = YES; 441 | CURRENT_PROJECT_VERSION = 1; 442 | DEVELOPMENT_TEAM = QSR4FL5D2K; 443 | ENABLE_HARDENED_RUNTIME = YES; 444 | ENABLE_PREVIEWS = YES; 445 | GENERATE_INFOPLIST_FILE = YES; 446 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 447 | LD_RUNPATH_SEARCH_PATHS = ( 448 | "$(inherited)", 449 | "@executable_path/../Frameworks", 450 | ); 451 | MACOSX_DEPLOYMENT_TARGET = 12.0; 452 | MARKETING_VERSION = 1.0; 453 | PRODUCT_BUNDLE_IDENTIFIER = com.frzi.TabViewRouting; 454 | PRODUCT_NAME = TabViewRouting; 455 | SDKROOT = macosx; 456 | SWIFT_EMIT_LOC_STRINGS = YES; 457 | SWIFT_VERSION = 5.0; 458 | }; 459 | name = Release; 460 | }; 461 | /* End XCBuildConfiguration section */ 462 | 463 | /* Begin XCConfigurationList section */ 464 | C0B1C55F2752E875002DD942 /* Build configuration list for PBXProject "TabViewRouting" */ = { 465 | isa = XCConfigurationList; 466 | buildConfigurations = ( 467 | C0B1C5772752E877002DD942 /* Debug */, 468 | C0B1C5782752E877002DD942 /* Release */, 469 | ); 470 | defaultConfigurationIsVisible = 0; 471 | defaultConfigurationName = Release; 472 | }; 473 | C0B1C5792752E877002DD942 /* Build configuration list for PBXNativeTarget "TabViewRouting (iOS)" */ = { 474 | isa = XCConfigurationList; 475 | buildConfigurations = ( 476 | C0B1C57A2752E877002DD942 /* Debug */, 477 | C0B1C57B2752E877002DD942 /* Release */, 478 | ); 479 | defaultConfigurationIsVisible = 0; 480 | defaultConfigurationName = Release; 481 | }; 482 | C0B1C57C2752E877002DD942 /* Build configuration list for PBXNativeTarget "TabViewRouting (macOS)" */ = { 483 | isa = XCConfigurationList; 484 | buildConfigurations = ( 485 | C0B1C57D2752E877002DD942 /* Debug */, 486 | C0B1C57E2752E877002DD942 /* Release */, 487 | ); 488 | defaultConfigurationIsVisible = 0; 489 | defaultConfigurationName = Release; 490 | }; 491 | /* End XCConfigurationList section */ 492 | 493 | /* Begin XCRemoteSwiftPackageReference section */ 494 | C0B1C5892752F2FB002DD942 /* XCRemoteSwiftPackageReference "SwiftUIRouter" */ = { 495 | isa = XCRemoteSwiftPackageReference; 496 | repositoryURL = "https://github.com/frzi/SwiftUIRouter"; 497 | requirement = { 498 | kind = upToNextMajorVersion; 499 | minimumVersion = 1.3.0; 500 | }; 501 | }; 502 | /* End XCRemoteSwiftPackageReference section */ 503 | 504 | /* Begin XCSwiftPackageProductDependency section */ 505 | C0B1C58A2752F2FB002DD942 /* SwiftUIRouter */ = { 506 | isa = XCSwiftPackageProductDependency; 507 | package = C0B1C5892752F2FB002DD942 /* XCRemoteSwiftPackageReference "SwiftUIRouter" */; 508 | productName = SwiftUIRouter; 509 | }; 510 | C0B1C58C2752F301002DD942 /* SwiftUIRouter */ = { 511 | isa = XCSwiftPackageProductDependency; 512 | package = C0B1C5892752F2FB002DD942 /* XCRemoteSwiftPackageReference "SwiftUIRouter" */; 513 | productName = SwiftUIRouter; 514 | }; 515 | /* End XCSwiftPackageProductDependency section */ 516 | }; 517 | rootObject = C0B1C55C2752E875002DD942 /* Project object */; 518 | } 519 | -------------------------------------------------------------------------------- /TabViewRouting/TabViewRouting.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /TabViewRouting/TabViewRouting.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /TabViewRouting/TabViewRouting.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "object": { 3 | "pins": [ 4 | { 5 | "package": "SwiftUIRouter", 6 | "repositoryURL": "https://github.com/frzi/SwiftUIRouter", 7 | "state": { 8 | "branch": null, 9 | "revision": "5e69c689ceaae3c8ed52ae535f294aeb262dc812", 10 | "version": "1.3.0" 11 | } 12 | } 13 | ] 14 | }, 15 | "version": 1 16 | } 17 | -------------------------------------------------------------------------------- /TabViewRouting/iOS/RootView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TabViewRouting 3 | // Created by Freek (github.com/frzi) 2021 4 | // 5 | 6 | import SwiftUI 7 | import SwiftUIRouter 8 | 9 | extension String: Identifiable { 10 | public var id: String { self } 11 | } 12 | 13 | struct RootView: View { 14 | @EnvironmentObject private var navigator: Navigator 15 | 16 | @State private var selected = -1 17 | 18 | private let titles: [(title: String, image: String)] = [ 19 | ("Movies", "film"), 20 | ("Music", "music.note"), 21 | ("Books", "book"), 22 | ] 23 | 24 | var body: some View { 25 | TabView(selection: $selected) { 26 | ForEach(0.. 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | --------------------------------------------------------------------------------