├── .assets ├── AppIcon.png ├── AppPreview1.gif ├── Screenshot1.png ├── Screenshot2.png ├── Screenshot3.png ├── Screenshot4.png └── Screenshot5.png ├── .gitignore ├── AppStoreReplica ├── AppStoreReplica.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── xcshareddata │ │ └── xcschemes │ │ │ └── AppStoreReplica.xcscheme │ └── xcuserdata │ │ └── BES.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ └── xcschememanagement.plist └── AppStoreReplica │ ├── ContentView.swift │ ├── Extensions │ └── Date+Ext.swift │ ├── Preview Content │ └── Preview Assets.xcassets │ │ └── Contents.json │ ├── Resources │ └── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ ├── AppIcon-1024.png │ │ ├── AppIcon-20.png │ │ ├── AppIcon-20@2x.png │ │ ├── AppIcon-20@3x.png │ │ ├── AppIcon-29.png │ │ ├── AppIcon-29@2x.png │ │ ├── AppIcon-29@3x.png │ │ ├── AppIcon-40.png │ │ ├── AppIcon-40@2x.png │ │ ├── AppIcon-40@3x.png │ │ ├── AppIcon-60@2x.png │ │ ├── AppIcon-60@3x.png │ │ ├── AppIcon-76.png │ │ ├── AppIcon-76@2x.png │ │ ├── AppIcon-83.5@2x.png │ │ └── Contents.json │ │ └── Contents.json │ ├── Supporting files │ ├── AppStoreApp.swift │ └── Info.plist │ └── Views │ ├── Blocks │ ├── Apps │ │ ├── AppLarge1Block.swift │ │ ├── AppLarge2Block.swift │ │ ├── AppLarge3Block.swift │ │ ├── AppMedium1Block.swift │ │ ├── AppMedium2Block.swift │ │ ├── AppSmall1Block.swift │ │ └── AppSmall2Block.swift │ ├── Carousels │ │ ├── AppCarouselExtraLargeBlock.swift │ │ ├── AppCarouselLargeBlock.swift │ │ ├── AppCarouselMedium1Block.swift │ │ ├── AppCarouselMedium2Block.swift │ │ ├── AppCarouselSmall1Block.swift │ │ └── AppCarouselSmall2Block.swift │ ├── Headers │ │ ├── ArcadeHeader.swift │ │ ├── NavigationViewHeaderBlock.swift │ │ ├── NavigationViewHeaderWithImageBlock.swift │ │ ├── SectionHeaderBlock.swift │ │ └── SectionHeaderExtendedBlock.swift │ └── Sections │ │ ├── DiscoverBlock.swift │ │ ├── QuickLinksBlock.swift │ │ ├── SuggestedAppsBlock.swift │ │ ├── TermsAndConditionsBlock.swift │ │ ├── TopAppsCategoriesBlock.swift │ │ └── TopGamesCategoriesBlock.swift │ ├── Elements │ ├── Buttons │ │ ├── AccountButton.swift │ │ ├── DefaultButton.swift │ │ ├── DismissButton.swift │ │ ├── GetButton.swift │ │ ├── SingleLineButton.swift │ │ ├── SingleLineIconAndButtonView.swift │ │ └── TryButton.swift │ ├── Labels │ │ ├── InAppPurchasesLabel.swift │ │ ├── ItemDetailsLabel.swift │ │ └── ItemTitleLabel.swift │ ├── Lists │ │ └── RecentlyUpdatedAppsList.swift │ ├── NavigationLinks │ │ ├── ProfileNavigationLink.swift │ │ └── SingleLineNavigationLink.swift │ ├── SearchBars │ │ └── SearchBar.swift │ └── Shapes │ │ └── AppShape.swift │ └── Screens │ ├── AccountView.swift │ ├── AppMainView.swift │ ├── AppsTabView.swift │ ├── ArcadeTabView.swift │ ├── DefaultView.swift │ ├── GamesTabView.swift │ ├── SearchTabView.swift │ └── TodayTabView.swift └── Readme.md /.assets/AppIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomEstelrich/AppStoreReplicaApp/3d7f4413755e1b6213c1bfbddf280ab915e0c86f/.assets/AppIcon.png -------------------------------------------------------------------------------- /.assets/AppPreview1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomEstelrich/AppStoreReplicaApp/3d7f4413755e1b6213c1bfbddf280ab915e0c86f/.assets/AppPreview1.gif -------------------------------------------------------------------------------- /.assets/Screenshot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomEstelrich/AppStoreReplicaApp/3d7f4413755e1b6213c1bfbddf280ab915e0c86f/.assets/Screenshot1.png -------------------------------------------------------------------------------- /.assets/Screenshot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomEstelrich/AppStoreReplicaApp/3d7f4413755e1b6213c1bfbddf280ab915e0c86f/.assets/Screenshot2.png -------------------------------------------------------------------------------- /.assets/Screenshot3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomEstelrich/AppStoreReplicaApp/3d7f4413755e1b6213c1bfbddf280ab915e0c86f/.assets/Screenshot3.png -------------------------------------------------------------------------------- /.assets/Screenshot4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomEstelrich/AppStoreReplicaApp/3d7f4413755e1b6213c1bfbddf280ab915e0c86f/.assets/Screenshot4.png -------------------------------------------------------------------------------- /.assets/Screenshot5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomEstelrich/AppStoreReplicaApp/3d7f4413755e1b6213c1bfbddf280ab915e0c86f/.assets/Screenshot5.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /AppStoreReplica/AppStoreReplica.xcodeproj/project.xcworkspace/xcuserdata/BES.xcuserdatad/UserInterfaceState.xcuserstate 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | C92112CB24CF927600B74FEE /* DefaultView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C92112CA24CF927600B74FEE /* DefaultView.swift */; }; 11 | C922477F24CF89D10013F293 /* GetButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = C922477E24CF89D10013F293 /* GetButton.swift */; }; 12 | C922478124CF8B250013F293 /* InAppPurchasesLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C922478024CF8B250013F293 /* InAppPurchasesLabel.swift */; }; 13 | C922478324CF8BD40013F293 /* TryButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = C922478224CF8BD40013F293 /* TryButton.swift */; }; 14 | C92F643C24D3163400A5DEB8 /* AppCarouselMedium2Block.swift in Sources */ = {isa = PBXBuildFile; fileRef = C92F643B24D3163400A5DEB8 /* AppCarouselMedium2Block.swift */; }; 15 | C92F643E24D3199300A5DEB8 /* ArcadeHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = C92F643D24D3199300A5DEB8 /* ArcadeHeader.swift */; }; 16 | C92F644024D3214700A5DEB8 /* AppCarouselSmall2Block.swift in Sources */ = {isa = PBXBuildFile; fileRef = C92F643F24D3214700A5DEB8 /* AppCarouselSmall2Block.swift */; }; 17 | C92F644224D325C200A5DEB8 /* AppShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = C92F644124D325C200A5DEB8 /* AppShape.swift */; }; 18 | C932352224CE18D000D3839F /* SearchBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = C932352124CE18D000D3839F /* SearchBar.swift */; }; 19 | C951D58724D2052F00C4EF26 /* Date+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = C951D58624D2052F00C4EF26 /* Date+Ext.swift */; }; 20 | C95A19BC24C5FB2D0055BDA1 /* SingleLineButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = C95A19BB24C5FB2D0055BDA1 /* SingleLineButton.swift */; }; 21 | C95A19BE24C5FB570055BDA1 /* RecentlyUpdatedAppsList.swift in Sources */ = {isa = PBXBuildFile; fileRef = C95A19BD24C5FB570055BDA1 /* RecentlyUpdatedAppsList.swift */; }; 22 | C97D65D324CF8C7C00E1640F /* SectionHeaderBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C97D65D224CF8C7C00E1640F /* SectionHeaderBlock.swift */; }; 23 | C98A3B0A24C4E018009387D3 /* AppStoreApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = C98A3B0924C4E018009387D3 /* AppStoreApp.swift */; }; 24 | C98A3B0C24C4E018009387D3 /* AppMainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C98A3B0B24C4E018009387D3 /* AppMainView.swift */; }; 25 | C98A3B0E24C4E019009387D3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C98A3B0D24C4E019009387D3 /* Assets.xcassets */; }; 26 | C98A3B1124C4E019009387D3 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C98A3B1024C4E019009387D3 /* Preview Assets.xcassets */; }; 27 | C98A3B1E24C4F2DD009387D3 /* TodayTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C98A3B1D24C4F2DD009387D3 /* TodayTabView.swift */; }; 28 | C98A3B2024C4F304009387D3 /* GamesTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C98A3B1F24C4F304009387D3 /* GamesTabView.swift */; }; 29 | C98A3B2224C4F31F009387D3 /* AppsTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C98A3B2124C4F31F009387D3 /* AppsTabView.swift */; }; 30 | C98A3B2424C4F348009387D3 /* ArcadeTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C98A3B2324C4F348009387D3 /* ArcadeTabView.swift */; }; 31 | C98A3B2624C4F364009387D3 /* SearchTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C98A3B2524C4F364009387D3 /* SearchTabView.swift */; }; 32 | C98A3B2924C4F476009387D3 /* AppCarouselLargeBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C98A3B2824C4F476009387D3 /* AppCarouselLargeBlock.swift */; }; 33 | C98A3B2B24C4F490009387D3 /* AppCarouselSmall1Block.swift in Sources */ = {isa = PBXBuildFile; fileRef = C98A3B2A24C4F490009387D3 /* AppCarouselSmall1Block.swift */; }; 34 | C98A3B2D24C4F4A8009387D3 /* AppSmall1Block.swift in Sources */ = {isa = PBXBuildFile; fileRef = C98A3B2C24C4F4A8009387D3 /* AppSmall1Block.swift */; }; 35 | C98A3B2F24C4F8CB009387D3 /* NavigationViewHeaderBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C98A3B2E24C4F8CB009387D3 /* NavigationViewHeaderBlock.swift */; }; 36 | C999AF7024CE44E400EB346A /* QuickLinksBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C999AF6F24CE44E400EB346A /* QuickLinksBlock.swift */; }; 37 | C999AF7224CE468E00EB346A /* DefaultButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = C999AF7124CE468E00EB346A /* DefaultButton.swift */; }; 38 | C999AF7424CE490600EB346A /* TermsAndConditionsBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C999AF7324CE490600EB346A /* TermsAndConditionsBlock.swift */; }; 39 | C99ED4ED24D30397006A8D71 /* TopAppsCategoriesBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C99ED4EC24D30397006A8D71 /* TopAppsCategoriesBlock.swift */; }; 40 | C99ED4EF24D305F0006A8D71 /* AppMedium2Block.swift in Sources */ = {isa = PBXBuildFile; fileRef = C99ED4EE24D305F0006A8D71 /* AppMedium2Block.swift */; }; 41 | C9A128E824C5DC88008A54D5 /* AccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9A128E724C5DC88008A54D5 /* AccountView.swift */; }; 42 | C9A128EA24C5DECC008A54D5 /* AccountButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9A128E924C5DECC008A54D5 /* AccountButton.swift */; }; 43 | C9A128ED24C5E377008A54D5 /* DismissButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9A128EC24C5E377008A54D5 /* DismissButton.swift */; }; 44 | C9C0852424D22E540021C29D /* NavigationViewHeaderWithImageBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9C0852324D22E540021C29D /* NavigationViewHeaderWithImageBlock.swift */; }; 45 | C9C0852624D230AB0021C29D /* AppCarouselExtraLargeBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9C0852524D230AB0021C29D /* AppCarouselExtraLargeBlock.swift */; }; 46 | C9D91B2824C625AC00DB0008 /* DiscoverBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9D91B2724C625AC00DB0008 /* DiscoverBlock.swift */; }; 47 | C9D91B2A24C625CC00DB0008 /* SuggestedAppsBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9D91B2924C625CC00DB0008 /* SuggestedAppsBlock.swift */; }; 48 | C9D91B2C24C643F300DB0008 /* AppSmall2Block.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9D91B2B24C643F300DB0008 /* AppSmall2Block.swift */; }; 49 | C9D91B2F24C6470700DB0008 /* AppLarge1Block.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9D91B2E24C6470700DB0008 /* AppLarge1Block.swift */; }; 50 | C9D91B3224C6477800DB0008 /* AppLarge2Block.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9D91B3124C6477800DB0008 /* AppLarge2Block.swift */; }; 51 | C9D91B3424C6479900DB0008 /* AppLarge3Block.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9D91B3324C6479800DB0008 /* AppLarge3Block.swift */; }; 52 | C9E7620F24CE29F60029264E /* ItemDetailsLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9E7620E24CE29F60029264E /* ItemDetailsLabel.swift */; }; 53 | C9E7621124CE2A500029264E /* ItemTitleLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9E7621024CE2A500029264E /* ItemTitleLabel.swift */; }; 54 | C9E7621424CE326D0029264E /* AppMedium1Block.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9E7621324CE326D0029264E /* AppMedium1Block.swift */; }; 55 | C9E7621624CE38C30029264E /* AppCarouselMedium1Block.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9E7621524CE38C30029264E /* AppCarouselMedium1Block.swift */; }; 56 | C9E7621824CE41050029264E /* SingleLineIconAndButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9E7621724CE41050029264E /* SingleLineIconAndButtonView.swift */; }; 57 | C9E7621A24CE42F20029264E /* TopGamesCategoriesBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9E7621924CE42F20029264E /* TopGamesCategoriesBlock.swift */; }; 58 | C9F2565F24CF80AD00549B6C /* SectionHeaderExtendedBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9F2565E24CF80AD00549B6C /* SectionHeaderExtendedBlock.swift */; }; 59 | C9F63BA724C5EABC00ECA58B /* ProfileNavigationLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9F63BA624C5EABC00ECA58B /* ProfileNavigationLink.swift */; }; 60 | C9F63BAA24C5EAEF00ECA58B /* SingleLineNavigationLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9F63BA924C5EAEF00ECA58B /* SingleLineNavigationLink.swift */; }; 61 | /* End PBXBuildFile section */ 62 | 63 | /* Begin PBXFileReference section */ 64 | C92112CA24CF927600B74FEE /* DefaultView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = DefaultView.swift; path = AppStoreReplica/Views/Screens/DefaultView.swift; sourceTree = SOURCE_ROOT; }; 65 | C922477E24CF89D10013F293 /* GetButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GetButton.swift; sourceTree = ""; }; 66 | C922478024CF8B250013F293 /* InAppPurchasesLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InAppPurchasesLabel.swift; sourceTree = ""; }; 67 | C922478224CF8BD40013F293 /* TryButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TryButton.swift; sourceTree = ""; }; 68 | C92F643B24D3163400A5DEB8 /* AppCarouselMedium2Block.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCarouselMedium2Block.swift; sourceTree = ""; }; 69 | C92F643D24D3199300A5DEB8 /* ArcadeHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArcadeHeader.swift; sourceTree = ""; }; 70 | C92F643F24D3214700A5DEB8 /* AppCarouselSmall2Block.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCarouselSmall2Block.swift; sourceTree = ""; }; 71 | C92F644124D325C200A5DEB8 /* AppShape.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppShape.swift; sourceTree = ""; }; 72 | C932352124CE18D000D3839F /* SearchBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchBar.swift; sourceTree = ""; }; 73 | C951D58624D2052F00C4EF26 /* Date+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Date+Ext.swift"; sourceTree = ""; }; 74 | C95A19BB24C5FB2D0055BDA1 /* SingleLineButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleLineButton.swift; sourceTree = ""; }; 75 | C95A19BD24C5FB570055BDA1 /* RecentlyUpdatedAppsList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecentlyUpdatedAppsList.swift; sourceTree = ""; }; 76 | C97D65D224CF8C7C00E1640F /* SectionHeaderBlock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionHeaderBlock.swift; sourceTree = ""; }; 77 | C98A3B0624C4E018009387D3 /* AppStoreReplica.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AppStoreReplica.app; sourceTree = BUILT_PRODUCTS_DIR; }; 78 | C98A3B0924C4E018009387D3 /* AppStoreApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppStoreApp.swift; sourceTree = ""; }; 79 | C98A3B0B24C4E018009387D3 /* AppMainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppMainView.swift; sourceTree = ""; }; 80 | C98A3B0D24C4E019009387D3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 81 | C98A3B1024C4E019009387D3 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 82 | C98A3B1224C4E019009387D3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 83 | C98A3B1D24C4F2DD009387D3 /* TodayTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodayTabView.swift; sourceTree = ""; }; 84 | C98A3B1F24C4F304009387D3 /* GamesTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GamesTabView.swift; sourceTree = ""; }; 85 | C98A3B2124C4F31F009387D3 /* AppsTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppsTabView.swift; sourceTree = ""; }; 86 | C98A3B2324C4F348009387D3 /* ArcadeTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArcadeTabView.swift; sourceTree = ""; }; 87 | C98A3B2524C4F364009387D3 /* SearchTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchTabView.swift; sourceTree = ""; }; 88 | C98A3B2824C4F476009387D3 /* AppCarouselLargeBlock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCarouselLargeBlock.swift; sourceTree = ""; }; 89 | C98A3B2A24C4F490009387D3 /* AppCarouselSmall1Block.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCarouselSmall1Block.swift; sourceTree = ""; }; 90 | C98A3B2C24C4F4A8009387D3 /* AppSmall1Block.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSmall1Block.swift; sourceTree = ""; }; 91 | C98A3B2E24C4F8CB009387D3 /* NavigationViewHeaderBlock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationViewHeaderBlock.swift; sourceTree = ""; }; 92 | C999AF6F24CE44E400EB346A /* QuickLinksBlock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickLinksBlock.swift; sourceTree = ""; }; 93 | C999AF7124CE468E00EB346A /* DefaultButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultButton.swift; sourceTree = ""; }; 94 | C999AF7324CE490600EB346A /* TermsAndConditionsBlock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TermsAndConditionsBlock.swift; sourceTree = ""; }; 95 | C99ED4EC24D30397006A8D71 /* TopAppsCategoriesBlock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TopAppsCategoriesBlock.swift; sourceTree = ""; }; 96 | C99ED4EE24D305F0006A8D71 /* AppMedium2Block.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppMedium2Block.swift; sourceTree = ""; }; 97 | C9A128E724C5DC88008A54D5 /* AccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountView.swift; sourceTree = ""; }; 98 | C9A128E924C5DECC008A54D5 /* AccountButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountButton.swift; sourceTree = ""; }; 99 | C9A128EC24C5E377008A54D5 /* DismissButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DismissButton.swift; sourceTree = ""; }; 100 | C9C0852324D22E540021C29D /* NavigationViewHeaderWithImageBlock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationViewHeaderWithImageBlock.swift; sourceTree = ""; }; 101 | C9C0852524D230AB0021C29D /* AppCarouselExtraLargeBlock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCarouselExtraLargeBlock.swift; sourceTree = ""; }; 102 | C9D91B2724C625AC00DB0008 /* DiscoverBlock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiscoverBlock.swift; sourceTree = ""; }; 103 | C9D91B2924C625CC00DB0008 /* SuggestedAppsBlock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuggestedAppsBlock.swift; sourceTree = ""; }; 104 | C9D91B2B24C643F300DB0008 /* AppSmall2Block.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSmall2Block.swift; sourceTree = ""; }; 105 | C9D91B2E24C6470700DB0008 /* AppLarge1Block.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLarge1Block.swift; sourceTree = ""; }; 106 | C9D91B3124C6477800DB0008 /* AppLarge2Block.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLarge2Block.swift; sourceTree = ""; }; 107 | C9D91B3324C6479800DB0008 /* AppLarge3Block.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLarge3Block.swift; sourceTree = ""; }; 108 | C9E7620E24CE29F60029264E /* ItemDetailsLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemDetailsLabel.swift; sourceTree = ""; }; 109 | C9E7621024CE2A500029264E /* ItemTitleLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemTitleLabel.swift; sourceTree = ""; }; 110 | C9E7621324CE326D0029264E /* AppMedium1Block.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppMedium1Block.swift; sourceTree = ""; }; 111 | C9E7621524CE38C30029264E /* AppCarouselMedium1Block.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCarouselMedium1Block.swift; sourceTree = ""; }; 112 | C9E7621724CE41050029264E /* SingleLineIconAndButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleLineIconAndButtonView.swift; sourceTree = ""; }; 113 | C9E7621924CE42F20029264E /* TopGamesCategoriesBlock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TopGamesCategoriesBlock.swift; sourceTree = ""; }; 114 | C9F2565E24CF80AD00549B6C /* SectionHeaderExtendedBlock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SectionHeaderExtendedBlock.swift; sourceTree = ""; }; 115 | C9F63BA624C5EABC00ECA58B /* ProfileNavigationLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileNavigationLink.swift; sourceTree = ""; }; 116 | C9F63BA924C5EAEF00ECA58B /* SingleLineNavigationLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleLineNavigationLink.swift; sourceTree = ""; }; 117 | /* End PBXFileReference section */ 118 | 119 | /* Begin PBXFrameworksBuildPhase section */ 120 | C98A3B0324C4E018009387D3 /* Frameworks */ = { 121 | isa = PBXFrameworksBuildPhase; 122 | buildActionMask = 2147483647; 123 | files = ( 124 | ); 125 | runOnlyForDeploymentPostprocessing = 0; 126 | }; 127 | /* End PBXFrameworksBuildPhase section */ 128 | 129 | /* Begin PBXGroup section */ 130 | C922478424CF8C2B0013F293 /* Headers */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | C98A3B2E24C4F8CB009387D3 /* NavigationViewHeaderBlock.swift */, 134 | C9C0852324D22E540021C29D /* NavigationViewHeaderWithImageBlock.swift */, 135 | C97D65D224CF8C7C00E1640F /* SectionHeaderBlock.swift */, 136 | C9F2565E24CF80AD00549B6C /* SectionHeaderExtendedBlock.swift */, 137 | C92F643D24D3199300A5DEB8 /* ArcadeHeader.swift */, 138 | ); 139 | path = Headers; 140 | sourceTree = ""; 141 | }; 142 | C92F644324D325D200A5DEB8 /* Shapes */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | C92F644124D325C200A5DEB8 /* AppShape.swift */, 146 | ); 147 | path = Shapes; 148 | sourceTree = ""; 149 | }; 150 | C932352324CE1C5200D3839F /* SearchBars */ = { 151 | isa = PBXGroup; 152 | children = ( 153 | C932352124CE18D000D3839F /* SearchBar.swift */, 154 | ); 155 | path = SearchBars; 156 | sourceTree = ""; 157 | }; 158 | C951D58824D2054B00C4EF26 /* Extensions */ = { 159 | isa = PBXGroup; 160 | children = ( 161 | C951D58624D2052F00C4EF26 /* Date+Ext.swift */, 162 | ); 163 | path = Extensions; 164 | sourceTree = ""; 165 | }; 166 | C95A19BF24C5FB730055BDA1 /* Lists */ = { 167 | isa = PBXGroup; 168 | children = ( 169 | C95A19BD24C5FB570055BDA1 /* RecentlyUpdatedAppsList.swift */, 170 | ); 171 | path = Lists; 172 | sourceTree = ""; 173 | }; 174 | C98A3AFD24C4E018009387D3 = { 175 | isa = PBXGroup; 176 | children = ( 177 | C98A3B0824C4E018009387D3 /* AppStoreReplica */, 178 | C98A3B0724C4E018009387D3 /* Products */, 179 | ); 180 | sourceTree = ""; 181 | }; 182 | C98A3B0724C4E018009387D3 /* Products */ = { 183 | isa = PBXGroup; 184 | children = ( 185 | C98A3B0624C4E018009387D3 /* AppStoreReplica.app */, 186 | ); 187 | name = Products; 188 | sourceTree = ""; 189 | }; 190 | C98A3B0824C4E018009387D3 /* AppStoreReplica */ = { 191 | isa = PBXGroup; 192 | children = ( 193 | C98A3B3124C4F91B009387D3 /* Supporting files */, 194 | C98A3B1B24C4F2AA009387D3 /* Views */, 195 | C98A3B3024C4F90E009387D3 /* Resources */, 196 | C951D58824D2054B00C4EF26 /* Extensions */, 197 | C98A3B0F24C4E019009387D3 /* Preview Content */, 198 | ); 199 | path = AppStoreReplica; 200 | sourceTree = ""; 201 | }; 202 | C98A3B0F24C4E019009387D3 /* Preview Content */ = { 203 | isa = PBXGroup; 204 | children = ( 205 | C98A3B1024C4E019009387D3 /* Preview Assets.xcassets */, 206 | ); 207 | path = "Preview Content"; 208 | sourceTree = ""; 209 | }; 210 | C98A3B1B24C4F2AA009387D3 /* Views */ = { 211 | isa = PBXGroup; 212 | children = ( 213 | C98A3B1C24C4F2C3009387D3 /* Screens */, 214 | C9D91B3024C6474400DB0008 /* Blocks */, 215 | C9FA305F24C6562500C356ED /* Elements */, 216 | ); 217 | path = Views; 218 | sourceTree = ""; 219 | }; 220 | C98A3B1C24C4F2C3009387D3 /* Screens */ = { 221 | isa = PBXGroup; 222 | children = ( 223 | C98A3B0B24C4E018009387D3 /* AppMainView.swift */, 224 | C98A3B1D24C4F2DD009387D3 /* TodayTabView.swift */, 225 | C98A3B1F24C4F304009387D3 /* GamesTabView.swift */, 226 | C98A3B2124C4F31F009387D3 /* AppsTabView.swift */, 227 | C98A3B2324C4F348009387D3 /* ArcadeTabView.swift */, 228 | C98A3B2524C4F364009387D3 /* SearchTabView.swift */, 229 | C9A128E724C5DC88008A54D5 /* AccountView.swift */, 230 | C92112CA24CF927600B74FEE /* DefaultView.swift */, 231 | ); 232 | path = Screens; 233 | sourceTree = ""; 234 | }; 235 | C98A3B3024C4F90E009387D3 /* Resources */ = { 236 | isa = PBXGroup; 237 | children = ( 238 | C98A3B0D24C4E019009387D3 /* Assets.xcassets */, 239 | ); 240 | path = Resources; 241 | sourceTree = ""; 242 | }; 243 | C98A3B3124C4F91B009387D3 /* Supporting files */ = { 244 | isa = PBXGroup; 245 | children = ( 246 | C98A3B1224C4E019009387D3 /* Info.plist */, 247 | C98A3B0924C4E018009387D3 /* AppStoreApp.swift */, 248 | ); 249 | path = "Supporting files"; 250 | sourceTree = ""; 251 | }; 252 | C9A128EB24C5DF18008A54D5 /* Buttons */ = { 253 | isa = PBXGroup; 254 | children = ( 255 | C9A128E924C5DECC008A54D5 /* AccountButton.swift */, 256 | C9A128EC24C5E377008A54D5 /* DismissButton.swift */, 257 | C95A19BB24C5FB2D0055BDA1 /* SingleLineButton.swift */, 258 | C9E7621724CE41050029264E /* SingleLineIconAndButtonView.swift */, 259 | C999AF7124CE468E00EB346A /* DefaultButton.swift */, 260 | C922477E24CF89D10013F293 /* GetButton.swift */, 261 | C922478224CF8BD40013F293 /* TryButton.swift */, 262 | ); 263 | path = Buttons; 264 | sourceTree = ""; 265 | }; 266 | C9D91B3024C6474400DB0008 /* Blocks */ = { 267 | isa = PBXGroup; 268 | children = ( 269 | C922478424CF8C2B0013F293 /* Headers */, 270 | C9DA553724CF8DD00062294F /* Carousels */, 271 | C9DA553624CF8DB90062294F /* Apps */, 272 | C9DA553824CF8DE30062294F /* Sections */, 273 | ); 274 | path = Blocks; 275 | sourceTree = ""; 276 | }; 277 | C9DA553624CF8DB90062294F /* Apps */ = { 278 | isa = PBXGroup; 279 | children = ( 280 | C9D91B2E24C6470700DB0008 /* AppLarge1Block.swift */, 281 | C9D91B3124C6477800DB0008 /* AppLarge2Block.swift */, 282 | C9D91B3324C6479800DB0008 /* AppLarge3Block.swift */, 283 | C9E7621324CE326D0029264E /* AppMedium1Block.swift */, 284 | C99ED4EE24D305F0006A8D71 /* AppMedium2Block.swift */, 285 | C98A3B2C24C4F4A8009387D3 /* AppSmall1Block.swift */, 286 | C9D91B2B24C643F300DB0008 /* AppSmall2Block.swift */, 287 | ); 288 | path = Apps; 289 | sourceTree = ""; 290 | }; 291 | C9DA553724CF8DD00062294F /* Carousels */ = { 292 | isa = PBXGroup; 293 | children = ( 294 | C98A3B2A24C4F490009387D3 /* AppCarouselSmall1Block.swift */, 295 | C92F643F24D3214700A5DEB8 /* AppCarouselSmall2Block.swift */, 296 | C9E7621524CE38C30029264E /* AppCarouselMedium1Block.swift */, 297 | C92F643B24D3163400A5DEB8 /* AppCarouselMedium2Block.swift */, 298 | C98A3B2824C4F476009387D3 /* AppCarouselLargeBlock.swift */, 299 | C9C0852524D230AB0021C29D /* AppCarouselExtraLargeBlock.swift */, 300 | ); 301 | path = Carousels; 302 | sourceTree = ""; 303 | }; 304 | C9DA553824CF8DE30062294F /* Sections */ = { 305 | isa = PBXGroup; 306 | children = ( 307 | C99ED4EC24D30397006A8D71 /* TopAppsCategoriesBlock.swift */, 308 | C9E7621924CE42F20029264E /* TopGamesCategoriesBlock.swift */, 309 | C999AF6F24CE44E400EB346A /* QuickLinksBlock.swift */, 310 | C9D91B2724C625AC00DB0008 /* DiscoverBlock.swift */, 311 | C9D91B2924C625CC00DB0008 /* SuggestedAppsBlock.swift */, 312 | C999AF7324CE490600EB346A /* TermsAndConditionsBlock.swift */, 313 | ); 314 | path = Sections; 315 | sourceTree = ""; 316 | }; 317 | C9E7621224CE2A7C0029264E /* Labels */ = { 318 | isa = PBXGroup; 319 | children = ( 320 | C922478024CF8B250013F293 /* InAppPurchasesLabel.swift */, 321 | C9E7621024CE2A500029264E /* ItemTitleLabel.swift */, 322 | C9E7620E24CE29F60029264E /* ItemDetailsLabel.swift */, 323 | ); 324 | path = Labels; 325 | sourceTree = ""; 326 | }; 327 | C9F63BA824C5EAC000ECA58B /* NavigationLinks */ = { 328 | isa = PBXGroup; 329 | children = ( 330 | C9F63BA624C5EABC00ECA58B /* ProfileNavigationLink.swift */, 331 | C9F63BA924C5EAEF00ECA58B /* SingleLineNavigationLink.swift */, 332 | ); 333 | path = NavigationLinks; 334 | sourceTree = ""; 335 | }; 336 | C9FA305F24C6562500C356ED /* Elements */ = { 337 | isa = PBXGroup; 338 | children = ( 339 | C9A128EB24C5DF18008A54D5 /* Buttons */, 340 | C95A19BF24C5FB730055BDA1 /* Lists */, 341 | C9F63BA824C5EAC000ECA58B /* NavigationLinks */, 342 | C932352324CE1C5200D3839F /* SearchBars */, 343 | C9E7621224CE2A7C0029264E /* Labels */, 344 | C92F644324D325D200A5DEB8 /* Shapes */, 345 | ); 346 | path = Elements; 347 | sourceTree = ""; 348 | }; 349 | /* End PBXGroup section */ 350 | 351 | /* Begin PBXNativeTarget section */ 352 | C98A3B0524C4E018009387D3 /* AppStoreReplica */ = { 353 | isa = PBXNativeTarget; 354 | buildConfigurationList = C98A3B1524C4E019009387D3 /* Build configuration list for PBXNativeTarget "AppStoreReplica" */; 355 | buildPhases = ( 356 | C98A3B0224C4E018009387D3 /* Sources */, 357 | C98A3B0324C4E018009387D3 /* Frameworks */, 358 | C98A3B0424C4E018009387D3 /* Resources */, 359 | ); 360 | buildRules = ( 361 | ); 362 | dependencies = ( 363 | ); 364 | name = AppStoreReplica; 365 | productName = AppStore; 366 | productReference = C98A3B0624C4E018009387D3 /* AppStoreReplica.app */; 367 | productType = "com.apple.product-type.application"; 368 | }; 369 | /* End PBXNativeTarget section */ 370 | 371 | /* Begin PBXProject section */ 372 | C98A3AFE24C4E018009387D3 /* Project object */ = { 373 | isa = PBXProject; 374 | attributes = { 375 | LastSwiftUpdateCheck = 1200; 376 | LastUpgradeCheck = 1200; 377 | TargetAttributes = { 378 | C98A3B0524C4E018009387D3 = { 379 | CreatedOnToolsVersion = 12.0; 380 | }; 381 | }; 382 | }; 383 | buildConfigurationList = C98A3B0124C4E018009387D3 /* Build configuration list for PBXProject "AppStoreReplica" */; 384 | compatibilityVersion = "Xcode 9.3"; 385 | developmentRegion = en; 386 | hasScannedForEncodings = 0; 387 | knownRegions = ( 388 | en, 389 | Base, 390 | ); 391 | mainGroup = C98A3AFD24C4E018009387D3; 392 | productRefGroup = C98A3B0724C4E018009387D3 /* Products */; 393 | projectDirPath = ""; 394 | projectRoot = ""; 395 | targets = ( 396 | C98A3B0524C4E018009387D3 /* AppStoreReplica */, 397 | ); 398 | }; 399 | /* End PBXProject section */ 400 | 401 | /* Begin PBXResourcesBuildPhase section */ 402 | C98A3B0424C4E018009387D3 /* Resources */ = { 403 | isa = PBXResourcesBuildPhase; 404 | buildActionMask = 2147483647; 405 | files = ( 406 | C98A3B1124C4E019009387D3 /* Preview Assets.xcassets in Resources */, 407 | C98A3B0E24C4E019009387D3 /* Assets.xcassets in Resources */, 408 | ); 409 | runOnlyForDeploymentPostprocessing = 0; 410 | }; 411 | /* End PBXResourcesBuildPhase section */ 412 | 413 | /* Begin PBXSourcesBuildPhase section */ 414 | C98A3B0224C4E018009387D3 /* Sources */ = { 415 | isa = PBXSourcesBuildPhase; 416 | buildActionMask = 2147483647; 417 | files = ( 418 | C98A3B2924C4F476009387D3 /* AppCarouselLargeBlock.swift in Sources */, 419 | C9D91B3224C6477800DB0008 /* AppLarge2Block.swift in Sources */, 420 | C92F643C24D3163400A5DEB8 /* AppCarouselMedium2Block.swift in Sources */, 421 | C98A3B2424C4F348009387D3 /* ArcadeTabView.swift in Sources */, 422 | C98A3B1E24C4F2DD009387D3 /* TodayTabView.swift in Sources */, 423 | C9C0852624D230AB0021C29D /* AppCarouselExtraLargeBlock.swift in Sources */, 424 | C92F643E24D3199300A5DEB8 /* ArcadeHeader.swift in Sources */, 425 | C9D91B2F24C6470700DB0008 /* AppLarge1Block.swift in Sources */, 426 | C951D58724D2052F00C4EF26 /* Date+Ext.swift in Sources */, 427 | C98A3B2D24C4F4A8009387D3 /* AppSmall1Block.swift in Sources */, 428 | C9E7621824CE41050029264E /* SingleLineIconAndButtonView.swift in Sources */, 429 | C98A3B2024C4F304009387D3 /* GamesTabView.swift in Sources */, 430 | C9F63BA724C5EABC00ECA58B /* ProfileNavigationLink.swift in Sources */, 431 | C9E7621124CE2A500029264E /* ItemTitleLabel.swift in Sources */, 432 | C9F63BAA24C5EAEF00ECA58B /* SingleLineNavigationLink.swift in Sources */, 433 | C92F644224D325C200A5DEB8 /* AppShape.swift in Sources */, 434 | C9C0852424D22E540021C29D /* NavigationViewHeaderWithImageBlock.swift in Sources */, 435 | C98A3B0C24C4E018009387D3 /* AppMainView.swift in Sources */, 436 | C9D91B2824C625AC00DB0008 /* DiscoverBlock.swift in Sources */, 437 | C999AF7424CE490600EB346A /* TermsAndConditionsBlock.swift in Sources */, 438 | C98A3B2224C4F31F009387D3 /* AppsTabView.swift in Sources */, 439 | C9E7621424CE326D0029264E /* AppMedium1Block.swift in Sources */, 440 | C9D91B3424C6479900DB0008 /* AppLarge3Block.swift in Sources */, 441 | C98A3B2F24C4F8CB009387D3 /* NavigationViewHeaderBlock.swift in Sources */, 442 | C98A3B2624C4F364009387D3 /* SearchTabView.swift in Sources */, 443 | C92112CB24CF927600B74FEE /* DefaultView.swift in Sources */, 444 | C999AF7024CE44E400EB346A /* QuickLinksBlock.swift in Sources */, 445 | C95A19BE24C5FB570055BDA1 /* RecentlyUpdatedAppsList.swift in Sources */, 446 | C999AF7224CE468E00EB346A /* DefaultButton.swift in Sources */, 447 | C9F2565F24CF80AD00549B6C /* SectionHeaderExtendedBlock.swift in Sources */, 448 | C9E7621A24CE42F20029264E /* TopGamesCategoriesBlock.swift in Sources */, 449 | C98A3B2B24C4F490009387D3 /* AppCarouselSmall1Block.swift in Sources */, 450 | C9D91B2C24C643F300DB0008 /* AppSmall2Block.swift in Sources */, 451 | C9D91B2A24C625CC00DB0008 /* SuggestedAppsBlock.swift in Sources */, 452 | C922478324CF8BD40013F293 /* TryButton.swift in Sources */, 453 | C932352224CE18D000D3839F /* SearchBar.swift in Sources */, 454 | C99ED4ED24D30397006A8D71 /* TopAppsCategoriesBlock.swift in Sources */, 455 | C97D65D324CF8C7C00E1640F /* SectionHeaderBlock.swift in Sources */, 456 | C922477F24CF89D10013F293 /* GetButton.swift in Sources */, 457 | C99ED4EF24D305F0006A8D71 /* AppMedium2Block.swift in Sources */, 458 | C95A19BC24C5FB2D0055BDA1 /* SingleLineButton.swift in Sources */, 459 | C9A128E824C5DC88008A54D5 /* AccountView.swift in Sources */, 460 | C92F644024D3214700A5DEB8 /* AppCarouselSmall2Block.swift in Sources */, 461 | C9E7621624CE38C30029264E /* AppCarouselMedium1Block.swift in Sources */, 462 | C922478124CF8B250013F293 /* InAppPurchasesLabel.swift in Sources */, 463 | C9A128ED24C5E377008A54D5 /* DismissButton.swift in Sources */, 464 | C98A3B0A24C4E018009387D3 /* AppStoreApp.swift in Sources */, 465 | C9E7620F24CE29F60029264E /* ItemDetailsLabel.swift in Sources */, 466 | C9A128EA24C5DECC008A54D5 /* AccountButton.swift in Sources */, 467 | ); 468 | runOnlyForDeploymentPostprocessing = 0; 469 | }; 470 | /* End PBXSourcesBuildPhase section */ 471 | 472 | /* Begin XCBuildConfiguration section */ 473 | C98A3B1324C4E019009387D3 /* Debug */ = { 474 | isa = XCBuildConfiguration; 475 | buildSettings = { 476 | ALWAYS_SEARCH_USER_PATHS = NO; 477 | CLANG_ANALYZER_NONNULL = YES; 478 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 479 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 480 | CLANG_CXX_LIBRARY = "libc++"; 481 | CLANG_ENABLE_MODULES = YES; 482 | CLANG_ENABLE_OBJC_ARC = YES; 483 | CLANG_ENABLE_OBJC_WEAK = YES; 484 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 485 | CLANG_WARN_BOOL_CONVERSION = YES; 486 | CLANG_WARN_COMMA = YES; 487 | CLANG_WARN_CONSTANT_CONVERSION = YES; 488 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 489 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 490 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 491 | CLANG_WARN_EMPTY_BODY = YES; 492 | CLANG_WARN_ENUM_CONVERSION = YES; 493 | CLANG_WARN_INFINITE_RECURSION = YES; 494 | CLANG_WARN_INT_CONVERSION = YES; 495 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 496 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 497 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 498 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 499 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 500 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 501 | CLANG_WARN_STRICT_PROTOTYPES = YES; 502 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 503 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 504 | CLANG_WARN_UNREACHABLE_CODE = YES; 505 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 506 | COPY_PHASE_STRIP = NO; 507 | DEBUG_INFORMATION_FORMAT = dwarf; 508 | ENABLE_STRICT_OBJC_MSGSEND = YES; 509 | ENABLE_TESTABILITY = YES; 510 | GCC_C_LANGUAGE_STANDARD = gnu11; 511 | GCC_DYNAMIC_NO_PIC = NO; 512 | GCC_NO_COMMON_BLOCKS = YES; 513 | GCC_OPTIMIZATION_LEVEL = 0; 514 | GCC_PREPROCESSOR_DEFINITIONS = ( 515 | "DEBUG=1", 516 | "$(inherited)", 517 | ); 518 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 519 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 520 | GCC_WARN_UNDECLARED_SELECTOR = YES; 521 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 522 | GCC_WARN_UNUSED_FUNCTION = YES; 523 | GCC_WARN_UNUSED_VARIABLE = YES; 524 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 525 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 526 | MTL_FAST_MATH = YES; 527 | ONLY_ACTIVE_ARCH = YES; 528 | SDKROOT = iphoneos; 529 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 530 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 531 | }; 532 | name = Debug; 533 | }; 534 | C98A3B1424C4E019009387D3 /* Release */ = { 535 | isa = XCBuildConfiguration; 536 | buildSettings = { 537 | ALWAYS_SEARCH_USER_PATHS = NO; 538 | CLANG_ANALYZER_NONNULL = YES; 539 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 540 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 541 | CLANG_CXX_LIBRARY = "libc++"; 542 | CLANG_ENABLE_MODULES = YES; 543 | CLANG_ENABLE_OBJC_ARC = YES; 544 | CLANG_ENABLE_OBJC_WEAK = YES; 545 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 546 | CLANG_WARN_BOOL_CONVERSION = YES; 547 | CLANG_WARN_COMMA = YES; 548 | CLANG_WARN_CONSTANT_CONVERSION = YES; 549 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 550 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 551 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 552 | CLANG_WARN_EMPTY_BODY = YES; 553 | CLANG_WARN_ENUM_CONVERSION = YES; 554 | CLANG_WARN_INFINITE_RECURSION = YES; 555 | CLANG_WARN_INT_CONVERSION = YES; 556 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 557 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 558 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 559 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 560 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 561 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 562 | CLANG_WARN_STRICT_PROTOTYPES = YES; 563 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 564 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 565 | CLANG_WARN_UNREACHABLE_CODE = YES; 566 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 567 | COPY_PHASE_STRIP = NO; 568 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 569 | ENABLE_NS_ASSERTIONS = NO; 570 | ENABLE_STRICT_OBJC_MSGSEND = YES; 571 | GCC_C_LANGUAGE_STANDARD = gnu11; 572 | GCC_NO_COMMON_BLOCKS = YES; 573 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 574 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 575 | GCC_WARN_UNDECLARED_SELECTOR = YES; 576 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 577 | GCC_WARN_UNUSED_FUNCTION = YES; 578 | GCC_WARN_UNUSED_VARIABLE = YES; 579 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 580 | MTL_ENABLE_DEBUG_INFO = NO; 581 | MTL_FAST_MATH = YES; 582 | SDKROOT = iphoneos; 583 | SWIFT_COMPILATION_MODE = wholemodule; 584 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 585 | VALIDATE_PRODUCT = YES; 586 | }; 587 | name = Release; 588 | }; 589 | C98A3B1624C4E019009387D3 /* Debug */ = { 590 | isa = XCBuildConfiguration; 591 | buildSettings = { 592 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 593 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 594 | CODE_SIGN_STYLE = Automatic; 595 | DEVELOPMENT_ASSET_PATHS = "\"AppStoreReplica/Preview Content\""; 596 | DEVELOPMENT_TEAM = ""; 597 | ENABLE_PREVIEWS = YES; 598 | INFOPLIST_FILE = "AppStoreReplica/Supporting files/Info.plist"; 599 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 600 | LD_RUNPATH_SEARCH_PATHS = ( 601 | "$(inherited)", 602 | "@executable_path/Frameworks", 603 | ); 604 | PRODUCT_BUNDLE_IDENTIFIER = com.BEstelrich.AppStoreReplica; 605 | PRODUCT_NAME = "$(TARGET_NAME)"; 606 | SWIFT_VERSION = 5.0; 607 | TARGETED_DEVICE_FAMILY = "1,2"; 608 | }; 609 | name = Debug; 610 | }; 611 | C98A3B1724C4E019009387D3 /* Release */ = { 612 | isa = XCBuildConfiguration; 613 | buildSettings = { 614 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 615 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 616 | CODE_SIGN_STYLE = Automatic; 617 | DEVELOPMENT_ASSET_PATHS = "\"AppStoreReplica/Preview Content\""; 618 | DEVELOPMENT_TEAM = ""; 619 | ENABLE_PREVIEWS = YES; 620 | INFOPLIST_FILE = "AppStoreReplica/Supporting files/Info.plist"; 621 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 622 | LD_RUNPATH_SEARCH_PATHS = ( 623 | "$(inherited)", 624 | "@executable_path/Frameworks", 625 | ); 626 | PRODUCT_BUNDLE_IDENTIFIER = com.BEstelrich.AppStoreReplica; 627 | PRODUCT_NAME = "$(TARGET_NAME)"; 628 | SWIFT_VERSION = 5.0; 629 | TARGETED_DEVICE_FAMILY = "1,2"; 630 | }; 631 | name = Release; 632 | }; 633 | /* End XCBuildConfiguration section */ 634 | 635 | /* Begin XCConfigurationList section */ 636 | C98A3B0124C4E018009387D3 /* Build configuration list for PBXProject "AppStoreReplica" */ = { 637 | isa = XCConfigurationList; 638 | buildConfigurations = ( 639 | C98A3B1324C4E019009387D3 /* Debug */, 640 | C98A3B1424C4E019009387D3 /* Release */, 641 | ); 642 | defaultConfigurationIsVisible = 0; 643 | defaultConfigurationName = Release; 644 | }; 645 | C98A3B1524C4E019009387D3 /* Build configuration list for PBXNativeTarget "AppStoreReplica" */ = { 646 | isa = XCConfigurationList; 647 | buildConfigurations = ( 648 | C98A3B1624C4E019009387D3 /* Debug */, 649 | C98A3B1724C4E019009387D3 /* Release */, 650 | ); 651 | defaultConfigurationIsVisible = 0; 652 | defaultConfigurationName = Release; 653 | }; 654 | /* End XCConfigurationList section */ 655 | }; 656 | rootObject = C98A3AFE24C4E018009387D3 /* Project object */; 657 | } 658 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica.xcodeproj/xcshareddata/xcschemes/AppStoreReplica.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica.xcodeproj/xcuserdata/BES.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 9 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica.xcodeproj/xcuserdata/BES.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | AppStoreReplica.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.19 | AppStore - ContentView.swift | 2 | import SwiftUI 3 | 4 | 5 | struct AppMainView: View { 6 | var body: some View { 7 | NavigationView { 8 | TabView { 9 | TodayTabView() 10 | GamesTabView() 11 | AppsTabView() 12 | ArcadeTabView() 13 | SearchTabView() 14 | } 15 | .navigationTitle("Apps") 16 | } 17 | 18 | } 19 | } 20 | 21 | struct TodayTabView: View { 22 | var body: some View { 23 | ScrollView { 24 | SingleAppView() 25 | HStack { 26 | Text("Popular Apps") 27 | .font(.title) 28 | .bold() 29 | .padding(.leading) 30 | 31 | Spacer() 32 | } 33 | MultipleAppView() 34 | } 35 | .tabItem { 36 | Image(systemName: "note") 37 | Text("Home") 38 | } 39 | .tabItem { 40 | Image(systemName: "note") 41 | Text("Today") 42 | } 43 | } 44 | } 45 | 46 | 47 | struct GamesTabView: View { 48 | var body: some View { 49 | Text("Games view") 50 | .tabItem { 51 | Image(systemName: "keyboard") 52 | Text("Games") 53 | } 54 | } 55 | } 56 | 57 | struct AppsTabView: View { 58 | var body: some View { 59 | Text("Apps view") 60 | .tabItem { 61 | Image(systemName: "square.stack.3d.up.fill") 62 | Text("Apps") 63 | } 64 | } 65 | } 66 | 67 | struct ArcadeTabView: View { 68 | var body: some View { 69 | Text("Arcade view") 70 | .tabItem { 71 | Image(systemName: "gamecontroller.fill") 72 | Text("Arcade") 73 | } 74 | } 75 | } 76 | 77 | struct SearchTabView: View { 78 | var body: some View { 79 | Text("Search view") 80 | .tabItem { 81 | Image(systemName: "magnifyingglass") 82 | Text("Search") 83 | } 84 | } 85 | } 86 | 87 | 88 | 89 | 90 | 91 | struct ContentView_Previews: PreviewProvider { 92 | static var previews: some View { 93 | AppMainView() 94 | } 95 | } 96 | 97 | 98 | struct SingleAppView: View { 99 | var body: some View { 100 | TabView { 101 | ForEach(0 ..< 5) { item in 102 | VStack { 103 | HStack { 104 | VStack(alignment: .leading) { 105 | Text("Some app") 106 | .bold() 107 | Text("Details and stuff") 108 | .foregroundColor(.secondary) 109 | } 110 | Spacer() 111 | } 112 | RoundedRectangle(cornerRadius: 8, style: .continuous) 113 | } 114 | } 115 | .padding() 116 | } 117 | .frame(width: UIScreen.main.bounds.width, height: 270) 118 | .tabViewStyle(PageTabViewStyle()) 119 | } 120 | } 121 | 122 | struct MultipleAppView: View { 123 | var body: some View { 124 | TabView { 125 | ForEach(0 ..< 5) { item in 126 | VStack { 127 | AppView() 128 | AppView() 129 | AppView() 130 | } 131 | } 132 | .padding() 133 | } 134 | .frame(width: UIScreen.main.bounds.width, height: 250) 135 | .tabViewStyle(PageTabViewStyle()) 136 | } 137 | } 138 | 139 | 140 | struct AppView: View { 141 | var body: some View { 142 | HStack { 143 | RoundedRectangle(cornerRadius: 8, style: .continuous) 144 | .frame(width: 50, height: 50) 145 | VStack(alignment: .leading) { 146 | Text("Some app") 147 | .bold() 148 | Text("Details and stuff") 149 | .foregroundColor(.secondary) 150 | } 151 | Spacer() 152 | 153 | Image(systemName: "icloud.and.arrow.down") 154 | .font(.headline) 155 | } 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Extensions/Date+Ext.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.29 | AppStoreReplica - Date+Ext.swift | 2 | import Foundation 3 | 4 | 5 | extension Date { 6 | 7 | func toFullDateFormat() -> String { 8 | let dateFormatter = DateFormatter() 9 | dateFormatter.dateFormat = "EEEE, MMMM dd" 10 | return dateFormatter.string(from: self) 11 | } 12 | 13 | 14 | func toWeekDayFormat() -> String { 15 | let dateFormatter = DateFormatter() 16 | dateFormatter.dateStyle = .medium 17 | dateFormatter.doesRelativeDateFormatting = true 18 | return dateFormatter.string(from: self) 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomEstelrich/AppStoreReplicaApp/3d7f4413755e1b6213c1bfbddf280ab915e0c86f/AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomEstelrich/AppStoreReplicaApp/3d7f4413755e1b6213c1bfbddf280ab915e0c86f/AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-20.png -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomEstelrich/AppStoreReplicaApp/3d7f4413755e1b6213c1bfbddf280ab915e0c86f/AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-20@2x.png -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomEstelrich/AppStoreReplicaApp/3d7f4413755e1b6213c1bfbddf280ab915e0c86f/AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-20@3x.png -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomEstelrich/AppStoreReplicaApp/3d7f4413755e1b6213c1bfbddf280ab915e0c86f/AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-29.png -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomEstelrich/AppStoreReplicaApp/3d7f4413755e1b6213c1bfbddf280ab915e0c86f/AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-29@2x.png -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomEstelrich/AppStoreReplicaApp/3d7f4413755e1b6213c1bfbddf280ab915e0c86f/AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-29@3x.png -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomEstelrich/AppStoreReplicaApp/3d7f4413755e1b6213c1bfbddf280ab915e0c86f/AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-40.png -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomEstelrich/AppStoreReplicaApp/3d7f4413755e1b6213c1bfbddf280ab915e0c86f/AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-40@2x.png -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomEstelrich/AppStoreReplicaApp/3d7f4413755e1b6213c1bfbddf280ab915e0c86f/AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-40@3x.png -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomEstelrich/AppStoreReplicaApp/3d7f4413755e1b6213c1bfbddf280ab915e0c86f/AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-60@2x.png -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomEstelrich/AppStoreReplicaApp/3d7f4413755e1b6213c1bfbddf280ab915e0c86f/AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-60@3x.png -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomEstelrich/AppStoreReplicaApp/3d7f4413755e1b6213c1bfbddf280ab915e0c86f/AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-76.png -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomEstelrich/AppStoreReplicaApp/3d7f4413755e1b6213c1bfbddf280ab915e0c86f/AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-76@2x.png -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomEstelrich/AppStoreReplicaApp/3d7f4413755e1b6213c1bfbddf280ab915e0c86f/AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-83.5@2x.png -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "AppIcon-20@2x.png", 5 | "idiom" : "iphone", 6 | "scale" : "2x", 7 | "size" : "20x20" 8 | }, 9 | { 10 | "filename" : "AppIcon-20@3x.png", 11 | "idiom" : "iphone", 12 | "scale" : "3x", 13 | "size" : "20x20" 14 | }, 15 | { 16 | "filename" : "AppIcon-29@2x.png", 17 | "idiom" : "iphone", 18 | "scale" : "2x", 19 | "size" : "29x29" 20 | }, 21 | { 22 | "filename" : "AppIcon-29@3x.png", 23 | "idiom" : "iphone", 24 | "scale" : "3x", 25 | "size" : "29x29" 26 | }, 27 | { 28 | "filename" : "AppIcon-40@2x.png", 29 | "idiom" : "iphone", 30 | "scale" : "2x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "filename" : "AppIcon-40@3x.png", 35 | "idiom" : "iphone", 36 | "scale" : "3x", 37 | "size" : "40x40" 38 | }, 39 | { 40 | "filename" : "AppIcon-60@2x.png", 41 | "idiom" : "iphone", 42 | "scale" : "2x", 43 | "size" : "60x60" 44 | }, 45 | { 46 | "filename" : "AppIcon-60@3x.png", 47 | "idiom" : "iphone", 48 | "scale" : "3x", 49 | "size" : "60x60" 50 | }, 51 | { 52 | "filename" : "AppIcon-20.png", 53 | "idiom" : "ipad", 54 | "scale" : "1x", 55 | "size" : "20x20" 56 | }, 57 | { 58 | "filename" : "AppIcon-20@2x.png", 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "20x20" 62 | }, 63 | { 64 | "filename" : "AppIcon-29.png", 65 | "idiom" : "ipad", 66 | "scale" : "1x", 67 | "size" : "29x29" 68 | }, 69 | { 70 | "filename" : "AppIcon-29@2x.png", 71 | "idiom" : "ipad", 72 | "scale" : "2x", 73 | "size" : "29x29" 74 | }, 75 | { 76 | "filename" : "AppIcon-40.png", 77 | "idiom" : "ipad", 78 | "scale" : "1x", 79 | "size" : "40x40" 80 | }, 81 | { 82 | "filename" : "AppIcon-40@2x.png", 83 | "idiom" : "ipad", 84 | "scale" : "2x", 85 | "size" : "40x40" 86 | }, 87 | { 88 | "filename" : "AppIcon-76.png", 89 | "idiom" : "ipad", 90 | "scale" : "1x", 91 | "size" : "76x76" 92 | }, 93 | { 94 | "filename" : "AppIcon-76@2x.png", 95 | "idiom" : "ipad", 96 | "scale" : "2x", 97 | "size" : "76x76" 98 | }, 99 | { 100 | "filename" : "AppIcon-83.5@2x.png", 101 | "idiom" : "ipad", 102 | "scale" : "2x", 103 | "size" : "83.5x83.5" 104 | }, 105 | { 106 | "filename" : "AppIcon-1024.png", 107 | "idiom" : "ios-marketing", 108 | "scale" : "1x", 109 | "size" : "1024x1024" 110 | } 111 | ], 112 | "info" : { 113 | "author" : "xcode", 114 | "version" : 1 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Resources/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Supporting files/AppStoreApp.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.19 | AppStore - AppStoreApp.swift | 2 | import SwiftUI 3 | 4 | 5 | @main 6 | struct AppStoreApp: App { 7 | 8 | var body: some Scene { 9 | WindowGroup { 10 | AppMainView() 11 | } 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Supporting files/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | AppStoreReplica 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UIApplicationSceneManifest 26 | 27 | UIApplicationSupportsMultipleScenes 28 | 29 | 30 | UIApplicationSupportsIndirectInputEvents 31 | 32 | UILaunchScreen 33 | 34 | UIRequiredDeviceCapabilities 35 | 36 | armv7 37 | 38 | UISupportedInterfaceOrientations 39 | 40 | UIInterfaceOrientationPortrait 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UISupportedInterfaceOrientations~ipad 45 | 46 | UIInterfaceOrientationPortrait 47 | UIInterfaceOrientationPortraitUpsideDown 48 | UIInterfaceOrientationLandscapeLeft 49 | UIInterfaceOrientationLandscapeRight 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Blocks/Apps/AppLarge1Block.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.20 | AppStoreReplica - AppLarge1Block.swift | 2 | import SwiftUI 3 | 4 | 5 | struct AppLarge1Block: View { 6 | var body: some View { 7 | ZStack(alignment: .leading) { 8 | VStack(alignment: .leading) { 9 | Text("CATEGORY") 10 | .font(.headline) 11 | .foregroundColor(.secondary) 12 | 13 | Text("App headline") 14 | .font(.title) 15 | .foregroundColor(.white) 16 | .fontWeight(.bold) 17 | 18 | Spacer() 19 | 20 | Text("Description.") 21 | .foregroundColor(.white) 22 | } 23 | .padding() 24 | .frame(maxWidth: .infinity, alignment: .leading) 25 | } 26 | .frame(width: UIScreen.main.bounds.width - 32, height: UIScreen.main.bounds.width * 1.1) 27 | .background(Color(UIColor.systemGray2)) 28 | .clipShape(RoundedRectangle(cornerRadius: 20)) 29 | .padding(.vertical, 8) 30 | } 31 | } 32 | 33 | 34 | struct AppLarge1Block_Previews: PreviewProvider { 35 | static var previews: some View { 36 | AppLarge1Block() 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Blocks/Apps/AppLarge2Block.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.20 | AppStoreReplica - AppLarge2Block.swift | 2 | import SwiftUI 3 | 4 | 5 | struct AppLarge2Block: View { 6 | var body: some View { 7 | VStack(alignment: .leading) { 8 | Spacer() 9 | 10 | Text("Headline") 11 | .font(.system(size: 40)) 12 | .fontWeight(.bold) 13 | .foregroundColor(.white) 14 | .padding(.horizontal) 15 | 16 | HStack { 17 | RoundedRectangle(cornerRadius: 12, style: .continuous) 18 | .foregroundColor(Color.gray) 19 | .frame(width: 50, height: 50) 20 | 21 | VStack(alignment: .leading) { 22 | Text("App name") 23 | .bold() 24 | 25 | Text("Details") 26 | .font(.subheadline) 27 | } 28 | .foregroundColor(.white) 29 | 30 | Spacer() 31 | 32 | VStack { 33 | GetButton() 34 | .padding(.bottom, 8) 35 | 36 | InAppPurchasesLabel() 37 | .foregroundColor(.white) 38 | } 39 | } 40 | .padding(20) 41 | .background(Color.secondary) 42 | } 43 | .frame(width: UIScreen.main.bounds.width - 32, height: UIScreen.main.bounds.width * 1.1) 44 | .background(Color(UIColor.systemGray2)) 45 | .clipShape(RoundedRectangle(cornerRadius: 20)) 46 | .padding(.vertical, 8) 47 | } 48 | } 49 | 50 | 51 | struct AppLarge2Block_Previews: PreviewProvider { 52 | static var previews: some View { 53 | AppLarge2Block() 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Blocks/Apps/AppLarge3Block.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.20 | AppStoreReplica - AppLarge3Block.swift | 2 | import SwiftUI 3 | 4 | 5 | struct AppLarge3Block: View { 6 | var body: some View { 7 | VStack(alignment: .leading) { 8 | Text("CATEGORY") 9 | .font(.headline) 10 | .foregroundColor(.white) 11 | 12 | 13 | Text("Headline") 14 | .font(.title) 15 | .fontWeight(.bold) 16 | .foregroundColor(.white) 17 | .frame(height: 75) 18 | 19 | Spacer() 20 | 21 | VStack { 22 | AppSmall2Block() 23 | Divider() 24 | AppSmall2Block() 25 | Divider() 26 | AppSmall2Block() 27 | Divider() 28 | AppSmall2Block() 29 | } 30 | } 31 | .padding() 32 | .frame(width: UIScreen.main.bounds.width - 32, height: UIScreen.main.bounds.width * 1.1) 33 | .background(Color(UIColor.systemGray2)) 34 | .clipShape(RoundedRectangle(cornerRadius: 20)) 35 | } 36 | } 37 | 38 | 39 | struct AppLarge3Block_Previews: PreviewProvider { 40 | static var previews: some View { 41 | AppLarge3Block() 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Blocks/Apps/AppMedium1Block.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.26 | AppStoreReplica - AppMedium1Block.swift | 2 | import SwiftUI 3 | 4 | 5 | struct AppMedium1Block: View { 6 | var body: some View { 7 | VStack(alignment: .center) { 8 | RoundedRectangle(cornerRadius: 32, style: .continuous) 9 | .foregroundColor(Color.gray) 10 | .aspectRatio(CGSize(width: 1, height: 1), contentMode: .fit) 11 | 12 | ItemTitleLabel(text: "App title") 13 | .lineLimit(1) 14 | .frame(width: 160) 15 | 16 | ItemDetailsLabel(text: "Description") 17 | .lineLimit(1) 18 | .frame(width: 160) 19 | } 20 | } 21 | } 22 | 23 | struct AppMedium1Block_Previews: PreviewProvider { 24 | static var previews: some View { 25 | AppMedium1Block() 26 | } 27 | } 28 | 29 | 30 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Blocks/Apps/AppMedium2Block.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.30 | AppStoreReplica - AppMedium2Block.swift | 2 | import SwiftUI 3 | 4 | 5 | struct AppMedium2Block: View { 6 | var body: some View { 7 | HStack(alignment: .top) { 8 | ZStack(alignment: .center) { 9 | ZStack { 10 | RoundedRectangle(cornerRadius: 16, style: .continuous) 11 | .foregroundColor(Color(UIColor.systemGray2)) 12 | 13 | RoundedRectangle(cornerRadius: 10, style: .continuous) 14 | .foregroundColor(Color(UIColor.systemGray4)) 15 | .padding() 16 | .mask( 17 | Circle() 18 | .size(width: 170, height: 170) 19 | .offset(x: -30, y: 10) 20 | ) 21 | 22 | Text("+") 23 | .font(.system(size: 40)) 24 | .fontWeight(.bold) 25 | .foregroundColor(Color(UIColor.systemGray4)) 26 | .offset(x: 55, y: -55) 27 | } 28 | .frame(width: 150, height: 150) 29 | 30 | RoundedRectangle(cornerRadius: 10) 31 | .foregroundColor(Color(UIColor.gray)) 32 | .frame(width: 50, height: 50) 33 | .offset(x: -60, y: 60) 34 | } 35 | 36 | VStack { 37 | ItemTitleLabel(text: "App title") 38 | .lineLimit(1) 39 | 40 | ItemDetailsLabel(text: "Description") 41 | .lineLimit(1) 42 | 43 | Spacer() 44 | 45 | GetButton(title: "$3.99") 46 | } 47 | 48 | .frame(width: 200, height: 150, alignment: .leading) 49 | } 50 | } 51 | } 52 | 53 | 54 | struct AppMedium2Block_Previews: PreviewProvider { 55 | static var previews: some View { 56 | AppMedium2Block() 57 | } 58 | } 59 | 60 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Blocks/Apps/AppSmall1Block.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.19 | AppStore - AppSmall1Block.swift | 2 | import SwiftUI 3 | 4 | 5 | struct AppSmall1Block: View { 6 | var body: some View { 7 | HStack { 8 | RoundedRectangle(cornerRadius: 12, style: .continuous) 9 | .foregroundColor(Color.gray) 10 | .frame(width: 50, height: 50) 11 | 12 | VStack(alignment: .leading) { 13 | Text("App title") 14 | .bold() 15 | 16 | Text("Description") 17 | .font(.subheadline) 18 | .foregroundColor(.secondary) 19 | } 20 | 21 | Spacer() 22 | 23 | VStack { 24 | GetButton() 25 | .padding(.bottom, 8) 26 | 27 | InAppPurchasesLabel() 28 | } 29 | } 30 | } 31 | } 32 | 33 | 34 | struct AppSmall1Block_Previews: PreviewProvider { 35 | static var previews: some View { 36 | AppSmall1Block() 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Blocks/Apps/AppSmall2Block.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.20 | AppStoreReplica - AppSmall2Block.swift | 2 | import SwiftUI 3 | 4 | 5 | struct AppSmall2Block: View { 6 | var body: some View { 7 | HStack { 8 | RoundedRectangle(cornerRadius: 12, style: .continuous) 9 | .foregroundColor(Color.gray) 10 | .frame(width: 50, height: 50) 11 | 12 | VStack(alignment: .leading) { 13 | Text("App name") 14 | .bold() 15 | 16 | Text("Description") 17 | .font(.subheadline) 18 | } 19 | .foregroundColor(.white) 20 | 21 | Spacer() 22 | 23 | TryButton() 24 | } 25 | } 26 | } 27 | 28 | 29 | struct AppSmall2Block_Previews: PreviewProvider { 30 | static var previews: some View { 31 | AppSmall2Block() 32 | .preferredColorScheme(.dark) 33 | .previewLayout(.sizeThatFits) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Blocks/Carousels/AppCarouselExtraLargeBlock.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.29 | AppStoreReplica - AppCarrouselExtraLargeBlock.swift | 2 | import SwiftUI 3 | 4 | 5 | struct AppCarouselExtraLargeBlock: View { 6 | var body: some View { 7 | VStack { 8 | VStack { 9 | AppLarge1Block() 10 | AppLarge2Block() 11 | AppLarge2Block() 12 | AppLarge3Block() 13 | } 14 | } 15 | } 16 | } 17 | 18 | 19 | struct AppCarrouselExtraLargeBlock_Previews: PreviewProvider { 20 | static var previews: some View { 21 | AppCarouselExtraLargeBlock() 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Blocks/Carousels/AppCarouselLargeBlock.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.19 | AppStore - AppCarouselLargeBlock.swift | 2 | import SwiftUI 3 | 4 | 5 | struct AppCarouselLargeBlock: View { 6 | var body: some View { 7 | TabView { 8 | ForEach(0 ..< 5) { item in 9 | VStack { 10 | Divider() 11 | VStack(alignment: .leading) { 12 | Text("UPDATE") 13 | .bold() 14 | .foregroundColor(.blue) 15 | .font(.footnote) 16 | 17 | Text("App title") 18 | .font(.title3) 19 | 20 | Text("Description") 21 | .foregroundColor(.secondary) 22 | } 23 | .frame(maxWidth: .infinity, alignment: .leading) 24 | RoundedRectangle(cornerRadius: 12, style: .continuous) 25 | .foregroundColor(Color.gray) 26 | } 27 | } 28 | .padding(.horizontal) 29 | } 30 | .frame(width: UIScreen.main.bounds.width, height: 300) 31 | .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never)) 32 | .padding(.bottom, 24) 33 | } 34 | } 35 | 36 | 37 | struct AppCarouselLargeBlock_Previews: PreviewProvider { 38 | static var previews: some View { 39 | AppCarouselLargeBlock() 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Blocks/Carousels/AppCarouselMedium1Block.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.26 | AppStoreReplica - AppCarouselMedium1Block.swift | 2 | import SwiftUI 3 | 4 | 5 | struct AppCarouselMedium1Block: View { 6 | var title: String = "Title" 7 | let cellsNumber: Int 8 | 9 | var body: some View { 10 | VStack { 11 | SectionHeaderExtendedBlock(title: title) 12 | .padding(.horizontal, 16) 13 | 14 | ScrollView([.horizontal], showsIndicators: false) { 15 | HStack { 16 | ForEach(Range(0...cellsNumber)) { _ in 17 | AppMedium1Block() 18 | } 19 | } 20 | } 21 | } 22 | .frame(height: 250) 23 | .padding(.bottom, 24) 24 | } 25 | } 26 | 27 | 28 | struct AppCarouselMedium1Block_Previews: PreviewProvider { 29 | static var previews: some View { 30 | AppCarouselMedium1Block(cellsNumber: 5) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Blocks/Carousels/AppCarouselMedium2Block.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.30 | AppStoreReplica - AppCarouselMedium2Block.swift | 2 | import SwiftUI 3 | 4 | 5 | struct AppCarouselMedium2Block: View { 6 | var title: String = "Title" 7 | let cellsNumber: Int 8 | 9 | var body: some View { 10 | VStack { 11 | SectionHeaderExtendedBlock(title: title) 12 | .padding(.horizontal, 16) 13 | 14 | ScrollView([.horizontal], showsIndicators: false) { 15 | HStack { 16 | ForEach(Range(0...cellsNumber)) { _ in 17 | AppMedium2Block() 18 | .padding() 19 | } 20 | } 21 | } 22 | } 23 | .padding(.bottom, 24) 24 | } 25 | } 26 | 27 | struct AppCarouselMedium2Block_Previews: PreviewProvider { 28 | static var previews: some View { 29 | AppCarouselMedium2Block(cellsNumber: 5) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Blocks/Carousels/AppCarouselSmall1Block.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.19 | AppStore - AppCarouselSmall1Block.swift | 2 | import SwiftUI 3 | 4 | 5 | struct AppCarouselSmall1Block: View { 6 | var title: String = "Title" 7 | 8 | var body: some View { 9 | VStack { 10 | SectionHeaderExtendedBlock(title: title) 11 | .padding() 12 | 13 | TabView { 14 | ForEach(0 ..< 5) { item in 15 | VStack { 16 | AppSmall1Block() 17 | AppSmall1Block() 18 | AppSmall1Block() 19 | } 20 | } 21 | .padding(.horizontal) 22 | } 23 | .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never)) 24 | .tabViewStyle(PageTabViewStyle()) 25 | } 26 | .frame(width: UIScreen.main.bounds.width, height: 250) 27 | .padding(.bottom) 28 | } 29 | 30 | } 31 | 32 | 33 | struct AppCarouselSmall1Block_Previews: PreviewProvider { 34 | static var previews: some View { 35 | AppCarouselSmall1Block() 36 | } 37 | } 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Blocks/Carousels/AppCarouselSmall2Block.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.30 | AppStoreReplica - AppCarouselSmall2Block.swift | 2 | import SwiftUI 3 | 4 | 5 | struct AppCarouselSmall2Block: View { 6 | 7 | var body: some View { 8 | VStack(spacing: 20) { 9 | VStack { 10 | HStack { 11 | AppShape() 12 | AppShape() 13 | AppShape() 14 | AppShape() 15 | AppShape() 16 | } 17 | 18 | HStack { 19 | AppShape() 20 | AppShape() 21 | AppShape() 22 | AppShape() 23 | AppShape() 24 | AppShape() 25 | } 26 | } 27 | 28 | Text(" Arcade") 29 | 30 | DefaultButton(title: "See all games") 31 | .padding(.horizontal, 64) 32 | 33 | } 34 | .frame(width: UIScreen.main.bounds.width, height: 250) 35 | .padding(.bottom) 36 | } 37 | 38 | } 39 | 40 | struct AppCarouselSmall2Block_Previews: PreviewProvider { 41 | static var previews: some View { 42 | AppCarouselSmall2Block() 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Blocks/Headers/ArcadeHeader.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.30 | AppStoreReplica - ArcadeHeader.swift | 2 | import SwiftUI 3 | 4 | struct ArcadeHeader: View { 5 | @State var isAccountViewPresented = false 6 | 7 | var body: some View { 8 | VStack(spacing: 20) { 9 | AccountButton(isAccountViewPresented: $isAccountViewPresented) 10 | .padding(.top, 64) 11 | .frame(maxWidth: .infinity, alignment: .trailing) 12 | 13 | Spacer() 14 | 15 | Text(" Arcade") 16 | 17 | Text(""" 18 | Unlimited access to 19 | 100+ ad-free games. 20 | No in-app purchases. 21 | """) 22 | .font(.title) 23 | .fontWeight(.bold) 24 | 25 | DefaultButton(title: "Try It Free") 26 | 27 | Text("One month free, then $4.99/month") 28 | .font(.caption) 29 | .foregroundColor(.secondary) 30 | .padding(.bottom, 32) 31 | } 32 | .padding(.horizontal, 32) 33 | .background(Color(UIColor.systemGray2)) 34 | .frame(height: UIScreen.main.bounds.height * 0.75) 35 | 36 | } 37 | } 38 | 39 | 40 | struct ArcadeHeader_Previews: PreviewProvider { 41 | static var previews: some View { 42 | ArcadeHeader() 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Blocks/Headers/NavigationViewHeaderBlock.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.19 | AppStore - NavigationViewHeaderBlock.swift | 2 | import SwiftUI 3 | 4 | 5 | struct NavigationViewHeaderBlock: View { 6 | @State var isAccountViewPresented = false 7 | let date: Date 8 | 9 | var body: some View { 10 | VStack { 11 | Text(date.toFullDateFormat()) 12 | .font(.subheadline) 13 | .frame(maxWidth: .infinity, alignment: .leading) 14 | .padding(.leading) 15 | .foregroundColor(.secondary) 16 | 17 | HStack { 18 | Text(date.toWeekDayFormat()) 19 | .font(.title) 20 | .bold() 21 | .padding(.leading) 22 | 23 | Spacer() 24 | } 25 | .frame(maxWidth: .infinity, alignment: .leading) 26 | } 27 | .padding(.top, 32) 28 | } 29 | } 30 | 31 | 32 | struct NavigationViewHeaderBlock_Previews: PreviewProvider { 33 | static var previews: some View { 34 | NavigationViewHeaderBlock(date: Date()) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Blocks/Headers/NavigationViewHeaderWithImageBlock.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.29 | AppStoreReplica - NavigationViewHeaderWithImageBlock.swift | 2 | import SwiftUI 3 | 4 | 5 | struct NavigationViewHeaderWithImageBlock: View { 6 | @State var isAccountViewPresented = false 7 | let date: Date 8 | 9 | var body: some View { 10 | VStack { 11 | Text(date.toFullDateFormat()) 12 | .font(.subheadline) 13 | .frame(maxWidth: .infinity, alignment: .leading) 14 | .padding(.leading) 15 | .foregroundColor(.secondary) 16 | 17 | HStack { 18 | Text(date.toWeekDayFormat()) 19 | .font(.title) 20 | .bold() 21 | .padding(.leading) 22 | 23 | Spacer() 24 | 25 | AccountButton(isAccountViewPresented: $isAccountViewPresented) 26 | .padding(.trailing) 27 | } 28 | .frame(maxWidth: .infinity, alignment: .leading) 29 | } 30 | .padding(.top, 32) 31 | } 32 | } 33 | 34 | 35 | struct NavigationViewHeaderWithImageBlock_Previews: PreviewProvider { 36 | static var previews: some View { 37 | NavigationViewHeaderWithImageBlock(date: Date()) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Blocks/Headers/SectionHeaderBlock.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.27 | AppStoreReplica - SectionHeaderBlock.swift | 2 | import SwiftUI 3 | 4 | 5 | struct SectionHeaderBlock: View { 6 | var title: String = "Title" 7 | 8 | var body: some View { 9 | VStack(alignment: .leading) { 10 | Divider() 11 | HStack { 12 | Text(title) 13 | .font(.title3) 14 | .bold() 15 | } 16 | } 17 | } 18 | } 19 | 20 | 21 | struct SectionHeaderBlock_Previews: PreviewProvider { 22 | static var previews: some View { 23 | SectionHeaderBlock() 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Blocks/Headers/SectionHeaderExtendedBlock.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.27 | AppStoreReplica - SectionHeaderExtendedBlock.swift | 2 | import SwiftUI 3 | 4 | 5 | struct SectionHeaderExtendedBlock: View { 6 | var title: String = "Title" 7 | 8 | var body: some View { 9 | VStack { 10 | Divider() 11 | 12 | HStack { 13 | Text(title) 14 | .font(.title3) 15 | .bold() 16 | 17 | Spacer() 18 | 19 | Button("See All") {} 20 | .font(.subheadline) 21 | } 22 | } 23 | } 24 | } 25 | 26 | struct SectionHeaderExtendedBlock_Previews: PreviewProvider { 27 | static var previews: some View { 28 | SectionHeaderExtendedBlock() 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Blocks/Sections/DiscoverBlock.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.20 | AppStoreReplica - DiscoverBlock.swift | 2 | import SwiftUI 3 | 4 | 5 | struct DiscoverBlock: View { 6 | var body: some View { 7 | VStack(alignment: .leading) { 8 | Text("Discover") 9 | .font(.title3) 10 | .bold() 11 | 12 | Divider() 13 | 14 | Group { 15 | SingleLineButton(title: "alarm clock") 16 | Divider() 17 | SingleLineButton(title: "reverse video") 18 | Divider() 19 | SingleLineButton(title: "video editor") 20 | Divider() 21 | SingleLineButton(title: "car games") 22 | } 23 | } 24 | .frame(maxWidth: .infinity, alignment: .leading) 25 | .padding() 26 | } 27 | } 28 | 29 | 30 | struct DiscoverBlock_Previews: PreviewProvider { 31 | static var previews: some View { 32 | DiscoverBlock() 33 | } 34 | } 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Blocks/Sections/QuickLinksBlock.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.26 | AppStoreReplica - QuickLinksBlock.swift | 2 | import SwiftUI 3 | 4 | 5 | struct QuickLinksBlock: View { 6 | var body: some View { 7 | VStack(alignment: .leading) { 8 | SectionHeaderBlock(title: "Quick Links") 9 | .padding(.bottom, 24) 10 | 11 | Group { 12 | SingleLineButton(title: "Try Apple Arcade") 13 | Divider() 14 | SingleLineButton(title: "Games in French") 15 | Divider() 16 | SingleLineButton(title: "About In-App Purchases") 17 | Divider() 18 | SingleLineButton(title: "Parents' Guide to the App Store") 19 | Divider() 20 | SingleLineButton(title: "About Personalization") 21 | } 22 | 23 | VStack(spacing: 10) { 24 | DefaultButton(title: "Redeem") 25 | DefaultButton(title: "Send Gift") 26 | DefaultButton(title: "Add Funds to Apple ID") 27 | } 28 | .padding(.top, 64) 29 | } 30 | .frame(maxWidth: .infinity, alignment: .leading) 31 | .padding() 32 | } 33 | } 34 | 35 | 36 | struct QuickLinksBlock_Previews: PreviewProvider { 37 | static var previews: some View { 38 | QuickLinksBlock() 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Blocks/Sections/SuggestedAppsBlock.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.20 | AppStoreReplica - SuggestedAppsBlock.swift | 2 | import SwiftUI 3 | 4 | 5 | struct SuggestedAppsBlock: View { 6 | var body: some View { 7 | VStack(alignment: .leading) { 8 | Text("Suggested") 9 | .font(.title3) 10 | .bold() 11 | 12 | ForEach(Range(0...5)) {_ in 13 | Divider() 14 | AppSmall1Block() 15 | .padding(.vertical, 10) 16 | .frame(height: 60) 17 | } 18 | } 19 | .padding(20) 20 | } 21 | } 22 | 23 | 24 | struct SuggestedAppsBlock_Previews: PreviewProvider { 25 | static var previews: some View { 26 | SuggestedAppsBlock() 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Blocks/Sections/TermsAndConditionsBlock.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.26 | AppStoreReplica - TermsAndConditionsBlock.swift | 2 | import SwiftUI 3 | 4 | 5 | struct TermsAndConditionsBlock: View { 6 | var body: some View { 7 | VStack(alignment: .leading) { 8 | Divider() 9 | .padding(.bottom, 8) 10 | HStack { 11 | ItemDetailsLabel(text: "Terms & Conditions") 12 | Image(systemName: "chevron.right") 13 | .foregroundColor(.secondary) 14 | .font(.caption) 15 | } 16 | } 17 | .padding() 18 | } 19 | } 20 | 21 | 22 | struct TermsAndConditionsBlock_Previews: PreviewProvider { 23 | static var previews: some View { 24 | TermsAndConditionsBlock() 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Blocks/Sections/TopAppsCategoriesBlock.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.30 | AppStoreReplica - TopAppsCategoriesBlock.swift | 2 | import SwiftUI 3 | 4 | 5 | struct TopAppsCategoriesBlock: View { 6 | var body: some View { 7 | VStack { 8 | SectionHeaderExtendedBlock(title: "Top Categories") 9 | .padding(.bottom, 24) 10 | 11 | VStack { 12 | SingleLineIconAndButtonView(emojiImage: "🇫🇷", buttonTitle: "Apps in French") 13 | 14 | Group { 15 | Divider() 16 | SingleLineIconAndButtonView(emojiImage: "🍿", buttonTitle: "Entertainment") 17 | } 18 | 19 | Group { 20 | Divider() 21 | SingleLineIconAndButtonView(emojiImage: "🎈", buttonTitle: "Kids") 22 | } 23 | 24 | Group { 25 | Divider() 26 | SingleLineIconAndButtonView(emojiImage: "🚲", buttonTitle: "Health & Fitness") 27 | } 28 | 29 | Group { 30 | Divider() 31 | SingleLineIconAndButtonView(emojiImage: "👨‍🏫", buttonTitle: "Education") 32 | } 33 | 34 | Group { 35 | Divider() 36 | SingleLineIconAndButtonView(emojiImage: "📅", buttonTitle: "Productivity") 37 | } 38 | } 39 | } 40 | .frame(maxWidth: .infinity, alignment: .leading) 41 | .padding(.horizontal) 42 | } 43 | } 44 | 45 | 46 | struct TopAppsCategoriesBlock_Previews: PreviewProvider { 47 | static var previews: some View { 48 | TopAppsCategoriesBlock() 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Blocks/Sections/TopGamesCategoriesBlock.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.26 | AppStoreReplica - TopGamesCategoriesBlock.swift | 2 | import SwiftUI 3 | 4 | 5 | struct TopGamesCategoriesBlock: View { 6 | var body: some View { 7 | VStack { 8 | SectionHeaderExtendedBlock(title: "Top Categories") 9 | .padding(.bottom, 24) 10 | 11 | VStack { 12 | SingleLineIconAndButtonView(emojiImage: "🇫🇷", buttonTitle: "Games in French") 13 | 14 | Group { 15 | Divider() 16 | SingleLineIconAndButtonView(emojiImage: "⚔️", buttonTitle: "Action") 17 | } 18 | 19 | Group { 20 | Divider() 21 | SingleLineIconAndButtonView(emojiImage: "🚀", buttonTitle: "Casual") 22 | } 23 | 24 | Group { 25 | Divider() 26 | SingleLineIconAndButtonView(emojiImage: "👨‍👩‍👦", buttonTitle: "Family") 27 | } 28 | 29 | Group { 30 | Divider() 31 | SingleLineIconAndButtonView(emojiImage: "🎈", buttonTitle: "Kids") 32 | } 33 | 34 | Group { 35 | Divider() 36 | SingleLineIconAndButtonView(emojiImage: "🧩", buttonTitle: "Puzzle") 37 | } 38 | } 39 | } 40 | .frame(maxWidth: .infinity, alignment: .leading) 41 | .padding(.horizontal) 42 | } 43 | 44 | } 45 | 46 | 47 | struct TopGamesCategoriesBlock_Previews: PreviewProvider { 48 | static var previews: some View { 49 | TopGamesCategoriesBlock() 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Elements/Buttons/AccountButton.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.20 | AppStoreReplica - AccountButton.swift | 2 | import SwiftUI 3 | 4 | 5 | struct AccountButton: View { 6 | @Binding var isAccountViewPresented: Bool 7 | 8 | var body: some View { 9 | Button(action: { 10 | isAccountViewPresented = true 11 | }) { 12 | Image(systemName: "person.circle.fill") 13 | .foregroundColor(.secondary) 14 | .font(.title) 15 | .clipShape(Circle()) 16 | } 17 | .sheet(isPresented: self.$isAccountViewPresented) { 18 | AccountView() 19 | } 20 | } 21 | } 22 | 23 | 24 | struct AccountButton_Previews: PreviewProvider { 25 | static var previews: some View { 26 | AccountButton(isAccountViewPresented: .constant(false)) 27 | .previewLayout(.sizeThatFits) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Elements/Buttons/DefaultButton.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.26 | AppStoreReplica - DefaultButton.swift | 2 | import SwiftUI 3 | 4 | 5 | struct DefaultButton: View { 6 | @Environment (\.colorScheme) var colorScheme:ColorScheme 7 | @State var isPresented = false 8 | let title: String 9 | 10 | var body: some View { 11 | Button(action: { 12 | isPresented = true 13 | }) { 14 | Text(title) 15 | .fontWeight(.semibold) 16 | .frame(maxWidth: .infinity) 17 | .frame(height: 44) 18 | .foregroundColor(colorScheme == .light ? .blue : .white) 19 | .background(Color(UIColor.systemGray6)) 20 | .cornerRadius(10) 21 | } 22 | .sheet(isPresented: self.$isPresented) { 23 | DefaultView(title: title) 24 | } 25 | } 26 | } 27 | 28 | 29 | struct DefaultButtonView_Previews: PreviewProvider { 30 | static var previews: some View { 31 | DefaultButton(title: "Title") 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Elements/Buttons/DismissButton.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.20 | AppStoreReplica - DismmissButton.swift | 2 | import SwiftUI 3 | 4 | 5 | struct DismissButton: View { 6 | var title: String 7 | @Environment(\.presentationMode) var presentationMode:Binding 8 | 9 | var body: some View { 10 | Button(title) { 11 | self.presentationMode.wrappedValue.dismiss() 12 | } 13 | } 14 | } 15 | 16 | 17 | struct DismmissButton_Previews: PreviewProvider { 18 | static var previews: some View { 19 | DismissButton(title: "Done") 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Elements/Buttons/GetButton.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.27 | AppStoreReplica - GetButton.swift | 2 | import SwiftUI 3 | 4 | 5 | struct GetButton: View { 6 | var title: String = "GET" 7 | 8 | var body: some View { 9 | Button(title) {} 10 | .font(Font.system(.caption).bold()) 11 | .padding(.horizontal, 24) 12 | .padding(.vertical, 6) 13 | .background(Color(UIColor.systemGray6)) 14 | .clipShape(Capsule()) 15 | } 16 | } 17 | 18 | 19 | struct GetButton_Previews: PreviewProvider { 20 | static var previews: some View { 21 | GetButton() 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Elements/Buttons/SingleLineButton.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.20 | AppStoreReplica - SingleLineButton.swift | 2 | import SwiftUI 3 | 4 | 5 | struct SingleLineButton: View { 6 | @State var isPresented = false 7 | let title: String 8 | 9 | var body: some View { 10 | Button(action: { 11 | isPresented = true 12 | }) { 13 | Text(title) 14 | } 15 | .sheet(isPresented: self.$isPresented) { 16 | DefaultView(title: title) 17 | } 18 | } 19 | } 20 | 21 | 22 | struct SingleLineButton_Previews: PreviewProvider { 23 | static var previews: some View { 24 | SingleLineButton(isPresented: false, title: "GET") 25 | .previewLayout(.sizeThatFits) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Elements/Buttons/SingleLineIconAndButtonView.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.26 | AppStoreReplica - SingleLineIconAndButtonView.swift | 2 | import SwiftUI 3 | 4 | 5 | struct SingleLineIconAndButtonView: View { 6 | @State var isPresented = false 7 | let emojiImage: String 8 | let buttonTitle: String 9 | 10 | var body: some View { 11 | Button(action: { 12 | isPresented = true 13 | }) { 14 | HStack() { 15 | Text(emojiImage) 16 | Text(buttonTitle) 17 | .foregroundColor(.primary) 18 | } 19 | } 20 | .frame(maxWidth: .infinity, alignment: .leading) 21 | .sheet(isPresented: self.$isPresented) { 22 | DefaultView(title: buttonTitle) 23 | } 24 | 25 | } 26 | } 27 | 28 | 29 | struct SingleLineIconAndButtonView_Previews: PreviewProvider { 30 | static var previews: some View { 31 | SingleLineIconAndButtonView(emojiImage: "🇫🇷", buttonTitle: "Title") 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Elements/Buttons/TryButton.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.27 | AppStoreReplica - TryButton.swift | 2 | import SwiftUI 3 | 4 | 5 | struct TryButton: View { 6 | var body: some View { 7 | Button("TRY IT FREE") {} 8 | .font(Font.system(.caption).bold()) 9 | .accentColor(.white) 10 | .padding(.horizontal, 18) 11 | .padding(.vertical, 6) 12 | .background(Color.blue) 13 | .clipShape(Capsule()) 14 | } 15 | } 16 | 17 | 18 | struct TryButton_Previews: PreviewProvider { 19 | static var previews: some View { 20 | TryButton() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Elements/Labels/InAppPurchasesLabel.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.27 | AppStoreReplica - InAppPurchasesLabel.swift | 2 | import SwiftUI 3 | 4 | 5 | struct InAppPurchasesLabel: View { 6 | var body: some View { 7 | Text("In-App Purchases") 8 | .font(.system(size: 8)) 9 | } 10 | } 11 | 12 | 13 | struct InAppPurchasesLabel_Previews: PreviewProvider { 14 | static var previews: some View { 15 | InAppPurchasesLabel() 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Elements/Labels/ItemDetailsLabel.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.26 | AppStoreReplica - ItemDetailsLabel.swift | 2 | import SwiftUI 3 | 4 | 5 | struct ItemDetailsLabel: View { 6 | let text: String 7 | 8 | var body: some View { 9 | Text(text) 10 | .font(.subheadline) 11 | .foregroundColor(.secondary) 12 | } 13 | } 14 | 15 | 16 | struct ItemDetailsLabel_Previews: PreviewProvider { 17 | static var previews: some View { 18 | ItemDetailsLabel(text: "Details") 19 | } 20 | } 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Elements/Labels/ItemTitleLabel.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.26 | AppStoreReplica - ItemTitleTextView.swift | 2 | import SwiftUI 3 | 4 | 5 | struct ItemTitleLabel: View { 6 | let text: String 7 | 8 | var body: some View { 9 | Text(text) 10 | .bold() 11 | } 12 | } 13 | 14 | 15 | struct ItemTitleLabel_Previews: PreviewProvider { 16 | static var previews: some View { 17 | ItemTitleLabel(text: "App name") 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Elements/Lists/RecentlyUpdatedAppsList.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.20 | AppStoreReplica - RecentlyUpdatedAppsList.swift | 2 | import SwiftUI 3 | 4 | 5 | struct RecentlyUpdatedAppsList: View { 6 | let title: String 7 | let date: String 8 | let description: String = "Release notes" 9 | let range: Range 10 | 11 | 12 | var body: some View { 13 | ForEach(range) {_ in 14 | VStack { 15 | AppSmall1Block() 16 | Spacer() 17 | HStack { 18 | Text(description) 19 | .font(.subheadline) 20 | 21 | Spacer() 22 | 23 | Button("more"){} 24 | .accentColor(.blue) 25 | .font(.subheadline) 26 | } 27 | } 28 | .padding(.vertical, 10) 29 | } 30 | } 31 | } 32 | 33 | 34 | struct RecentlyUpdatedAppsList_Previews: PreviewProvider { 35 | static var previews: some View { 36 | RecentlyUpdatedAppsList(title: "Title", date: "Today", range: Range(0...0)) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Elements/NavigationLinks/ProfileNavigationLink.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.20 | AppStoreReplica - ProfileNavigationLink.swift | 2 | import SwiftUI 3 | 4 | 5 | struct ProfileNavigationLink: View { 6 | let username: String 7 | let email: String 8 | var image: Image = Image(systemName: "person.crop.circle.fill") 9 | 10 | var body: some View { 11 | NavigationLink( 12 | destination: EmptyView(), 13 | label: { 14 | HStack { 15 | image 16 | .font(.system(size: 50)) 17 | .padding(.horizontal, 5) 18 | 19 | VStack (alignment: .leading, spacing: 5) { 20 | Text(username) 21 | Text(email) 22 | .font(.caption) 23 | } 24 | } 25 | } 26 | ) 27 | } 28 | } 29 | 30 | struct ProfileNavigationLink_Previews: PreviewProvider { 31 | static var previews: some View { 32 | ProfileNavigationLink(username: "Bartolome Estelrich", email: "my.email@icloud.com") 33 | .previewLayout(.sizeThatFits) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Elements/NavigationLinks/SingleLineNavigationLink.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.20 | AppStoreReplica - SingleLineNavigationLink.swift | 2 | import SwiftUI 3 | 4 | 5 | struct SingleLineNavigationLink: View { 6 | let text: String 7 | 8 | var body: some View { 9 | NavigationLink( 10 | destination: EmptyView(), 11 | label: { 12 | HStack { 13 | Text(text) 14 | } 15 | } 16 | ) 17 | } 18 | } 19 | 20 | 21 | struct SingleLineNavigationLink_Previews: PreviewProvider { 22 | static var previews: some View { 23 | SingleLineNavigationLink(text: "Description") 24 | .previewLayout(.sizeThatFits) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Elements/SearchBars/SearchBar.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.26 | AppStoreReplica - CustomSearchBar.swift | 2 | import SwiftUI 3 | 4 | 5 | struct CustomSearchBar: View { 6 | @Binding var text: String 7 | 8 | var body: some View { 9 | SearchBar(text: $text) 10 | .padding(.horizontal, 8) 11 | } 12 | } 13 | 14 | 15 | struct SearchBar: UIViewRepresentable { 16 | @Binding var text: String 17 | 18 | class Coordinator: NSObject, UISearchBarDelegate { 19 | @Binding var text: String 20 | 21 | init(text: Binding) { 22 | _text = text 23 | } 24 | 25 | func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { 26 | text = searchText 27 | } 28 | 29 | func searchBarSearchButtonClicked(_ searchBar: UISearchBar) { 30 | searchBar.resignFirstResponder() 31 | } 32 | } 33 | 34 | func makeCoordinator() -> SearchBar.Coordinator { 35 | return Coordinator(text: $text) 36 | } 37 | 38 | func makeUIView(context: UIViewRepresentableContext) -> UISearchBar { 39 | let searchBar = UISearchBar(frame: .zero) 40 | searchBar.delegate = context.coordinator 41 | searchBar.autocapitalizationType = .none 42 | searchBar.searchBarStyle = .minimal 43 | searchBar.enablesReturnKeyAutomatically = false 44 | return searchBar 45 | } 46 | 47 | func updateUIView(_ uiView: UISearchBar, context: UIViewRepresentableContext) { 48 | uiView.text = text 49 | uiView.placeholder = "Game, Apps, Stories, and More" 50 | } 51 | 52 | } 53 | 54 | 55 | struct CustomSearchBar_Previews: PreviewProvider { 56 | static var previews: some View { 57 | CustomSearchBar(text: .constant("Search")) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Elements/Shapes/AppShape.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.30 | AppStoreReplica - AppShape.swift | 2 | import SwiftUI 3 | 4 | 5 | struct AppShape: View { 6 | var body: some View { 7 | RoundedRectangle(cornerRadius: 12, style: .continuous) 8 | .foregroundColor(Color.gray) 9 | .frame(width: 75, height: 75) 10 | } 11 | } 12 | 13 | 14 | struct AppShape_Previews: PreviewProvider { 15 | static var previews: some View { 16 | AppShape() 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Screens/AccountView.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.20 | AppStoreReplica - AccountView.swift | 2 | import SwiftUI 3 | 4 | 5 | struct AccountView: View { 6 | @Environment(\.presentationMode) var presentationMode 7 | 8 | var body: some View { 9 | NavigationView { 10 | List { 11 | Section { 12 | ProfileNavigationLink(username: "Bartolome Estelrich", email: "my.email@icloud.com") 13 | } 14 | 15 | Section { 16 | SingleLineNavigationLink(text: "Purchased") 17 | SingleLineNavigationLink(text: "Subscriptions") 18 | } 19 | 20 | Section { 21 | SingleLineButton(title: "Redeem Gift Card or Code") 22 | SingleLineButton(title: "Send Gift Card by Email") 23 | SingleLineButton(title: "Add Funds to Apple ID") 24 | } 25 | 26 | Section { 27 | SingleLineNavigationLink(text: "Personalized Recommendations") 28 | } 29 | 30 | Section(header: Text("UPDATED RECENTLY")) { 31 | RecentlyUpdatedAppsList(title: "App title", date: "Today", range: Range(0...5)) 32 | } 33 | 34 | } 35 | .listStyle(GroupedListStyle()) 36 | .navigationBarTitle("Account", displayMode: .inline) 37 | .navigationBarItems(trailing: DismissButton(title: "Done", presentationMode: _presentationMode)) 38 | } 39 | } 40 | } 41 | 42 | 43 | struct AccountView_Previews: PreviewProvider { 44 | static var previews: some View { 45 | AccountView() 46 | .preferredColorScheme(.dark) 47 | } 48 | } 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Screens/AppMainView.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.19 | AppStore - AppMainView.swift | 2 | import SwiftUI 3 | 4 | 5 | struct AppMainView: View { 6 | 7 | var body: some View { 8 | TabView { 9 | TodayTabView() 10 | .tabItem { 11 | Image(systemName: "note") 12 | Text("Today") 13 | } 14 | 15 | GamesTabView() 16 | .tabItem { 17 | Image(systemName: "keyboard") 18 | Text("Games") 19 | } 20 | 21 | AppsTabView() 22 | .tabItem { 23 | Image(systemName: "square.stack.3d.up.fill") 24 | Text("Apps") 25 | } 26 | 27 | ArcadeTabView() 28 | .tabItem { 29 | Image(systemName: "gamecontroller.fill") 30 | Text("Arcade") 31 | } 32 | 33 | SearchTabView() 34 | .tabItem { 35 | Image(systemName: "magnifyingglass") 36 | Text("Search") 37 | } 38 | } 39 | } 40 | 41 | } 42 | 43 | 44 | struct ContentView_Previews: PreviewProvider { 45 | 46 | static var previews: some View { 47 | AppMainView() 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Screens/AppsTabView.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.19 | AppStore - AppsTabView.swift | 2 | import SwiftUI 3 | 4 | 5 | struct AppsTabView: View { 6 | @State var isAccountViewPresented = false 7 | 8 | var body: some View { 9 | NavigationView { 10 | ScrollView { 11 | AppCarouselLargeBlock() 12 | AppCarouselSmall1Block(title: "Get Ready for Sports") 13 | AppCarouselMedium2Block(title: "Apps With Free Trials", cellsNumber: 5) 14 | TopAppsCategoriesBlock() 15 | QuickLinksBlock() 16 | TermsAndConditionsBlock() 17 | } 18 | .navigationBarTitle("Apps") 19 | .navigationBarItems(trailing: AccountButton(isAccountViewPresented: $isAccountViewPresented)) 20 | } 21 | } 22 | } 23 | 24 | 25 | struct AppsTabView_Previews: PreviewProvider { 26 | static var previews: some View { 27 | AppsTabView() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Screens/ArcadeTabView.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.19 | AppStore - ArcadeTabView.swift | 2 | import SwiftUI 3 | 4 | 5 | struct ArcadeTabView: View { 6 | @State var isAccountViewPresented = false 7 | 8 | var body: some View { 9 | ScrollView { 10 | ArcadeHeader() 11 | AppCarouselSmall1Block(title: "Popular Arcade Games") 12 | AppCarouselMedium1Block(title: "Arcade Games With Gorgeous Graphics", cellsNumber: 5) 13 | AppCarouselSmall2Block() 14 | TermsAndConditionsBlock() 15 | } 16 | .edgesIgnoringSafeArea(.top) 17 | } 18 | } 19 | 20 | 21 | struct ArcadeTabView_Previews: PreviewProvider { 22 | static var previews: some View { 23 | ArcadeTabView() 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Screens/DefaultView.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.27 | AppStoreReplica - DefaultView.swift | 2 | import SwiftUI 3 | 4 | 5 | struct DefaultView: View { 6 | @Environment(\.presentationMode) var presentationMode 7 | let title: String 8 | 9 | var body: some View { 10 | NavigationView { 11 | Text(title) 12 | .navigationBarTitle(title, displayMode: .inline) 13 | .navigationBarItems(leading: DismissButton(title: "Cancel", presentationMode: _presentationMode)) 14 | } 15 | } 16 | } 17 | 18 | 19 | struct DefaultView_Previews: PreviewProvider { 20 | static var previews: some View { 21 | DefaultView(title: "Default") 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Screens/GamesTabView.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.19 | AppStore - GamesTabView.swift | 2 | import SwiftUI 3 | 4 | 5 | struct GamesTabView: View { 6 | @State var isAccountViewPresented = false 7 | 8 | var body: some View { 9 | NavigationView { 10 | ScrollView { 11 | AppCarouselLargeBlock() 12 | AppCarouselSmall1Block(title: "What to Play This Week") 13 | AppCarouselSmall1Block(title: "New Games We Love") 14 | AppCarouselMedium1Block(title: "Coming Soon", cellsNumber: 5) 15 | TopGamesCategoriesBlock() 16 | QuickLinksBlock() 17 | TermsAndConditionsBlock() 18 | } 19 | .navigationBarTitle("Games") 20 | .navigationBarItems(trailing: AccountButton(isAccountViewPresented: $isAccountViewPresented)) 21 | } 22 | .navigationViewStyle(StackNavigationViewStyle()) 23 | } 24 | } 25 | 26 | 27 | struct GamesTabView_Previews: PreviewProvider { 28 | static var previews: some View { 29 | GamesTabView() 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Screens/SearchTabView.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.19 | AppStore - SearchTabView.swift | 2 | import SwiftUI 3 | //import Combine 4 | 5 | 6 | struct SearchTabView: View { 7 | @State var isAccountViewPresented = false 8 | @State var text: String = "" 9 | 10 | var body: some View { 11 | NavigationView { 12 | ScrollView { 13 | CustomSearchBar(text: $text) 14 | DiscoverBlock() 15 | Spacer() 16 | SuggestedAppsBlock() 17 | } 18 | .navigationBarTitle("Search") 19 | .navigationBarItems(leading: SearchBar(text: $text), trailing: AccountButton(isAccountViewPresented: $isAccountViewPresented)) 20 | } 21 | .navigationViewStyle(StackNavigationViewStyle()) 22 | } 23 | } 24 | 25 | 26 | struct SearchTabView_Previews: PreviewProvider { 27 | static var previews: some View { 28 | SearchTabView() 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /AppStoreReplica/AppStoreReplica/Views/Screens/TodayTabView.swift: -------------------------------------------------------------------------------- 1 | // 2020.07.19 | AppStore - TodayTabView.swift | 2 | import SwiftUI 3 | 4 | 5 | struct TodayTabView: View { 6 | 7 | var body: some View { 8 | ScrollView { 9 | ForEach(Range(0...4)) { index in 10 | setupCurrentDate(by: index) 11 | AppCarouselExtraLargeBlock() 12 | } 13 | } 14 | } 15 | 16 | 17 | func setupCurrentDate(by index: Int) -> AnyView { 18 | let date = Calendar.current.date(byAdding: .day, value: index, to: Date()) 19 | return index == 0 ? AnyView(NavigationViewHeaderWithImageBlock(date: date!)) : AnyView(NavigationViewHeaderBlock(date: date!)) 20 | } 21 | 22 | } 23 | 24 | 25 | struct TodayTabView_Previews: PreviewProvider { 26 | static var previews: some View { 27 | TodayTabView() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 |

AppStore Replica App

4 | 5 | [![Swift](https://img.shields.io/badge/Swift-5.0-orange.svg?longCache=true&style=flat&logo=swift)][Swift] 6 | [![iOS](https://img.shields.io/badge/iOS-14.0+-lightgrey.svg?longCache=true&?style=flat&logo=apple)][iOS] 7 | [![](https://img.shields.io/badge/Twitter-%231DA1F2.svg?&style=flat&logo=twitter&logoColor=white)][Twitter] 8 | 9 | 10 | 11 | 12 | 13 | ## Documentation 14 | - [SwiftUI framework](https://developer.apple.com/documentation/swiftui) 15 | 16 | 17 | ## Frameworks/External dependencies 18 | - Foundation 19 | - SwiftUI 20 | 21 | 22 | ## Description 23 | AppStore Replica pretends to be a **copy of the App Store layout made entirely in SwiftUI**. In order to structure the project, views have been divided into **three groups: Screens, Blocks and Elements**. **Screens** are made up of the **sum of views that generate a complete screen in the app**, while **Blocks** are basically **partial views that are used multiple times** during the project. Finally, **basic views** like buttons, labels or lists belong to the **Elements** group. 24 | 25 | The **goal** of this project is to **put into practice the concepts learned in SwiftUI** and understand better how views are divided, reused and connected in a multi-tab-application. 26 | 27 | 28 | ## Preview 29 | Those are the most relevant screenshots of the app. 30 | 31 |

32 | 33 | 34 | 35 | 36 | 37 | 38 |

39 | 40 | 41 | 42 | 43 | 44 | 45 | [Swift]: https://www.swift.org 46 | [iOS]: https://developer.apple.com/ios/ 47 | [Twitter]: https://twitter.com/TomEstelrich --------------------------------------------------------------------------------