├── .gitignore ├── .gitigore ├── Frameworks ├── Traditional │ ├── Assets │ │ ├── iOS │ │ │ └── Info.plist │ │ ├── macOS │ │ │ └── Info.plist │ │ ├── tvOS │ │ │ └── Info.plist │ │ └── watchOS │ │ │ └── Info.plist │ ├── Console.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── xcshareddata │ │ │ └── xcschemes │ │ │ │ ├── Console-iOS.xcscheme │ │ │ │ ├── Console-macOS.xcscheme │ │ │ │ ├── Console-tvOS.xcscheme │ │ │ │ └── Console-watchOS.xcscheme │ │ └── xcuserdata │ │ │ ├── rami.xcuserdatad │ │ │ └── xcschemes │ │ │ │ └── xcschememanagement.plist │ │ │ └── tib.xcuserdatad │ │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ ├── Sources │ │ ├── Console.h │ │ └── Console.swift │ └── Tests │ │ ├── Assets │ │ ├── iOS │ │ │ └── Info.plist │ │ ├── macOS │ │ │ └── Info.plist │ │ └── tvOS │ │ │ └── Info.plist │ │ └── Sources │ │ └── ConsoleTests.swift ├── Universal │ ├── Assets │ │ ├── Console.xcconfig │ │ └── Info.plist │ ├── Console.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── xcshareddata │ │ │ └── xcschemes │ │ │ │ └── Console.xcscheme │ │ └── xcuserdata │ │ │ └── rami.xcuserdatad │ │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ ├── Sources │ │ ├── Console.h │ │ └── Console.swift │ └── Tests │ │ ├── Assets │ │ ├── Console-Tests.xcconfig │ │ └── Info.plist │ │ └── Sources │ │ └── ConsoleTests.swift └── Usage │ ├── Usage.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── tib.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist │ └── Usage │ ├── AppDelegate.swift │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ └── ViewController.swift ├── LICENSE ├── README.md ├── VIPER ├── ServicesAndVIPER │ ├── Application │ │ ├── Assets │ │ │ ├── Assets.xcassets │ │ │ │ ├── AppIcon.appiconset │ │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ │ └── Base.lproj │ │ │ │ ├── LaunchScreen.storyboard │ │ │ │ └── Main.storyboard │ │ └── Sources │ │ │ ├── App │ │ │ ├── App.swift │ │ │ ├── Controllers │ │ │ │ └── ViewController.swift │ │ │ └── VIPER │ │ │ │ └── ServiceInteractor.swift │ │ │ ├── AppDelegate.swift │ │ │ ├── SceneDelegate.swift │ │ │ └── Services │ │ │ ├── Api │ │ │ ├── ApiServiceInterface.swift │ │ │ ├── HTTP.swift │ │ │ ├── MyApiService.swift │ │ │ └── Objects │ │ │ │ └── TodoObject.swift │ │ │ ├── ServiceBuilderInterface.swift │ │ │ └── ServiceInterface.swift │ ├── Environments │ │ ├── Development │ │ │ ├── Assets │ │ │ │ └── Info.plist │ │ │ └── Sources │ │ │ │ └── Services │ │ │ │ └── ServiceBuilder.swift │ │ ├── Fake │ │ │ ├── Assets │ │ │ │ └── Info.plist │ │ │ └── Sources │ │ │ │ ├── ServiceBuilder.swift │ │ │ │ └── Services │ │ │ │ └── Api │ │ │ │ └── FakeApiService.swift │ │ └── Production │ │ │ ├── Assets │ │ │ └── Info.plist │ │ │ └── Sources │ │ │ └── Services │ │ │ └── ServiceBuilder.swift │ └── ServicesAndVIPER.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── xcshareddata │ │ └── xcschemes │ │ │ ├── ServicesAndVIPER-Development.xcscheme │ │ │ ├── ServicesAndVIPER-Fake.xcscheme │ │ │ └── ServicesAndVIPER.xcscheme │ │ └── xcuserdata │ │ └── tib.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── VIPER best practices │ ├── .gitignore │ ├── VIPER best practices.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ └── swiftpm │ │ │ │ └── Package.resolved │ │ └── xcuserdata │ │ │ └── tib.xcuserdatad │ │ │ ├── xcdebugger │ │ │ └── Breakpoints_v2.xcbkptlist │ │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ └── VIPER best practices │ │ ├── Assets │ │ ├── Assets.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── Base.lproj │ │ │ └── LaunchScreen.storyboard │ │ └── Info.plist │ │ └── Sources │ │ ├── App │ │ ├── App.swift │ │ ├── ViewModels │ │ │ ├── BookmarkViewModel.swift │ │ │ └── CommentViewModel.swift │ │ └── Views │ │ │ ├── TextCell.swift │ │ │ ├── TextCell.xib │ │ │ ├── TextDetailCell.swift │ │ │ └── TextDetailCell.xib │ │ ├── AppDelegate.swift │ │ ├── Modules │ │ ├── Albums │ │ │ ├── AlbumsModule.swift │ │ │ ├── Implementations │ │ │ │ └── Default │ │ │ │ │ ├── AlbumsDefaultInteractor.swift │ │ │ │ │ ├── AlbumsDefaultPresenter.swift │ │ │ │ │ ├── AlbumsDefaultRouter.swift │ │ │ │ │ └── AlbumsDefaultView.swift │ │ │ └── Interfaces │ │ │ │ ├── AlbumsInteractor.swift │ │ │ │ ├── AlbumsPresenter.swift │ │ │ │ ├── AlbumsRouter.swift │ │ │ │ └── AlbumsView.swift │ │ ├── Home │ │ │ ├── HomeModule.swift │ │ │ ├── Implementations │ │ │ │ └── Default │ │ │ │ │ ├── HomeDefaultInteractor.swift │ │ │ │ │ ├── HomeDefaultPresenter.swift │ │ │ │ │ ├── HomeDefaultRouter.swift │ │ │ │ │ └── HomeDefaultView.swift │ │ │ └── Interfaces │ │ │ │ ├── HomeInteractor.swift │ │ │ │ ├── HomePresenter.swift │ │ │ │ ├── HomeRouter.swift │ │ │ │ └── HomeView.swift │ │ ├── Main │ │ │ ├── Implementations │ │ │ │ └── Default │ │ │ │ │ ├── MainDefaultInteractor.swift │ │ │ │ │ ├── MainDefaultPresenter.swift │ │ │ │ │ ├── MainDefaultRouter.swift │ │ │ │ │ └── MainDefaultView.swift │ │ │ ├── Interfaces │ │ │ │ ├── MainInteractor.swift │ │ │ │ ├── MainPresenter.swift │ │ │ │ ├── MainRouter.swift │ │ │ │ └── MainView.swift │ │ │ └── MainModule.swift │ │ ├── Photos │ │ │ ├── Implementations │ │ │ │ └── Default │ │ │ │ │ ├── PhotosDefaultInteractor.swift │ │ │ │ │ ├── PhotosDefaultPresenter.swift │ │ │ │ │ ├── PhotosDefaultRouter.swift │ │ │ │ │ └── PhotosDefaultView.swift │ │ │ ├── Interfaces │ │ │ │ ├── PhotosInteractor.swift │ │ │ │ ├── PhotosPresenter.swift │ │ │ │ ├── PhotosRouter.swift │ │ │ │ └── PhotosView.swift │ │ │ └── PhotosModule.swift │ │ ├── PostDetails │ │ │ ├── Implementations │ │ │ │ └── Default │ │ │ │ │ ├── PostDetailsDefaultInteractor.swift │ │ │ │ │ ├── PostDetailsDefaultPresenter.swift │ │ │ │ │ ├── PostDetailsDefaultRouter.swift │ │ │ │ │ └── PostDetailsDefaultView.swift │ │ │ ├── Interfaces │ │ │ │ ├── PostDetailsInteractor.swift │ │ │ │ ├── PostDetailsPresenter.swift │ │ │ │ ├── PostDetailsRouter.swift │ │ │ │ └── PostDetailsView.swift │ │ │ └── PostDetailsModule.swift │ │ ├── Posts │ │ │ ├── Implementations │ │ │ │ └── Default │ │ │ │ │ ├── PostsDefaultInteractor.swift │ │ │ │ │ ├── PostsDefaultPresenter.swift │ │ │ │ │ ├── PostsDefaultRouter.swift │ │ │ │ │ └── PostsDefaultView.swift │ │ │ ├── Interfaces │ │ │ │ ├── PostsInteractor.swift │ │ │ │ ├── PostsPresenter.swift │ │ │ │ ├── PostsRouter.swift │ │ │ │ └── PostsView.swift │ │ │ └── PostsModule.swift │ │ └── Todos │ │ │ ├── Implementations │ │ │ └── Default │ │ │ │ ├── TodosDefaultInteractor.swift │ │ │ │ ├── TodosDefaultPresenter.swift │ │ │ │ ├── TodosDefaultRouter.swift │ │ │ │ ├── TodosDefaultView.swift │ │ │ │ └── TodosModule.swift │ │ │ └── Interfaces │ │ │ ├── TodosInteractor.swift │ │ │ ├── TodosPresenter.swift │ │ │ ├── TodosRouter.swift │ │ │ └── TodosView.swift │ │ └── Services │ │ ├── Api │ │ ├── ApiService.swift │ │ ├── Entities │ │ │ ├── Album.swift │ │ │ ├── Comment.swift │ │ │ ├── Photo.swift │ │ │ ├── Post.swift │ │ │ └── Todo.swift │ │ └── Implementations │ │ │ ├── JSONPlaceholder │ │ │ └── JSONPlaceholderService.swift │ │ │ └── Mock │ │ │ └── MockService.swift │ │ └── Bookmark │ │ ├── BookmarkService.swift │ │ ├── Entities │ │ └── Bookmark.swift │ │ └── Implementations │ │ └── Default │ │ └── DefaultBookmarkService.swift └── VIPERAndSwiftUI │ ├── VIPERAndSwiftUI.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── tib.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── tib.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ └── xcschememanagement.plist │ └── VIPERAndSwiftUI │ ├── Assets │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Base.lproj │ │ └── LaunchScreen.storyboard │ ├── Info.plist │ └── Preview Assets.xcassets │ │ └── Contents.json │ └── Sources │ ├── AppDelegate.swift │ ├── HTTP.swift │ ├── Modules │ └── Todo │ │ ├── TodoEntity.swift │ │ ├── TodoEnvironment.swift │ │ ├── TodoInteractor.swift │ │ ├── TodoListItemView.swift │ │ ├── TodoModule.swift │ │ ├── TodoPresenter.swift │ │ ├── TodoRouter.swift │ │ ├── TodoView.swift │ │ └── TodoViewModel.swift │ ├── Publisher+On.swift │ ├── SceneDelegate.swift │ └── VIPER.swift ├── iOS ├── Auto Layout │ ├── AutoLayout - Anchors │ │ ├── AutoLayout - Anchors.xcodeproj │ │ │ ├── project.pbxproj │ │ │ ├── project.xcworkspace │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ └── xcuserdata │ │ │ │ │ └── tib.xcuserdatad │ │ │ │ │ └── UserInterfaceState.xcuserstate │ │ │ └── xcuserdata │ │ │ │ └── tib.xcuserdatad │ │ │ │ └── xcschemes │ │ │ │ └── xcschememanagement.plist │ │ └── AutoLayout - Anchors │ │ │ ├── AppDelegate.swift │ │ │ ├── Assets.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ │ ├── Info.plist │ │ │ └── ViewController.swift │ ├── AutoLayout - Constraints │ │ ├── AutoLayout - Constraints.xcodeproj │ │ │ ├── project.pbxproj │ │ │ ├── project.xcworkspace │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ └── xcuserdata │ │ │ │ │ └── tib.xcuserdatad │ │ │ │ │ └── UserInterfaceState.xcuserstate │ │ │ └── xcuserdata │ │ │ │ └── tib.xcuserdatad │ │ │ │ └── xcschemes │ │ │ │ └── xcschememanagement.plist │ │ └── AutoLayout - Constraints │ │ │ ├── AppDelegate.swift │ │ │ ├── Assets.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ │ ├── Info.plist │ │ │ └── ViewController.swift │ ├── AutoLayout - VFL │ │ ├── AutoLayout - VFL.xcodeproj │ │ │ ├── project.pbxproj │ │ │ └── xcuserdata │ │ │ │ └── tib.xcuserdatad │ │ │ │ └── xcschemes │ │ │ │ └── xcschememanagement.plist │ │ └── AutoLayout - VFL │ │ │ ├── AppDelegate.swift │ │ │ ├── Assets.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ │ ├── Info.plist │ │ │ └── ViewController.swift │ ├── AutoLayout.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── tib.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ ├── Layers - Circle │ │ ├── Layers - Circle.xcodeproj │ │ │ ├── project.pbxproj │ │ │ ├── project.xcworkspace │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ └── xcuserdata │ │ │ │ │ └── tib.xcuserdatad │ │ │ │ │ └── UserInterfaceState.xcuserstate │ │ │ └── xcuserdata │ │ │ │ └── tib.xcuserdatad │ │ │ │ └── xcschemes │ │ │ │ └── xcschememanagement.plist │ │ └── Layers - Circle │ │ │ ├── AppDelegate.swift │ │ │ ├── Assets.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ │ ├── CircularImageView.swift │ │ │ ├── Info.plist │ │ │ └── ViewController.swift │ ├── Layers - Gradient │ │ ├── Layers - Gradient.xcodeproj │ │ │ ├── project.pbxproj │ │ │ ├── project.xcworkspace │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ └── xcuserdata │ │ │ │ │ └── tib.xcuserdatad │ │ │ │ │ └── UserInterfaceState.xcuserstate │ │ │ └── xcuserdata │ │ │ │ └── tib.xcuserdatad │ │ │ │ └── xcschemes │ │ │ │ └── xcschememanagement.plist │ │ └── Layers - Gradient │ │ │ ├── AppDelegate.swift │ │ │ ├── Assets.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ │ ├── GradientView.swift │ │ │ ├── Info.plist │ │ │ └── ViewController.swift │ └── SpringsAndStruts │ │ ├── SpringsAndStruts.xcodeproj │ │ ├── project.pbxproj │ │ └── xcuserdata │ │ │ └── tib.xcuserdatad │ │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ │ └── SpringsAndStruts │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── ViewController.swift ├── CollectionView │ ├── Best Practice │ │ ├── CollectionViewExample.xcodeproj │ │ │ ├── project.pbxproj │ │ │ ├── project.xcworkspace │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ ├── xcshareddata │ │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ │ └── swiftpm │ │ │ │ │ │ └── Package.resolved │ │ │ │ └── xcuserdata │ │ │ │ │ └── tib.xcuserdatad │ │ │ │ │ └── UserInterfaceState.xcuserstate │ │ │ └── xcuserdata │ │ │ │ └── tib.xcuserdatad │ │ │ │ └── xcschemes │ │ │ │ └── xcschememanagement.plist │ │ └── CollectionViewExample │ │ │ ├── AppDelegate.swift │ │ │ ├── Assets.xcassets │ │ │ ├── 01.imageset │ │ │ │ ├── ABR.jpg │ │ │ │ └── Contents.json │ │ │ ├── 02.imageset │ │ │ │ ├── BOS.jpg │ │ │ │ └── Contents.json │ │ │ ├── 03.imageset │ │ │ │ ├── C.jpg │ │ │ │ └── Contents.json │ │ │ ├── 04.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── MTS.jpg │ │ │ ├── 05.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── PWD.jpg │ │ │ ├── 06.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── TH.jpg │ │ │ ├── 07.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── UABB.jpg │ │ │ ├── 08.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── W.jpg │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ ├── a01.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── a01.png │ │ │ ├── a02.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── a02.jpeg │ │ │ ├── a03.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── a03.png │ │ │ ├── a04.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── a04.jpeg │ │ │ ├── a05.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── a05.jpg │ │ │ ├── a06.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── a06.jpg │ │ │ ├── a07.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── a07.jpeg │ │ │ └── a08.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── a08.jpeg │ │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ │ ├── Components │ │ │ ├── Album │ │ │ │ ├── AlbumCell.swift │ │ │ │ ├── AlbumCell.xib │ │ │ │ ├── AlbumModel.swift │ │ │ │ └── AlbumViewModel.swift │ │ │ ├── Artist │ │ │ │ ├── ArtistCell.swift │ │ │ │ ├── ArtistCell.xib │ │ │ │ ├── ArtistModel.swift │ │ │ │ └── ArtistViewModel.swift │ │ │ ├── Collection │ │ │ │ ├── CollectionCell.swift │ │ │ │ ├── CollectionCell.xib │ │ │ │ ├── CollectionModel.swift │ │ │ │ └── CollectionViewModel.swift │ │ │ ├── Header │ │ │ │ ├── HeaderCell.swift │ │ │ │ ├── HeaderCell.xib │ │ │ │ ├── HeaderModel.swift │ │ │ │ └── HeaderViewModel.swift │ │ │ ├── Separator │ │ │ │ ├── SeparatorCell.swift │ │ │ │ ├── SeparatorCell.xib │ │ │ │ ├── SeparatorModel.swift │ │ │ │ └── SeparatorViewModel.swift │ │ │ ├── Song │ │ │ │ ├── SongCell.swift │ │ │ │ ├── SongCell.xib │ │ │ │ ├── SongModel.swift │ │ │ │ └── SongViewModel.swift │ │ │ └── Text │ │ │ │ ├── TextCell.swift │ │ │ │ ├── TextCell.xib │ │ │ │ ├── TextModel.swift │ │ │ │ └── TextViewModel.swift │ │ │ ├── Controllers │ │ │ ├── AlbumViewController.swift │ │ │ ├── ArtistViewController.swift │ │ │ └── ViewController.swift │ │ │ ├── Extensions │ │ │ └── UILabel+Height.swift │ │ │ └── Info.plist │ ├── Circular Cells │ │ ├── .gitignore │ │ ├── CircularCells.xcodeproj │ │ │ ├── project.pbxproj │ │ │ ├── project.xcworkspace │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ ├── xcshareddata │ │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ │ └── xcuserdata │ │ │ │ │ └── tib.xcuserdatad │ │ │ │ │ └── UserInterfaceState.xcuserstate │ │ │ ├── xcshareddata │ │ │ │ └── xcschemes │ │ │ │ │ └── CircularCells.xcscheme │ │ │ └── xcuserdata │ │ │ │ └── tib.xcuserdatad │ │ │ │ └── xcschemes │ │ │ │ └── xcschememanagement.plist │ │ └── CircularCells │ │ │ ├── AppDelegate.swift │ │ │ ├── Assets.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ │ ├── Cell.swift │ │ │ ├── Example.jpg │ │ │ ├── Info.plist │ │ │ └── ViewController.swift │ ├── IB │ │ ├── CollectionView.xcodeproj │ │ │ ├── project.pbxproj │ │ │ ├── project.xcworkspace │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ ├── xcshareddata │ │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ │ └── xcuserdata │ │ │ │ │ └── tib.xcuserdatad │ │ │ │ │ └── UserInterfaceState.xcuserstate │ │ │ └── xcuserdata │ │ │ │ └── tib.xcuserdatad │ │ │ │ └── xcschemes │ │ │ │ └── xcschememanagement.plist │ │ └── CollectionView │ │ │ ├── AppDelegate.swift │ │ │ ├── Assets.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ │ ├── Info.plist │ │ │ └── ViewController.swift │ ├── Programmatically │ │ ├── CollectionView.xcodeproj │ │ │ ├── project.pbxproj │ │ │ ├── project.xcworkspace │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ ├── xcshareddata │ │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ │ └── xcuserdata │ │ │ │ │ └── tib.xcuserdatad │ │ │ │ │ └── UserInterfaceState.xcuserstate │ │ │ └── xcuserdata │ │ │ │ └── tib.xcuserdatad │ │ │ │ └── xcschemes │ │ │ │ └── xcschememanagement.plist │ │ └── CollectionView │ │ │ ├── AppDelegate.swift │ │ │ ├── Assets.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ │ ├── Info.plist │ │ │ ├── MyCell.swift │ │ │ └── ViewController.swift │ ├── Sections │ │ ├── CollectionView.xcodeproj │ │ │ ├── project.pbxproj │ │ │ ├── project.xcworkspace │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ ├── xcshareddata │ │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ │ └── xcuserdata │ │ │ │ │ └── tib.xcuserdatad │ │ │ │ │ └── UserInterfaceState.xcuserstate │ │ │ └── xcuserdata │ │ │ │ └── tib.xcuserdatad │ │ │ │ └── xcschemes │ │ │ │ └── xcschememanagement.plist │ │ └── CollectionView │ │ │ ├── AppDelegate.swift │ │ │ ├── Assets.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ │ ├── Cell.swift │ │ │ ├── Cell.xib │ │ │ ├── Info.plist │ │ │ ├── Section.swift │ │ │ ├── Section.xib │ │ │ └── ViewController.swift │ └── Self Sizing Cells │ │ ├── .gitignore │ │ ├── SelfSizing.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ ├── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ └── xcuserdata │ │ │ │ └── tib.xcuserdatad │ │ │ │ └── UserInterfaceState.xcuserstate │ │ └── xcuserdata │ │ │ └── tib.xcuserdatad │ │ │ └── xcschemes │ │ │ ├── SelfSizing.xcscheme │ │ │ └── xcschememanagement.plist │ │ └── SelfSizing │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── CollectionViewCell.swift │ │ ├── CollectionViewController.swift │ │ ├── Info.plist │ │ ├── TableViewCell.swift │ │ └── TableViewController.swift ├── Forms │ └── StackForm │ │ ├── StackForm.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ ├── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ └── xcuserdata │ │ │ │ └── tib.xcuserdatad │ │ │ │ └── UserInterfaceState.xcuserstate │ │ └── xcuserdata │ │ │ └── tib.xcuserdatad │ │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ │ └── StackForm │ │ ├── Assets │ │ ├── Assets.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ └── Info.plist │ │ └── Sources │ │ ├── AppDelegate.swift │ │ ├── Extensions │ │ └── UIView+Id.swift │ │ ├── SceneDelegate.swift │ │ ├── ViewController.swift │ │ └── Views │ │ ├── Buttons │ │ ├── Button.swift │ │ └── SubmitButton.swift │ │ ├── ScrollView.swift │ │ ├── StackView.swift │ │ └── TextFields │ │ ├── EmailTextField.swift │ │ ├── PasswordTextField.swift │ │ └── TextField.swift ├── Pickers │ ├── Pickers.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── tib.xcuserdatad │ │ │ ├── xcdebugger │ │ │ └── Breakpoints_v2.xcbkptlist │ │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ └── Pickers │ │ ├── Assets │ │ ├── Assets.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ └── Info.plist │ │ └── Sources │ │ ├── AppDelegate.swift │ │ ├── ImagePicker.swift │ │ ├── SceneDelegate.swift │ │ ├── VideoPicker.swift │ │ ├── VideoView.swift │ │ └── ViewController.swift ├── SpriteKit │ └── Best Practices │ │ ├── SpriteKitBestPractices.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ ├── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ └── xcuserdata │ │ │ │ └── tib.xcuserdatad │ │ │ │ └── UserInterfaceState.xcuserstate │ │ └── xcuserdata │ │ │ └── tib.xcuserdatad │ │ │ ├── xcdebugger │ │ │ └── Breakpoints_v2.xcbkptlist │ │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ │ └── SpriteKitBestPractices │ │ ├── Assets │ │ ├── Assets.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── Scenes │ │ │ ├── Actions.sks │ │ │ └── GameScene.sks │ │ └── Sources │ │ ├── AppDelegate.swift │ │ ├── GameScene.swift │ │ ├── GameViewController.swift │ │ └── SKTexture+Gradient.swift ├── ViewController │ └── Custom Transitions │ │ ├── CustomTransition.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ ├── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ └── xcuserdata │ │ │ │ └── tib.xcuserdatad │ │ │ │ └── UserInterfaceState.xcuserstate │ │ └── xcuserdata │ │ │ └── tib.xcuserdatad │ │ │ ├── xcdebugger │ │ │ └── Breakpoints_v2.xcbkptlist │ │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ │ └── CustomTransition │ │ ├── Assets │ │ ├── Assets.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ └── Info.plist │ │ └── Sources │ │ ├── Animators │ │ ├── CustomAnimator.swift │ │ ├── FadePopAnimator.swift │ │ ├── FadePushAnimator.swift │ │ ├── SystemPopAnimator.swift │ │ └── SystemPushAnimator.swift │ │ ├── AppDelegate.swift │ │ ├── Controllers │ │ ├── DetailViewController.swift │ │ ├── MainViewController.swift │ │ └── ModalViewController.swift │ │ └── Interactions │ │ └── LeftEdgeInteractionController.swift └── iCloud drive │ ├── iCloudDrive.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── tib.xcuserdatad │ │ └── xcschemes │ │ ├── iCloudDrive.xcscheme │ │ └── xcschememanagement.plist │ └── iCloudDrive │ ├── Assets │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ └── iCloudDrive.entitlements │ └── Sources │ ├── AppDelegate.swift │ └── ViewController.swift └── macOS ├── Launcher ├── LauncherApplication │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ └── Main.storyboard │ ├── Info.plist │ └── LauncherApplication.entitlements ├── MainApplication.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── tib.xcuserdatad │ │ └── xcschemes │ │ ├── LauncherApplication.xcscheme │ │ ├── MainApplication.xcscheme │ │ └── xcschememanagement.plist └── MainApplication │ ├── AppDelegate.swift │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── Base.lproj │ └── Main.storyboard │ ├── Info.plist │ ├── MainApplication.entitlements │ └── ViewController.swift └── Networking ├── .gitignore ├── Networking.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcuserdata │ └── tib.xcuserdatad │ └── xcschemes │ ├── iOS.xcscheme │ └── xcschememanagement.plist ├── Shared └── Sources │ ├── BluetoothClient.swift │ ├── BluetoothConfig.swift │ ├── BluetoothServer.swift │ ├── NetworkDevice.swift │ ├── TCPClient.swift │ ├── TCPConfig.swift │ ├── TCPServer.swift │ ├── UDPClient.swift │ ├── UDPConfig.swift │ └── UDPServer.swift ├── iOS └── Application │ ├── Assets │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ └── Info.plist │ └── Sources │ ├── AppDelegate.swift │ └── ViewController.swift ├── macOS └── Application │ ├── Assets │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ └── Main.storyboard │ ├── Info.plist │ └── macOS.entitlements │ └── Sources │ ├── AppDelegate.swift │ └── ViewController.swift ├── tvOS └── Application │ ├── Assets │ ├── Assets.xcassets │ │ ├── App Icon & Top Shelf Image.brandassets │ │ │ ├── App Icon - App Store.imagestack │ │ │ │ ├── Back.imagestacklayer │ │ │ │ │ ├── Content.imageset │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── Contents.json │ │ │ │ ├── Contents.json │ │ │ │ ├── Front.imagestacklayer │ │ │ │ │ ├── Content.imageset │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── Contents.json │ │ │ │ └── Middle.imagestacklayer │ │ │ │ │ ├── Content.imageset │ │ │ │ │ └── Contents.json │ │ │ │ │ └── Contents.json │ │ │ ├── App Icon.imagestack │ │ │ │ ├── Back.imagestacklayer │ │ │ │ │ ├── Content.imageset │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── Contents.json │ │ │ │ ├── Contents.json │ │ │ │ ├── Front.imagestacklayer │ │ │ │ │ ├── Content.imageset │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── Contents.json │ │ │ │ └── Middle.imagestacklayer │ │ │ │ │ ├── Content.imageset │ │ │ │ │ └── Contents.json │ │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ ├── Top Shelf Image Wide.imageset │ │ │ │ └── Contents.json │ │ │ └── Top Shelf Image.imageset │ │ │ │ └── Contents.json │ │ ├── Contents.json │ │ └── LaunchImage.launchimage │ │ │ └── Contents.json │ ├── Base.lproj │ │ └── Main.storyboard │ └── Info.plist │ └── Sources │ ├── AppDelegate.swift │ └── ViewController.swift └── watchOS ├── Application └── Assets │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── Base.lproj │ └── Interface.storyboard │ └── Info.plist └── Extension ├── Assets ├── Assets.xcassets │ └── Complication.complicationset │ │ ├── Circular.imageset │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── Extra Large.imageset │ │ └── Contents.json │ │ ├── Modular.imageset │ │ └── Contents.json │ │ └── Utilitarian.imageset │ │ └── Contents.json ├── Info.plist └── PushNotificationPayload.apns └── Sources ├── ExtensionDelegate.swift ├── InterfaceController.swift └── NotificationController.swift /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.xcuserstate 3 | -------------------------------------------------------------------------------- /.gitigore: -------------------------------------------------------------------------------- 1 | *.xcuserstate 2 | -------------------------------------------------------------------------------- /Frameworks/Traditional/Assets/iOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Frameworks/Traditional/Assets/macOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSHumanReadableCopyright 22 | Copyright © 2017. Tibor Bodecs. All rights reserved. 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Frameworks/Traditional/Assets/tvOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Frameworks/Traditional/Assets/watchOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Frameworks/Traditional/Console.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Frameworks/Traditional/Console.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Frameworks/Traditional/Console.xcodeproj/xcuserdata/tib.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Console-iOS.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | Console-macOS.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 1 16 | 17 | Console-tvOS.xcscheme_^#shared#^_ 18 | 19 | orderHint 20 | 2 21 | 22 | Console-watchOS.xcscheme_^#shared#^_ 23 | 24 | orderHint 25 | 3 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /Frameworks/Traditional/Sources/Console.h: -------------------------------------------------------------------------------- 1 | // 2 | // Console.h 3 | // Console 4 | // 5 | // Created by Tibor Bödecs on 2017. 10. 18.. 6 | // Copyright © 2017. Tibor Bodecs. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for Console. 12 | FOUNDATION_EXPORT double ConsoleVersionNumber; 13 | 14 | //! Project version string for Console. 15 | FOUNDATION_EXPORT const unsigned char ConsoleVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /Frameworks/Traditional/Tests/Assets/iOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Frameworks/Traditional/Tests/Assets/macOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Frameworks/Traditional/Tests/Assets/tvOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Frameworks/Traditional/Tests/Sources/ConsoleTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ConsoleTests.swift 3 | // ConsoleTests 4 | // 5 | // Created by Tibor Bödecs on 2017. 10. 18.. 6 | // Copyright © 2017. Tibor Bodecs. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import Console 11 | 12 | 13 | class ConsoleTests: XCTestCase { 14 | 15 | func testExample() { 16 | Console.log("Hello World!") 17 | Console.log(Console.platform) 18 | 19 | #if os(iOS) 20 | XCTAssert(Console.platform == "iOS") 21 | #endif 22 | #if os(macOS) 23 | XCTAssert(Console.platform == "macOS") 24 | #endif 25 | #if os(tvOS) 26 | XCTAssert(Console.platform == "tvOS") 27 | #endif 28 | #if os(watchOS) 29 | XCTAssert(Console.platform == "watchOS") 30 | #endif 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Frameworks/Universal/Assets/Console.xcconfig: -------------------------------------------------------------------------------- 1 | 2 | SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator 3 | 4 | TARGETED_DEVICE_FAMILY = 1,2,3,4 5 | 6 | LD_RUNPATH_SEARCH_PATHS = @executable_path/Frameworks @loader_path/Frameworks $(inherited) 7 | LD_RUNPATH_SEARCH_PATHS[sdk=macosx*] = @executable_path/../Frameworks @loader_path/../Frameworks $(inherited) 8 | SDKROOT = $(SDKROOT) 9 | 10 | //Carthage support 11 | //FRAMEWORK_SEARCH_PATHS[sdk=macosx*] = $(SRCROOT)/Carthage/Build/Mac/ $(inherited) 12 | //FRAMEWORK_SEARCH_PATHS[sdk=iphone*] = $(SRCROOT)/Carthage/Build/iOS/ $(inherited) 13 | //FRAMEWORK_SEARCH_PATHS[sdk=watch*] = $(SRCROOT)/Carthage/Build/watchOS/ $(inherited) 14 | //FRAMEWORK_SEARCH_PATHS[sdk=appletv*] = $(SRCROOT)/Carthage/Build/tvOS/ $(inherited) 15 | 16 | -------------------------------------------------------------------------------- /Frameworks/Universal/Assets/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSHumanReadableCopyright 22 | Copyright © 2017. Tibor Bodecs. All rights reserved. 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Frameworks/Universal/Console.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Frameworks/Universal/Console.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Frameworks/Universal/Sources/Console.h: -------------------------------------------------------------------------------- 1 | // 2 | // Console.h 3 | // Console 4 | // 5 | // Created by Tibor Bödecs on 2017. 10. 18.. 6 | // Copyright © 2017. Tibor Bodecs. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for Console. 12 | FOUNDATION_EXPORT double ConsoleVersionNumber; 13 | 14 | //! Project version string for Console. 15 | FOUNDATION_EXPORT const unsigned char ConsoleVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /Frameworks/Universal/Tests/Assets/Console-Tests.xcconfig: -------------------------------------------------------------------------------- 1 | 2 | SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator 3 | 4 | TARGETED_DEVICE_FAMILY = 1,2,3,4 5 | 6 | LD_RUNPATH_SEARCH_PATHS = @executable_path/Frameworks @loader_path/Frameworks $(inherited) 7 | LD_RUNPATH_SEARCH_PATHS[sdk=macosx*] = @executable_path/../Frameworks @loader_path/../Frameworks $(inherited) 8 | SDKROOT = $(SDKROOT) 9 | LD_DYLIB_INSTALL_NAME = @rpath 10 | 11 | CODE_SIGN_STYLE = Manual 12 | DEVELOPMENT_TEAM = 13 | 14 | //:configuration = Debug 15 | CODE_SIGN_IDENTITY = 16 | CODE_SIGN_STYLE = Manual 17 | DEVELOPMENT_TEAM = 18 | PROVISIONING_PROFILE_SPECIFIER = 19 | 20 | 21 | //Carthage support 22 | //FRAMEWORK_SEARCH_PATHS[sdk=macosx*] = $(SRCROOT)/Carthage/Build/Mac/ $(inherited) 23 | //FRAMEWORK_SEARCH_PATHS[sdk=iphone*] = $(SRCROOT)/Carthage/Build/iOS/ $(inherited) 24 | //FRAMEWORK_SEARCH_PATHS[sdk=watch*] = $(SRCROOT)/Carthage/Build/watchOS/ $(inherited) 25 | //FRAMEWORK_SEARCH_PATHS[sdk=appletv*] = $(SRCROOT)/Carthage/Build/tvOS/ $(inherited) 26 | 27 | -------------------------------------------------------------------------------- /Frameworks/Universal/Tests/Assets/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Frameworks/Universal/Tests/Sources/ConsoleTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ConsoleTests.swift 3 | // ConsoleTests 4 | // 5 | // Created by Tibor Bödecs on 2017. 10. 18.. 6 | // Copyright © 2017. Tibor Bodecs. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import Console 11 | 12 | 13 | class ConsoleTests: XCTestCase { 14 | 15 | func testExample() { 16 | Console.log("Hello World!") 17 | Console.log(Console.platform) 18 | 19 | #if os(iOS) 20 | XCTAssert(Console.platform == "iOS") 21 | #endif 22 | #if os(macOS) 23 | XCTAssert(Console.platform == "macOS") 24 | #endif 25 | #if os(tvOS) 26 | XCTAssert(Console.platform == "tvOS") 27 | #endif 28 | #if os(watchOS) 29 | XCTAssert(Console.platform == "watchOS") 30 | #endif 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Frameworks/Usage/Usage.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Frameworks/Usage/Usage.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Frameworks/Usage/Usage.xcodeproj/xcuserdata/tib.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Usage.xcscheme 8 | 9 | orderHint 10 | 4 11 | 12 | Usage.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 4 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Frameworks/Usage/Usage/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Usage 4 | // 5 | // Created by Tibor Bödecs on 2017. 10. 23.. 6 | // Copyright © 2017. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder { 13 | 14 | var window: UIWindow? 15 | } 16 | 17 | extension AppDelegate: UIApplicationDelegate { 18 | 19 | func application(_ application: UIApplication, 20 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { 21 | return true 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /Frameworks/Usage/Usage/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Usage 4 | // 5 | // Created by Tibor Bödecs on 2017. 10. 23.. 6 | // Copyright © 2017. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Console 11 | 12 | class ViewController: UIViewController { 13 | 14 | override func viewDidLoad() { 15 | super.viewDidLoad() 16 | 17 | Console.log("hello") 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2015-2019 Tibor Bodecs 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The.Swift.Dev - Tutorials 2 | 3 | This repository contains all the Swift 5 sample codes for [theswiftdev.com](https://theswiftdev.com). 4 | 5 | ### License 6 | 7 | [WTFPL](LICENSE) 8 | -------------------------------------------------------------------------------- /VIPER/ServicesAndVIPER/Application/Assets/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /VIPER/ServicesAndVIPER/Application/Sources/App/App.swift: -------------------------------------------------------------------------------- 1 | // 2 | // App.swift 3 | // ServicesAndVIPER 4 | // 5 | // Created by Tibor Bödecs on 2019. 09. 25.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | final class App { 12 | 13 | let services = ServiceBuilder() 14 | 15 | // MARK: - singleton 16 | 17 | static let shared = App() 18 | 19 | private init() { 20 | // do nothing... 21 | } 22 | 23 | // MARK: - api 24 | 25 | func setup() { 26 | self.services.setup() 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /VIPER/ServicesAndVIPER/Application/Sources/App/Controllers/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // ServicesAndVIPER 4 | // 5 | // Created by Tibor Bödecs on 2019. 09. 25.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | // do nothing... 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /VIPER/ServicesAndVIPER/Application/Sources/App/VIPER/ServiceInteractor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ServiceInteractor.swift 3 | // ServicesAndVIPER 4 | // 5 | // Created by Tibor Bödecs on 2019. 09. 25.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class ServiceInteractor { 12 | 13 | let services: ServiceBuilderInterface 14 | 15 | init(services: ServiceBuilderInterface = App.shared.services) { 16 | self.services = services 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /VIPER/ServicesAndVIPER/Application/Sources/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // ServicesAndVIPER 4 | // 5 | // Created by Tibor Bödecs on 2019. 09. 25.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder { 13 | 14 | } 15 | 16 | extension AppDelegate: UIApplicationDelegate { 17 | 18 | func application(_ application: UIApplication, 19 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 20 | 21 | App.shared.setup() 22 | 23 | return true 24 | } 25 | 26 | // MARK: UISceneSession Lifecycle 27 | 28 | func application(_ application: UIApplication, 29 | configurationForConnecting connectingSceneSession: UISceneSession, 30 | options: UIScene.ConnectionOptions) -> UISceneConfiguration { 31 | .init(name: "Default Configuration", sessionRole: connectingSceneSession.role) 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /VIPER/ServicesAndVIPER/Application/Sources/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.swift 3 | // ServicesAndVIPER 4 | // 5 | // Created by Tibor Bödecs on 2019. 09. 25.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SceneDelegate: UIResponder { 12 | 13 | var window: UIWindow? 14 | } 15 | 16 | extension SceneDelegate: UIWindowSceneDelegate { 17 | 18 | func scene(_ scene: UIScene, 19 | willConnectTo session: UISceneSession, 20 | options connectionOptions: UIScene.ConnectionOptions) { 21 | guard let _ = (scene as? UIWindowScene) else { 22 | return 23 | } 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /VIPER/ServicesAndVIPER/Application/Sources/Services/Api/ApiServiceInterface.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ApiServiceInterface.swift 3 | // ServicesAndVIPER 4 | // 5 | // Created by Tibor Bödecs on 2019. 09. 25.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Combine 11 | 12 | protocol ApiServiceInterface: ServiceInterface { 13 | 14 | func todos() -> AnyPublisher<[TodoObject], HTTP.Error> 15 | } 16 | -------------------------------------------------------------------------------- /VIPER/ServicesAndVIPER/Application/Sources/Services/Api/HTTP.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HTTP.swift 3 | // ServicesAndVIPER 4 | // 5 | // Created by Tibor Bödecs on 2019. 09. 25.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | enum HTTP { 12 | 13 | enum Method: String { 14 | case get 15 | //... 16 | } 17 | enum Error: LocalizedError { 18 | case invalidResponse 19 | case statusCode(Int) 20 | case unknown(Swift.Error) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /VIPER/ServicesAndVIPER/Application/Sources/Services/Api/Objects/TodoObject.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TodoObject.swift 3 | // ServicesAndVIPER 4 | // 5 | // Created by Tibor Bödecs on 2019. 09. 25.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct TodoObject: Codable { 12 | let id: Int 13 | let title: String 14 | let completed: Bool 15 | } 16 | -------------------------------------------------------------------------------- /VIPER/ServicesAndVIPER/Application/Sources/Services/ServiceBuilderInterface.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ServiceBuilderInterface.swift 3 | // ServicesAndVIPER 4 | // 5 | // Created by Tibor Bödecs on 2019. 09. 25.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol ServiceBuilderInterface { 12 | 13 | var api: ApiServiceInterface { get } 14 | 15 | func setup() 16 | } 17 | 18 | extension ServiceBuilderInterface { 19 | 20 | func setup() { 21 | self.api.setup() 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /VIPER/ServicesAndVIPER/Application/Sources/Services/ServiceInterface.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ServiceInterface.swift 3 | // ServicesAndVIPER 4 | // 5 | // Created by Tibor Bödecs on 2019. 09. 25.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol ServiceInterface: class { 12 | func setup() 13 | } 14 | 15 | extension ServiceInterface { 16 | 17 | func setup() { 18 | // do nothing... 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /VIPER/ServicesAndVIPER/Environments/Development/Sources/Services/ServiceBuilder.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ServiceBuilder.swift 3 | // ServicesAndVIPER 4 | // 5 | // Created by Tibor Bödecs on 2019. 09. 25.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | final class ServiceBuilder: ServiceBuilderInterface { 12 | 13 | lazy var api: ApiServiceInterface = { 14 | // this can be the url of the development server 15 | MyApiService(baseUrl: "https://jsonplaceholder.typicode.com") 16 | }() 17 | } 18 | -------------------------------------------------------------------------------- /VIPER/ServicesAndVIPER/Environments/Fake/Sources/ServiceBuilder.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ServiceBuilder.swift 3 | // ServicesAndVIPER 4 | // 5 | // Created by Tibor Bödecs on 2019. 09. 25.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | final class ServiceBuilder: ServiceBuilderInterface { 12 | 13 | lazy var api: ApiServiceInterface = { 14 | FakeApiService() 15 | }() 16 | } 17 | -------------------------------------------------------------------------------- /VIPER/ServicesAndVIPER/Environments/Production/Sources/Services/ServiceBuilder.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ServiceBuilder.swift 3 | // ServicesAndVIPER 4 | // 5 | // Created by Tibor Bödecs on 2019. 09. 25.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | final class ServiceBuilder: ServiceBuilderInterface { 12 | 13 | lazy var api: ApiServiceInterface = { 14 | // this can be the url of the production server 15 | MyApiService(baseUrl: "https://jsonplaceholder.typicode.com") 16 | }() 17 | } 18 | -------------------------------------------------------------------------------- /VIPER/ServicesAndVIPER/ServicesAndVIPER.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /VIPER/ServicesAndVIPER/ServicesAndVIPER.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /VIPER/ServicesAndVIPER/ServicesAndVIPER.xcodeproj/xcuserdata/tib.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | ServicesAndVIPER-Development.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 1 11 | 12 | ServicesAndVIPER-Fake.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 2 16 | 17 | ServicesAndVIPER.xcscheme_^#shared#^_ 18 | 19 | orderHint 20 | 0 21 | 22 | 23 | SuppressBuildableAutocreation 24 | 25 | 16D3AC1B233B996500CA56D2 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/.gitignore: -------------------------------------------------------------------------------- 1 | Pods 2 | Podfile.lock 3 | VIPER\ best\ practices.xcworkspace 4 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "object": { 3 | "pins": [ 4 | { 5 | "package": "CollectionView", 6 | "repositoryURL": "https://github.com/CoreKit/CollectionView", 7 | "state": { 8 | "branch": null, 9 | "revision": "b97073bd9281c36f087801e78102184a6f88b5dc", 10 | "version": "2.0.6" 11 | } 12 | }, 13 | { 14 | "package": "Promises", 15 | "repositoryURL": "https://github.com/CoreKit/Promises.git", 16 | "state": { 17 | "branch": null, 18 | "revision": "84ed35f719685820e587da9a56d9cbf253168539", 19 | "version": "1.0.2" 20 | } 21 | } 22 | ] 23 | }, 24 | "version": 1 25 | } 26 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices.xcodeproj/xcuserdata/tib.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices.xcodeproj/xcuserdata/tib.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | VIPER best practices.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Assets/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/App/App.swift: -------------------------------------------------------------------------------- 1 | // 2 | // App.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class App { 12 | 13 | static let shared = App() 14 | 15 | private init() { 16 | 17 | } 18 | 19 | var apiService: ApiService { 20 | return JSONPlaceholderService() 21 | } 22 | 23 | var bookmarkService: BookmarkService { 24 | return DefaultBookmarkService() 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/App/ViewModels/BookmarkViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PostBookmarkViewModel.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 06.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class BookmarkViewModel: ViewModel { 12 | 13 | override var height: CGFloat { 64 } 14 | 15 | override func updateView() { 16 | self.view?.textLabel.text = self.model.post.title 17 | self.view?.detailTextLabel.text = self.model.isBookmarked ? "👍" : "" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/App/ViewModels/CommentViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CommentViewModel.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 06.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class CommentViewModel: ViewModel { 12 | 13 | override var height: CGFloat { 64 } 14 | 15 | override func updateView() { 16 | self.view?.textLabel.text = self.model.body 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/App/Views/TextCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CommentCell.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 07.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class TextCell: Cell { 12 | 13 | @IBOutlet weak var textLabel: UILabel! 14 | 15 | } 16 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/App/Views/TextDetailCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PostCell.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 06.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class TextDetailCell: Cell { 12 | 13 | @IBOutlet weak var textLabel: UILabel! 14 | @IBOutlet weak var detailTextLabel: UILabel! 15 | } 16 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @_exported import Promises 12 | @_exported import CollectionView 13 | 14 | @UIApplicationMain 15 | class AppDelegate: UIResponder { 16 | 17 | var window: UIWindow? 18 | } 19 | 20 | extension AppDelegate: UIApplicationDelegate { 21 | 22 | func application(_ application: UIApplication, 23 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 24 | 25 | self.window = UIWindow(frame: UIScreen.main.bounds) 26 | self.window?.rootViewController = MainModule().buildDefault() 27 | self.window?.makeKeyAndVisible() 28 | 29 | return true 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Albums/AlbumsModule.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AlbumsDefaultBuilder.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class AlbumsModule { 12 | 13 | func buildDefault() -> UIViewController { 14 | let view = AlbumsDefaultView() 15 | let interactor = AlbumsDefaultInteractor() 16 | let presenter = AlbumsDefaultPresenter() 17 | let router = AlbumsDefaultRouter() 18 | 19 | view.presenter = presenter 20 | 21 | presenter.interactor = interactor 22 | presenter.view = view 23 | presenter.router = router 24 | 25 | interactor.presenter = presenter 26 | 27 | router.presenter = presenter 28 | router.viewController = view 29 | 30 | return view 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Albums/Implementations/Default/AlbumsDefaultInteractor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AlbumsDefaultInteractor.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | class AlbumsDefaultInteractor { 11 | 12 | weak var presenter: AlbumsPresenter? 13 | } 14 | 15 | extension AlbumsDefaultInteractor: AlbumsInteractor { 16 | 17 | 18 | } 19 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Albums/Implementations/Default/AlbumsDefaultPresenter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AlbumsDefaultPresenter.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | class AlbumsDefaultPresenter { 11 | 12 | var router: AlbumsRouter? 13 | var interactor: AlbumsInteractor? 14 | weak var view: AlbumsView? 15 | } 16 | 17 | extension AlbumsDefaultPresenter: AlbumsPresenter { 18 | 19 | } 20 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Albums/Implementations/Default/AlbumsDefaultRouter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AlbumsDefaultRouter.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class AlbumsDefaultRouter { 12 | 13 | weak var presenter: AlbumsPresenter? 14 | weak var viewController: UIViewController? 15 | } 16 | 17 | extension AlbumsDefaultRouter: AlbumsRouter { 18 | 19 | } 20 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Albums/Implementations/Default/AlbumsDefaultView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AlbumsDefaultView.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class AlbumsDefaultView: UIViewController { 12 | 13 | var presenter: AlbumsPresenter? 14 | 15 | init() { 16 | super.init(nibName: nil, bundle: nil) 17 | 18 | self.title = "Albums" 19 | } 20 | 21 | required init?(coder aDecoder: NSCoder) { 22 | fatalError("init(coder:) has not been implemented") 23 | } 24 | 25 | override func viewDidLoad() { 26 | super.viewDidLoad() 27 | 28 | self.view.backgroundColor = .blue 29 | } 30 | } 31 | 32 | extension AlbumsDefaultView: AlbumsView { 33 | 34 | } 35 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Albums/Interfaces/AlbumsInteractor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AlbumsInteractor.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol AlbumsInteractor { 11 | 12 | var presenter: AlbumsPresenter? { get set } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Albums/Interfaces/AlbumsPresenter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AlbumsPresenter.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol AlbumsPresenter: class { 11 | 12 | var router: AlbumsRouter? { get set } 13 | var interactor: AlbumsInteractor? { get set } 14 | var view: AlbumsView? { get set } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Albums/Interfaces/AlbumsRouter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AlbumsRouter.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol AlbumsRouter { 11 | 12 | var presenter: AlbumsPresenter? { get set } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Albums/Interfaces/AlbumsView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AlbumsView.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol AlbumsView: class { 11 | 12 | var presenter: AlbumsPresenter? { get set } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Home/HomeModule.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HomeDefaultBuilder.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class HomeModule { 12 | 13 | func buildDefault() -> UIViewController { 14 | let view = HomeDefaultView() 15 | let interactor = HomeDefaultInteractor() 16 | let presenter = HomeDefaultPresenter() 17 | let router = HomeDefaultRouter() 18 | 19 | view.presenter = presenter 20 | 21 | presenter.interactor = interactor 22 | presenter.view = view 23 | presenter.router = router 24 | 25 | interactor.presenter = presenter 26 | 27 | router.presenter = presenter 28 | router.viewController = view 29 | 30 | presenter.setupViewControllers() 31 | 32 | return view 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Home/Implementations/Default/HomeDefaultInteractor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HomeDefaultInteractor.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | class HomeDefaultInteractor { 11 | 12 | weak var presenter: HomePresenter? 13 | } 14 | 15 | extension HomeDefaultInteractor: HomeInteractor { 16 | 17 | 18 | } 19 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Home/Implementations/Default/HomeDefaultPresenter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HomeDefaultPresenter.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | class HomeDefaultPresenter { 11 | 12 | var router: HomeRouter? 13 | var interactor: HomeInteractor? 14 | weak var view: HomeView? 15 | } 16 | 17 | extension HomeDefaultPresenter: HomePresenter { 18 | 19 | func setupViewControllers() { 20 | guard let controllers = self.router?.getViewControllers() else { 21 | return 22 | } 23 | self.view?.display(controllers) 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Home/Implementations/Default/HomeDefaultRouter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HomeDefaultRouter.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class HomeDefaultRouter { 12 | 13 | weak var presenter: HomePresenter? 14 | weak var viewController: UIViewController? 15 | 16 | } 17 | 18 | extension HomeDefaultRouter: HomeRouter { 19 | 20 | func getViewControllers() -> [UIViewController] { 21 | return [ 22 | PostsModule().buildDefault(), 23 | AlbumsModule().buildDefault(), 24 | PhotosModule().buildDefault(), 25 | TodosModule().buildDefault(), 26 | ].map { UINavigationController(rootViewController: $0) } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Home/Implementations/Default/HomeDefaultView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HomeDefaultView.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class HomeDefaultView: UITabBarController { 12 | 13 | var presenter: HomePresenter? 14 | } 15 | 16 | extension HomeDefaultView: HomeView { 17 | 18 | func display(_ viewControllers: [UIViewController]) { 19 | self.viewControllers = viewControllers 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Home/Interfaces/HomeInteractor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HomeInteractor.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol HomeInteractor { 11 | 12 | var presenter: HomePresenter? { get set } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Home/Interfaces/HomePresenter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HomePresenter.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol HomePresenter: class { 11 | 12 | var router: HomeRouter? { get set } 13 | var interactor: HomeInteractor? { get set } 14 | var view: HomeView? { get set } 15 | 16 | func setupViewControllers() 17 | 18 | } 19 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Home/Interfaces/HomeRouter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HomeRouter.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | protocol HomeRouter { 12 | 13 | var presenter: HomePresenter? { get set } 14 | 15 | func getViewControllers() -> [UIViewController] 16 | } 17 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Home/Interfaces/HomeView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HomeView.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | protocol HomeView: class { 12 | 13 | var presenter: HomePresenter? { get set } 14 | 15 | func display(_ viewControllers: [UIViewController]) 16 | } 17 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Main/Implementations/Default/MainDefaultInteractor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MainDefaultInteractor.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | class MainDefaultInteractor { 11 | 12 | weak var presenter: MainPresenter? 13 | } 14 | 15 | extension MainDefaultInteractor: MainInteractor { 16 | 17 | 18 | } 19 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Main/Implementations/Default/MainDefaultPresenter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MainDefaultPresenter.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | class MainDefaultPresenter { 11 | 12 | var router: MainRouter? 13 | var interactor: MainInteractor? 14 | weak var view: MainView? 15 | } 16 | 17 | extension MainDefaultPresenter: MainPresenter { 18 | 19 | func viewDidAppear() { 20 | self.router?.showHome() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Main/Implementations/Default/MainDefaultRouter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MainDefaultRouter.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class MainDefaultRouter { 12 | 13 | weak var presenter: MainPresenter? 14 | weak var viewController: UIViewController? 15 | } 16 | 17 | extension MainDefaultRouter: MainRouter { 18 | 19 | func showHome() { 20 | let viewController = HomeModule().buildDefault() 21 | viewController.modalPresentationStyle = .fullScreen 22 | self.viewController?.present(viewController, animated: true, completion: nil) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Main/Implementations/Default/MainDefaultView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MainDefaultView.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class MainDefaultView: UIViewController { 12 | 13 | var presenter: MainPresenter? 14 | 15 | override func viewDidAppear(_ animated: Bool) { 16 | super.viewDidAppear(animated) 17 | 18 | self.presenter?.viewDidAppear() 19 | } 20 | } 21 | 22 | extension MainDefaultView: MainView { 23 | 24 | } 25 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Main/Interfaces/MainInteractor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MainInteractor.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol MainInteractor { 11 | 12 | var presenter: MainPresenter? { get set } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Main/Interfaces/MainPresenter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MainPresenter.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol MainPresenter: class { 11 | 12 | var router: MainRouter? { get set } 13 | var interactor: MainInteractor? { get set } 14 | var view: MainView? { get set } 15 | 16 | func viewDidAppear() 17 | } 18 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Main/Interfaces/MainRouter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MainRouter.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol MainRouter { 11 | 12 | var presenter: MainPresenter? { get set } 13 | 14 | func showHome() 15 | } 16 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Main/Interfaces/MainView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MainView.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol MainView: class { 11 | 12 | var presenter: MainPresenter? { get set } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Main/MainModule.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MainDefaultBuilder.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class MainModule { 12 | 13 | func buildDefault() -> UIViewController { 14 | let view = MainDefaultView() 15 | let interactor = MainDefaultInteractor() 16 | let presenter = MainDefaultPresenter() 17 | let router = MainDefaultRouter() 18 | 19 | view.presenter = presenter 20 | 21 | presenter.interactor = interactor 22 | presenter.view = view 23 | presenter.router = router 24 | 25 | interactor.presenter = presenter 26 | 27 | router.presenter = presenter 28 | router.viewController = view 29 | 30 | return view 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Photos/Implementations/Default/PhotosDefaultInteractor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotosDefaultInteractor.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | class PhotosDefaultInteractor { 11 | 12 | weak var presenter: PhotosPresenter? 13 | } 14 | 15 | extension PhotosDefaultInteractor: PhotosInteractor { 16 | 17 | 18 | } 19 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Photos/Implementations/Default/PhotosDefaultPresenter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotosDefaultPresenter.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | class PhotosDefaultPresenter { 11 | 12 | var router: PhotosRouter? 13 | var interactor: PhotosInteractor? 14 | weak var view: PhotosView? 15 | } 16 | 17 | extension PhotosDefaultPresenter: PhotosPresenter { 18 | 19 | } 20 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Photos/Implementations/Default/PhotosDefaultRouter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotosDefaultRouter.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class PhotosDefaultRouter { 12 | 13 | weak var presenter: PhotosPresenter? 14 | weak var viewController: UIViewController? 15 | } 16 | 17 | extension PhotosDefaultRouter: PhotosRouter { 18 | 19 | } 20 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Photos/Implementations/Default/PhotosDefaultView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotosDefaultView.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class PhotosDefaultView: UIViewController { 12 | 13 | var presenter: PhotosPresenter? 14 | 15 | init() { 16 | super.init(nibName: nil, bundle: nil) 17 | 18 | self.title = "Photos" 19 | } 20 | 21 | required init?(coder aDecoder: NSCoder) { 22 | fatalError("init(coder:) has not been implemented") 23 | } 24 | 25 | override func viewDidLoad() { 26 | super.viewDidLoad() 27 | 28 | self.view.backgroundColor = .red 29 | } 30 | } 31 | 32 | extension PhotosDefaultView: PhotosView { 33 | 34 | } 35 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Photos/Interfaces/PhotosInteractor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotosInteractor.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol PhotosInteractor { 11 | 12 | var presenter: PhotosPresenter? { get set } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Photos/Interfaces/PhotosPresenter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotosPresenter.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol PhotosPresenter: class { 11 | 12 | var router: PhotosRouter? { get set } 13 | var interactor: PhotosInteractor? { get set } 14 | var view: PhotosView? { get set } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Photos/Interfaces/PhotosRouter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotosRouter.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol PhotosRouter { 11 | 12 | var presenter: PhotosPresenter? { get set } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Photos/Interfaces/PhotosView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotosView.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol PhotosView: class { 11 | 12 | var presenter: PhotosPresenter? { get set } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Photos/PhotosModule.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotosDefaultBuilder.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class PhotosModule { 12 | 13 | func buildDefault() -> UIViewController { 14 | let view = PhotosDefaultView() 15 | let interactor = PhotosDefaultInteractor() 16 | let presenter = PhotosDefaultPresenter() 17 | let router = PhotosDefaultRouter() 18 | 19 | view.presenter = presenter 20 | 21 | presenter.interactor = interactor 22 | presenter.view = view 23 | presenter.router = router 24 | 25 | interactor.presenter = presenter 26 | 27 | router.presenter = presenter 28 | router.viewController = view 29 | 30 | return view 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/PostDetails/Implementations/Default/PostDetailsDefaultInteractor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PostDetailsDefaultInteractor.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 07.. 6 | // 7 | 8 | import Foundation 9 | 10 | class PostDetailsDefaultInteractor { 11 | 12 | weak var presenter: PostDetailsPresenter? 13 | 14 | let apiService: ApiService 15 | let bookmarkService: BookmarkService 16 | 17 | init(apiService: ApiService, bookmarkService: BookmarkService) { 18 | self.apiService = apiService 19 | self.bookmarkService = bookmarkService 20 | } 21 | } 22 | 23 | extension PostDetailsDefaultInteractor: PostDetailsInteractor { 24 | 25 | func comments(for post: Post) -> Promise<[Comment]> { 26 | return self.apiService.comments(for: post) 27 | } 28 | 29 | func bookmark(for post: Post) -> Bookmark { 30 | return self.bookmarkService.bookmark(for: post) 31 | } 32 | 33 | 34 | 35 | } 36 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/PostDetails/Implementations/Default/PostDetailsDefaultRouter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PostDetailsDefaultRouter.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 07.. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class PostDetailsDefaultRouter { 12 | 13 | weak var presenter: PostDetailsPresenter? 14 | weak var viewController: UIViewController? 15 | weak var delegate: PostDetailsModuleDelegate? 16 | } 17 | 18 | extension PostDetailsDefaultRouter: PostDetailsRouter { 19 | 20 | func toggleBookmark(for post: Post) { 21 | self.delegate?.toggleBookmark(for: post) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/PostDetails/Interfaces/PostDetailsInteractor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PostDetailsInteractor.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 07.. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol PostDetailsInteractor { 11 | 12 | var presenter: PostDetailsPresenter? { get set } 13 | 14 | func comments(for post: Post) -> Promise<[Comment]> 15 | 16 | func bookmark(for post: Post) -> Bookmark 17 | } 18 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/PostDetails/Interfaces/PostDetailsPresenter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PostDetailsPresenter.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 07.. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol PostDetailsPresenter: class { 11 | 12 | var router: PostDetailsRouter? { get set } 13 | var interactor: PostDetailsInteractor? { get set } 14 | var view: PostDetailsView? { get set } 15 | 16 | func reload() 17 | func toggleBookmark() 18 | } 19 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/PostDetails/Interfaces/PostDetailsRouter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PostDetailsRouter.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 07.. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol PostDetailsRouter { 11 | 12 | var presenter: PostDetailsPresenter? { get set } 13 | 14 | func toggleBookmark(for post: Post) 15 | } 16 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/PostDetails/Interfaces/PostDetailsView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PostDetailsView.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 07.. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol PostDetailsView: class { 11 | 12 | var presenter: PostDetailsPresenter? { get set } 13 | 14 | func setup(with bookmark: Bookmark) 15 | func display(_ comments: [Comment]) 16 | } 17 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Posts/Implementations/Default/PostsDefaultRouter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PostsDefaultRouter.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class PostsDefaultRouter { 12 | 13 | weak var presenter: PostsPresenter? 14 | weak var viewController: UIViewController? 15 | } 16 | 17 | extension PostsDefaultRouter: PostsRouter { 18 | 19 | func showComments(for post: Post) { 20 | let viewController = PostDetailsModule().buildDefault(with: post, delegate: self) 21 | self.viewController?.show(viewController, sender: nil) 22 | } 23 | } 24 | 25 | extension PostsDefaultRouter: PostDetailsModuleDelegate { 26 | 27 | func toggleBookmark(for post: Post) { 28 | self.presenter?.toggleBookmark(for: post) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Posts/Interfaces/PostsInteractor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PostsInteractor.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol PostsInteractor { 11 | 12 | var presenter: PostsPresenter? { get set } 13 | 14 | func posts() -> Promise<[Post]> 15 | 16 | func bookmark(for post: Post) -> Bookmark 17 | func isBookmarked(_ post: Post) -> Bool 18 | func toggleBookmark(_ post: Post) 19 | } 20 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Posts/Interfaces/PostsPresenter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PostsPresenter.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol PostsPresenter: class { 11 | 12 | var router: PostsRouter? { get set } 13 | var interactor: PostsInteractor? { get set } 14 | var view: PostsView? { get set } 15 | 16 | func reload() 17 | func didSelect(_ post: Post) 18 | func toggleBookmark(for post: Post) 19 | } 20 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Posts/Interfaces/PostsRouter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PostsRouter.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol PostsRouter { 11 | 12 | var presenter: PostsPresenter? { get set } 13 | 14 | func showComments(for post: Post) 15 | } 16 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Posts/Interfaces/PostsView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PostsView.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol PostsView: class { 11 | 12 | var presenter: PostsPresenter? { get set } 13 | 14 | func displayLoading() 15 | func display(_ bookmarks: [Bookmark]) 16 | func display(_ error: Error) 17 | 18 | 19 | } 20 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Posts/PostsModule.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PostsDefaultBuilder.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class PostsModule { 12 | 13 | func buildDefault() -> UIViewController { 14 | let view = PostsDefaultView() 15 | let interactor = PostsDefaultInteractor(apiService: App.shared.apiService, 16 | bookmarkService: App.shared.bookmarkService) 17 | let presenter = PostsDefaultPresenter() 18 | let router = PostsDefaultRouter() 19 | 20 | view.presenter = presenter 21 | 22 | presenter.interactor = interactor 23 | presenter.view = view 24 | presenter.router = router 25 | 26 | interactor.presenter = presenter 27 | 28 | router.presenter = presenter 29 | router.viewController = view 30 | 31 | return view 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Todos/Implementations/Default/TodosDefaultInteractor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TodosDefaultInteractor.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | class TodosDefaultInteractor { 11 | 12 | weak var presenter: TodosPresenter? 13 | } 14 | 15 | extension TodosDefaultInteractor: TodosInteractor { 16 | 17 | 18 | } 19 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Todos/Implementations/Default/TodosDefaultPresenter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TodosDefaultPresenter.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | class TodosDefaultPresenter { 11 | 12 | var router: TodosRouter? 13 | var interactor: TodosInteractor? 14 | weak var view: TodosView? 15 | } 16 | 17 | extension TodosDefaultPresenter: TodosPresenter { 18 | 19 | } 20 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Todos/Implementations/Default/TodosDefaultRouter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TodosDefaultRouter.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class TodosDefaultRouter { 12 | 13 | weak var presenter: TodosPresenter? 14 | weak var viewController: UIViewController? 15 | } 16 | 17 | extension TodosDefaultRouter: TodosRouter { 18 | 19 | } 20 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Todos/Implementations/Default/TodosDefaultView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TodosDefaultView.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class TodosDefaultView: UIViewController { 12 | 13 | var presenter: TodosPresenter? 14 | 15 | init() { 16 | super.init(nibName: nil, bundle: nil) 17 | 18 | self.title = "Todos" 19 | } 20 | 21 | required init?(coder aDecoder: NSCoder) { 22 | fatalError("init(coder:) has not been implemented") 23 | } 24 | 25 | override func viewDidLoad() { 26 | super.viewDidLoad() 27 | 28 | self.view.backgroundColor = .yellow 29 | } 30 | } 31 | 32 | extension TodosDefaultView: TodosView { 33 | 34 | } 35 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Todos/Implementations/Default/TodosModule.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TodosDefaultBuilder.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class TodosModule { 12 | 13 | func buildDefault() -> UIViewController { 14 | let view = TodosDefaultView() 15 | let interactor = TodosDefaultInteractor() 16 | let presenter = TodosDefaultPresenter() 17 | let router = TodosDefaultRouter() 18 | 19 | view.presenter = presenter 20 | 21 | presenter.interactor = interactor 22 | presenter.view = view 23 | presenter.router = router 24 | 25 | interactor.presenter = presenter 26 | 27 | router.presenter = presenter 28 | router.viewController = view 29 | 30 | return view 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Todos/Interfaces/TodosInteractor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TodosInteractor.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol TodosInteractor { 11 | 12 | var presenter: TodosPresenter? { get set } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Todos/Interfaces/TodosPresenter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TodosPresenter.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol TodosPresenter: class { 11 | 12 | var router: TodosRouter? { get set } 13 | var interactor: TodosInteractor? { get set } 14 | var view: TodosView? { get set } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Todos/Interfaces/TodosRouter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TodosRouter.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol TodosRouter { 11 | 12 | var presenter: TodosPresenter? { get set } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Modules/Todos/Interfaces/TodosView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TodosView.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol TodosView: class { 11 | 12 | var presenter: TodosPresenter? { get set } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Services/Api/ApiService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Api.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol ApiService { 12 | 13 | func posts() -> Promise<[Post]> 14 | func comments(for post: Post) -> Promise<[Comment]> 15 | func albums() -> Promise<[Album]> 16 | func photos(for album: Album) -> Promise<[Photo]> 17 | func todos() -> Promise<[Todo]> 18 | } 19 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Services/Api/Entities/Album.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Album.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Album: Codable { 12 | 13 | let id: Int 14 | let title: String 15 | } 16 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Services/Api/Entities/Comment.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Comment.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Comment: Codable { 12 | let id: Int 13 | let name: String 14 | let email: String 15 | let body: String 16 | } 17 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Services/Api/Entities/Photo.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Photo.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Photo: Codable { 12 | 13 | let id: Int 14 | let title: String 15 | let url: String 16 | let thumbnailUrl: String 17 | } 18 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Services/Api/Entities/Post.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Post.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Post: Codable { 12 | 13 | let id: Int 14 | let title: String 15 | let body: String 16 | } 17 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Services/Api/Entities/Todo.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Todo.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Todo: Codable { 12 | 13 | let id: Int 14 | let title: String 15 | let completed: Bool 16 | } 17 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Services/Api/Implementations/Mock/MockService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MockService.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 05.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class MockService { 12 | 13 | } 14 | 15 | extension MockService: ApiService { 16 | func posts() -> Promise<[Post]> { 17 | return Promise<[Post]>() 18 | } 19 | 20 | func comments(for post: Post) -> Promise<[Comment]> { 21 | return Promise<[Comment]>() 22 | } 23 | 24 | func albums() -> Promise<[Album]> { 25 | return Promise<[Album]>() 26 | } 27 | 28 | func photos(for album: Album) -> Promise<[Photo]> { 29 | return Promise<[Photo]>() 30 | } 31 | 32 | func todos() -> Promise<[Todo]> { 33 | return Promise<[Todo]>() 34 | } 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Services/Bookmark/BookmarkService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Bookmark.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 08.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol BookmarkService { 12 | 13 | func bookmark(for post: Post) -> Bookmark 14 | func isBookmarked(_ post: Post) -> Bool 15 | func toggleBookmark(for post: Post) 16 | 17 | } 18 | -------------------------------------------------------------------------------- /VIPER/VIPER best practices/VIPER best practices/Sources/Services/Bookmark/Entities/Bookmark.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PostBookmark.swift 3 | // VIPER best practices 4 | // 5 | // Created by Tibor Bödecs on 2019. 03. 08.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Bookmark { 12 | 13 | let post: Post 14 | let isBookmarked: Bool 15 | 16 | init(post: Post, isBookmarked: Bool) { 17 | self.post = post 18 | self.isBookmarked = isBookmarked 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /VIPER/VIPERAndSwiftUI/VIPERAndSwiftUI.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /VIPER/VIPERAndSwiftUI/VIPERAndSwiftUI.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /VIPER/VIPERAndSwiftUI/VIPERAndSwiftUI.xcodeproj/project.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/VIPER/VIPERAndSwiftUI/VIPERAndSwiftUI.xcodeproj/project.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /VIPER/VIPERAndSwiftUI/VIPERAndSwiftUI.xcodeproj/xcuserdata/tib.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 9 | 14 | 15 | 16 | 18 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /VIPER/VIPERAndSwiftUI/VIPERAndSwiftUI.xcodeproj/xcuserdata/tib.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | VIPERAndSwiftUI.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /VIPER/VIPERAndSwiftUI/VIPERAndSwiftUI/Assets/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /VIPER/VIPERAndSwiftUI/VIPERAndSwiftUI/Assets/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /VIPER/VIPERAndSwiftUI/VIPERAndSwiftUI/Sources/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // VIPERAndSwiftUI 4 | // 5 | // Created by Tibor Bödecs on 2019. 09. 12.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | func application(_ application: UIApplication, 15 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 16 | return true 17 | } 18 | 19 | // MARK: UISceneSession Lifecycle 20 | 21 | func application(_ application: UIApplication, 22 | configurationForConnecting connectingSceneSession: UISceneSession, 23 | options: UIScene.ConnectionOptions) -> UISceneConfiguration { 24 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /VIPER/VIPERAndSwiftUI/VIPERAndSwiftUI/Sources/HTTP.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HTTP.swift 3 | // VIPERAndSwiftUI 4 | // 5 | // Created by Tibor Bödecs on 2019. 09. 14.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct HTTP { 12 | 13 | enum Method: String { 14 | case get 15 | case post 16 | case put 17 | case delete 18 | case patch 19 | } 20 | 21 | enum Error: LocalizedError { 22 | case unknown(Swift.Error) 23 | case invalidResponse 24 | case statusCode(Int) 25 | case invalidData 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /VIPER/VIPERAndSwiftUI/VIPERAndSwiftUI/Sources/Modules/Todo/TodoEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TaskEntity.swift 3 | // VIPERAndSwiftUI 4 | // 5 | // Created by Tibor Bödecs on 2019. 09. 12.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import SwiftUI 11 | 12 | struct TodoEntity: EntityInterface, Codable, Identifiable { 13 | let id: Int 14 | let title: String 15 | let completed: Bool 16 | } 17 | -------------------------------------------------------------------------------- /VIPER/VIPERAndSwiftUI/VIPERAndSwiftUI/Sources/Modules/Todo/TodoEnvironment.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TodoEnvironment.swift 3 | // VIPERAndSwiftUI 4 | // 5 | // Created by Tibor Bödecs on 2019. 09. 13.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Combine 11 | 12 | final class TodoEnvironment: ObservableObject { 13 | 14 | let objectWillChange = ObservableObjectPublisher() 15 | 16 | @Published var title: String = "Todo list" { 17 | willSet { 18 | self.objectWillChange.send() 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /VIPER/VIPERAndSwiftUI/VIPERAndSwiftUI/Sources/Modules/Todo/TodoListItemView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TodoListItemView.swift 3 | // VIPERAndSwiftUI 4 | // 5 | // Created by Tibor Bödecs on 2019. 09. 13.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import SwiftUI 11 | 12 | struct TodoListItemView: View { 13 | 14 | @EnvironmentObject var env: TodoEnvironment 15 | 16 | let todo: TodoEntity 17 | 18 | var body: some View { 19 | VStack(alignment: .leading) { 20 | Text(self.todo.title).font(.headline) 21 | if self.todo.completed { 22 | Text("Completed") 23 | .foregroundColor(.green) 24 | } 25 | else { 26 | Text("NOT Completed").font(.body) 27 | .foregroundColor(.red) 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /VIPER/VIPERAndSwiftUI/VIPERAndSwiftUI/Sources/Modules/Todo/TodoRouter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TaskRouter.swift 3 | // VIPERAndSwiftUI 4 | // 5 | // Created by Tibor Bödecs on 2019. 09. 12.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | final class TodoRouter: RouterInterface { 13 | 14 | weak var presenter: TodoPresenterRouterInterface! 15 | 16 | weak var viewController: UIViewController? 17 | } 18 | 19 | extension TodoRouter: TodoRouterPresenterInterface { 20 | 21 | } 22 | -------------------------------------------------------------------------------- /VIPER/VIPERAndSwiftUI/VIPERAndSwiftUI/Sources/Modules/Todo/TodoViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TaskView.swift 3 | // VIPERAndSwiftUI 4 | // 5 | // Created by Tibor Bödecs on 2019. 09. 12.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Combine 10 | import SwiftUI 11 | 12 | final class TodoViewModel: ObservableObject { 13 | 14 | let objectWillChange = ObservableObjectPublisher() 15 | 16 | @Published var error: Bool = false { 17 | willSet { 18 | self.objectWillChange.send() 19 | } 20 | } 21 | 22 | @Published var todos: [TodoEntity] = [] { 23 | willSet { 24 | self.objectWillChange.send() 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /VIPER/VIPERAndSwiftUI/VIPERAndSwiftUI/Sources/Publisher+On.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Publisher+On.swift 3 | // VIPERAndSwiftUI 4 | // 5 | // Created by Tibor Bödecs on 2019. 09. 16.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Combine 11 | 12 | public extension Publisher { 13 | 14 | func on(queue: DispatchQueue) -> Publishers.ReceiveOn { 15 | self.receive(on: queue, options: nil) 16 | } 17 | 18 | func on(success: @escaping ((Self.Output) -> Void), 19 | failure: @escaping ((Self.Failure) -> Void)) -> AnyCancellable { 20 | self.sink(receiveCompletion: { completion in 21 | switch completion { 22 | case .failure(let error): 23 | failure(error) 24 | case .finished: 25 | break 26 | } 27 | }, receiveValue: success) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /VIPER/VIPERAndSwiftUI/VIPERAndSwiftUI/Sources/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.swift 3 | // VIPERAndSwiftUI 4 | // 5 | // Created by Tibor Bödecs on 2019. 09. 12.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SwiftUI 11 | 12 | class SceneDelegate: UIResponder { 13 | 14 | var window: UIWindow? 15 | } 16 | 17 | extension SceneDelegate: UIWindowSceneDelegate { 18 | 19 | func scene(_ scene: UIScene, 20 | willConnectTo session: UISceneSession, 21 | options connectionOptions: UIScene.ConnectionOptions) { 22 | 23 | 24 | guard let windowScene = scene as? UIWindowScene else { 25 | return 26 | } 27 | let window = UIWindow(windowScene: windowScene) 28 | self.window = window 29 | window.rootViewController = TodoModule().build() 30 | window.makeKeyAndVisible() 31 | } 32 | 33 | } 34 | 35 | -------------------------------------------------------------------------------- /iOS/Auto Layout/AutoLayout - Anchors/AutoLayout - Anchors.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /iOS/Auto Layout/AutoLayout - Anchors/AutoLayout - Anchors.xcodeproj/project.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/Auto Layout/AutoLayout - Anchors/AutoLayout - Anchors.xcodeproj/project.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /iOS/Auto Layout/AutoLayout - Anchors/AutoLayout - Anchors.xcodeproj/xcuserdata/tib.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | AutoLayout - Anchors.xcscheme 8 | 9 | orderHint 10 | 1 11 | 12 | AutoLayout - Anchors.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /iOS/Auto Layout/AutoLayout - Anchors/AutoLayout - Anchors/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // AutoLayout - Anchors 4 | // 5 | // Created by Tibor Bödecs on 2017. 10. 31.. 6 | // Copyright © 2017. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder { 13 | 14 | var window: UIWindow? 15 | 16 | } 17 | 18 | extension AppDelegate: UIApplicationDelegate { 19 | 20 | func application(_ application: UIApplication, 21 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 22 | return true 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /iOS/Auto Layout/AutoLayout - Constraints/AutoLayout - Constraints.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /iOS/Auto Layout/AutoLayout - Constraints/AutoLayout - Constraints.xcodeproj/project.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/Auto Layout/AutoLayout - Constraints/AutoLayout - Constraints.xcodeproj/project.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /iOS/Auto Layout/AutoLayout - Constraints/AutoLayout - Constraints.xcodeproj/xcuserdata/tib.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | AutoLayout - Constraints.xcscheme 8 | 9 | orderHint 10 | 2 11 | 12 | AutoLayout - Constraints.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 3 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /iOS/Auto Layout/AutoLayout - Constraints/AutoLayout - Constraints/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // AutoLayout - Constraints 4 | // 5 | // Created by Tibor Bödecs on 2017. 10. 31.. 6 | // Copyright © 2017. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder { 13 | 14 | var window: UIWindow? 15 | 16 | } 17 | 18 | extension AppDelegate: UIApplicationDelegate { 19 | 20 | func application(_ application: UIApplication, 21 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 22 | return true 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /iOS/Auto Layout/AutoLayout - VFL/AutoLayout - VFL.xcodeproj/xcuserdata/tib.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | AutoLayout - VFL.xcscheme 8 | 9 | orderHint 10 | 3 11 | 12 | AutoLayout - VFL.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 4 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /iOS/Auto Layout/AutoLayout - VFL/AutoLayout - VFL/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // AutoLayout - VFL 4 | // 5 | // Created by Tibor Bödecs on 2017. 10. 31.. 6 | // Copyright © 2017. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder { 13 | 14 | var window: UIWindow? 15 | 16 | } 17 | 18 | extension AppDelegate: UIApplicationDelegate { 19 | 20 | func application(_ application: UIApplication, 21 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 22 | return true 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /iOS/Auto Layout/AutoLayout.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 12 | 13 | 15 | 16 | 18 | 19 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /iOS/Auto Layout/AutoLayout.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /iOS/Auto Layout/AutoLayout.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/Auto Layout/AutoLayout.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /iOS/Auto Layout/Layers - Circle/Layers - Circle.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /iOS/Auto Layout/Layers - Circle/Layers - Circle.xcodeproj/project.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/Auto Layout/Layers - Circle/Layers - Circle.xcodeproj/project.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /iOS/Auto Layout/Layers - Circle/Layers - Circle.xcodeproj/xcuserdata/tib.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Layers - Circle.xcscheme 8 | 9 | orderHint 10 | 5 11 | 12 | Layers - Circle.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 1 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /iOS/Auto Layout/Layers - Circle/Layers - Circle/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Layers - Circle 4 | // 5 | // Created by Tibor Bödecs on 2017. 10. 31.. 6 | // Copyright © 2017. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder { 13 | 14 | var window: UIWindow? 15 | 16 | } 17 | 18 | extension AppDelegate: UIApplicationDelegate { 19 | 20 | func application(_ application: UIApplication, 21 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 22 | return true 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /iOS/Auto Layout/Layers - Circle/Layers - Circle/CircularImageView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CircularImageView.swift 3 | // Layers - Circle 4 | // 5 | // Created by Tibor Bödecs on 2017. 10. 31.. 6 | // Copyright © 2017. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class CircularImageView: UIImageView { 12 | 13 | override var bounds: CGRect { 14 | didSet { 15 | self.layer.cornerRadius = round(self.bounds.size.width / 2.0) 16 | } 17 | } 18 | 19 | override init(frame: CGRect) { 20 | super.init(frame: frame) 21 | 22 | self.initialize() 23 | } 24 | 25 | required init?(coder aDecoder: NSCoder) { 26 | super.init(coder: aDecoder) 27 | 28 | self.initialize() 29 | } 30 | 31 | func initialize() { 32 | self.backgroundColor = .yellow 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /iOS/Auto Layout/Layers - Gradient/Layers - Gradient.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /iOS/Auto Layout/Layers - Gradient/Layers - Gradient.xcodeproj/project.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/Auto Layout/Layers - Gradient/Layers - Gradient.xcodeproj/project.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /iOS/Auto Layout/Layers - Gradient/Layers - Gradient.xcodeproj/xcuserdata/tib.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Layers - Gradient.xcscheme 8 | 9 | orderHint 10 | 4 11 | 12 | Layers - Gradient.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 2 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /iOS/Auto Layout/Layers - Gradient/Layers - Gradient/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Layers - Gradient 4 | // 5 | // Created by Tibor Bödecs on 2017. 10. 31.. 6 | // Copyright © 2017. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder { 13 | 14 | var window: UIWindow? 15 | 16 | } 17 | 18 | extension AppDelegate: UIApplicationDelegate { 19 | 20 | func application(_ application: UIApplication, 21 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 22 | return true 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /iOS/Auto Layout/SpringsAndStruts/SpringsAndStruts.xcodeproj/xcuserdata/tib.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SpringsAndStruts.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | SpringsAndStruts.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 5 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /iOS/Auto Layout/SpringsAndStruts/SpringsAndStruts/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SpringsAndStruts 4 | // 5 | // Created by Tibor Bödecs on 2017. 10. 31.. 6 | // Copyright © 2017. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder { 13 | 14 | var window: UIWindow? 15 | 16 | } 17 | 18 | extension AppDelegate: UIApplicationDelegate { 19 | 20 | func application(_ application: UIApplication, 21 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 22 | return true 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /iOS/Auto Layout/SpringsAndStruts/SpringsAndStruts/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // SpringsAndStruts 4 | // 5 | // Created by Tibor Bödecs on 2017. 10. 31.. 6 | // Copyright © 2017. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | weak var square: UIView! 14 | 15 | var squareFrame: CGRect { 16 | let midX = self.view.bounds.midX 17 | let midY = self.view.bounds.midY 18 | let size: CGFloat = 64 19 | return CGRect(x: midX-size/2, y: midY-size/2, width: size, height: size) 20 | } 21 | 22 | override func loadView() { 23 | super.loadView() 24 | 25 | let square = UIView() 26 | self.view.addSubview(square) 27 | self.square = square 28 | } 29 | 30 | override func viewDidLoad() { 31 | super.viewDidLoad() 32 | 33 | self.square.backgroundColor = .yellow 34 | } 35 | 36 | override func viewDidLayoutSubviews() { 37 | super.viewDidLayoutSubviews() 38 | 39 | self.square.frame = self.squareFrame 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "object": { 3 | "pins": [ 4 | { 5 | "package": "CollectionView", 6 | "repositoryURL": "https://github.com/corekit/collectionview", 7 | "state": { 8 | "branch": null, 9 | "revision": "a8acb6b5a643a1bb9746b23100ad22c7e69e5108", 10 | "version": "2.0.5" 11 | } 12 | } 13 | ] 14 | }, 15 | "version": 1 16 | } 17 | -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample.xcodeproj/project.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/CollectionView/Best Practice/CollectionViewExample.xcodeproj/project.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample.xcodeproj/xcuserdata/tib.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | CollectionView.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | CollectionView.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 0 16 | 17 | CollectionViewExample.xcscheme_^#shared#^_ 18 | 19 | orderHint 20 | 0 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // CollectionViewExample 4 | // 5 | // Created by Tibor Bödecs on 2018. 04. 16.. 6 | // Copyright © 2018. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | @_exported import CollectionView 11 | 12 | @UIApplicationMain 13 | class AppDelegate: UIResponder { 14 | 15 | var window: UIWindow? 16 | 17 | } 18 | 19 | extension AppDelegate: UIApplicationDelegate { 20 | 21 | func application(_ application: UIApplication, 22 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 23 | return true 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/01.imageset/ABR.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/01.imageset/ABR.jpg -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/01.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "ABR.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/02.imageset/BOS.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/02.imageset/BOS.jpg -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/02.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "BOS.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/03.imageset/C.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/03.imageset/C.jpg -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/03.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "C.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/04.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "MTS.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/04.imageset/MTS.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/04.imageset/MTS.jpg -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/05.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "PWD.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/05.imageset/PWD.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/05.imageset/PWD.jpg -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/06.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "TH.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/06.imageset/TH.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/06.imageset/TH.jpg -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/07.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "UABB.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/07.imageset/UABB.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/07.imageset/UABB.jpg -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/08.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "W.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/08.imageset/W.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/08.imageset/W.jpg -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/a01.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "a01.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/a01.imageset/a01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/a01.imageset/a01.png -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/a02.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "a02.jpeg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/a02.imageset/a02.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/a02.imageset/a02.jpeg -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/a03.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "a03.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/a03.imageset/a03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/a03.imageset/a03.png -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/a04.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "a04.jpeg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/a04.imageset/a04.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/a04.imageset/a04.jpeg -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/a05.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "a05.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/a05.imageset/a05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/a05.imageset/a05.jpg -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/a06.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "a06.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/a06.imageset/a06.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/a06.imageset/a06.jpg -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/a07.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "a07.jpeg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/a07.imageset/a07.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/a07.imageset/a07.jpeg -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/a08.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "a08.jpeg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/a08.imageset/a08.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/CollectionView/Best Practice/CollectionViewExample/Assets.xcassets/a08.imageset/a08.jpeg -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Components/Album/AlbumModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AlbumModel.swift 3 | // CollectionViewExample 4 | // 5 | // Created by Tibor Bödecs on 2019. 08. 24.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct AlbumModel { 12 | let artist: String 13 | let name: String 14 | let image: String 15 | } 16 | -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Components/Artist/ArtistModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ArtistModel.swift 3 | // CollectionViewExample 4 | // 5 | // Created by Tibor Bödecs on 2019. 08. 24.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct ArtistModel { 12 | let name: String 13 | let image: String 14 | } 15 | 16 | -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Components/Collection/CollectionCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CollectionCell.swift 3 | // CollectionViewExample 4 | // 5 | // Created by Tibor Bödecs on 2018. 04. 13.. 6 | // Copyright © 2018. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class CollectionCell: Cell { 12 | 13 | @IBOutlet weak var collectionView: CollectionView! 14 | 15 | open var source: Source? = nil { 16 | didSet { 17 | self.collectionView.source = self.source 18 | self.collectionView.reloadData() 19 | } 20 | } 21 | 22 | 23 | override func awakeFromNib() { 24 | super.awakeFromNib() 25 | 26 | self.collectionView.showsHorizontalScrollIndicator = false 27 | } 28 | 29 | override func reset() { 30 | super.reset() 31 | 32 | self.source = nil 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Components/Collection/CollectionModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CollectionModel.swift 3 | // CollectionViewExample 4 | // 5 | // Created by Tibor Bödecs on 2019. 08. 24.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct CollectionModel { 12 | let source: Source 13 | } 14 | -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Components/Collection/CollectionViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CollectionViewModel.swift 3 | // CollectionViewExample 4 | // 5 | // Created by Tibor Bödecs on 2019. 08. 24.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class CollectionViewModel: ViewModel { 12 | 13 | override func updateView() { 14 | self.view?.source = self.model.source 15 | } 16 | 17 | override func size(grid: Grid) -> CGSize { 18 | grid.size(for: self.collectionView, height: 180, items: grid.columns) 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Components/Header/HeaderCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HeaderCell.swift 3 | // CollectionViewExample 4 | // 5 | // Created by Tibor Bödecs on 2018. 04. 13.. 6 | // Copyright © 2018. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class HeaderCell: Cell { 12 | 13 | @IBOutlet weak var textLabel: UILabel! 14 | 15 | override func awakeFromNib() { 16 | super.awakeFromNib() 17 | 18 | self.textLabel.font = UIFont.systemFont(ofSize: 28, weight: .bold) 19 | self.textLabel.textColor = .black 20 | } 21 | 22 | override func reset() { 23 | super.reset() 24 | 25 | self.textLabel.text = nil 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Components/Header/HeaderModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HeaderModel.swift 3 | // CollectionViewExample 4 | // 5 | // Created by Tibor Bödecs on 2019. 08. 24.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct HeaderModel { 12 | let title: String 13 | } 14 | -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Components/Header/HeaderViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HeaderViewModel.swift 3 | // CollectionViewExample 4 | // 5 | // Created by Tibor Bödecs on 2019. 08. 24.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class HeaderViewModel: ViewModel { 12 | 13 | override var height: CGFloat { 14 | 64 15 | } 16 | 17 | override func updateView() { 18 | self.view?.textLabel.text = self.model.title 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Components/Separator/SeparatorCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SeparatorCell.swift 3 | // CollectionViewExample 4 | // 5 | // Created by Tibor Bödecs on 2018. 04. 13.. 6 | // Copyright © 2018. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SeparatorCell: Cell { 12 | 13 | override func awakeFromNib() { 14 | super.awakeFromNib() 15 | } 16 | 17 | override func reset() { 18 | super.reset() 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Components/Separator/SeparatorModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SeparatorModel.swift 3 | // CollectionViewExample 4 | // 5 | // Created by Tibor Bödecs on 2019. 08. 24.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | struct SeparatorModel { 13 | let height: CGFloat = 1 14 | let color: UIColor = UIColor(white: 0.95, alpha: 1.0) 15 | } 16 | -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Components/Separator/SeparatorViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SeparatorViewModel.swift 3 | // CollectionViewExample 4 | // 5 | // Created by Tibor Bödecs on 2019. 08. 24.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SeparatorViewModel: ViewModel { 12 | 13 | override var height: CGFloat { 14 | 44 15 | } 16 | 17 | override func updateView() { 18 | self.view?.contentView.backgroundColor = self.model.color 19 | } 20 | 21 | override func size(grid: Grid) -> CGSize { 22 | grid.size(for: self.collectionView, height: self.model.height, items: grid.columns) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Components/Song/SongModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SongModel.swift 3 | // CollectionViewExample 4 | // 5 | // Created by Tibor Bödecs on 2019. 08. 24.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct SongModel { 12 | let name: String 13 | let duration: String 14 | } 15 | 16 | -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Components/Song/SongViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SongViewModel.swift 3 | // CollectionViewExample 4 | // 5 | // Created by Tibor Bödecs on 2019. 08. 24.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SongViewModel: ViewModel { 12 | 13 | // override var height: CGFloat { 14 | // return 44 15 | // } 16 | 17 | override func updateView() { 18 | self.view?.numberLabel.text = String(self.indexPath.row + 1) 19 | self.view?.textLabel.text = self.model.name 20 | self.view?.detailTextLabel.text = self.model.duration 21 | } 22 | 23 | override func size(grid: Grid) -> CGSize { 24 | grid.size(for: self.collectionView, height: 44, items: grid.columns) 25 | } 26 | 27 | } 28 | 29 | -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Components/Text/TextCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TextCell.swift 3 | // CollectionViewExample 4 | // 5 | // Created by Tibor Bödecs on 2018. 04. 13.. 6 | // Copyright © 2018. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class TextCell: Cell { 12 | 13 | @IBOutlet weak var textLabel: UILabel! 14 | 15 | override func awakeFromNib() { 16 | super.awakeFromNib() 17 | 18 | self.textLabel.font = UIFont.systemFont(ofSize: 12, weight: .bold) 19 | self.textLabel.textColor = .black 20 | self.textLabel.numberOfLines = 0 21 | } 22 | 23 | override func reset() { 24 | super.reset() 25 | 26 | self.textLabel.text = nil 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Components/Text/TextModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TextModel.swift 3 | // CollectionViewExample 4 | // 5 | // Created by Tibor Bödecs on 2019. 08. 24.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct TextModel { 12 | let content: String 13 | } 14 | -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Components/Text/TextViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TextViewModel.swift 3 | // CollectionViewExample 4 | // 5 | // Created by Tibor Bödecs on 2019. 08. 24.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class TextViewModel: ViewModel { 12 | 13 | override var height: CGFloat { 14 | 44 15 | } 16 | 17 | override func updateView() { 18 | self.view?.textLabel.text = self.model.content 19 | } 20 | 21 | } 22 | 23 | class DynamicTextViewModel: TextViewModel { 24 | 25 | override func size(grid: Grid) -> CGSize { 26 | // note: cell has 8pt paddings on every side, that's why the +-16... 27 | let width = grid.width(for: self.collectionView) - 16 28 | let font = UIFont.systemFont(ofSize: 12, weight: .bold) 29 | let height = UILabel.height(forWidth: width - 16, font: font, text: self.model.content) 30 | return .init(width: width, height: height + 16) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /iOS/CollectionView/Best Practice/CollectionViewExample/Extensions/UILabel+Height.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UILabel+Height.swift 3 | // CollectionViewExample 4 | // 5 | // Created by Tibor Bödecs on 2019. 08. 24.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public extension UILabel { 12 | 13 | class func height(forWidth width: CGFloat, font: UIFont, text: String) -> CGFloat { 14 | let size = CGSize(width: width, height: .greatestFiniteMagnitude) 15 | let label = UILabel(frame: CGRect(origin: .zero, size: size)) 16 | label.numberOfLines = 0 17 | label.lineBreakMode = .byWordWrapping 18 | label.font = font 19 | label.text = text 20 | label.sizeToFit() 21 | return label.frame.height 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /iOS/CollectionView/Circular Cells/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | build 3 | .build 4 | 5 | -------------------------------------------------------------------------------- /iOS/CollectionView/Circular Cells/CircularCells.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /iOS/CollectionView/Circular Cells/CircularCells.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /iOS/CollectionView/Circular Cells/CircularCells.xcodeproj/project.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/CollectionView/Circular Cells/CircularCells.xcodeproj/project.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /iOS/CollectionView/Circular Cells/CircularCells.xcodeproj/xcuserdata/tib.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | CircularCells.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | Example.xcscheme 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | 1686BA4F201872500078911E 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /iOS/CollectionView/Circular Cells/CircularCells/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // CircularCells 4 | // 5 | // Created by Tibor Bödecs on 2018. 01. 24.. 6 | // Copyright © 2018. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder { 13 | 14 | var window: UIWindow? 15 | } 16 | 17 | extension AppDelegate: UIApplicationDelegate { 18 | 19 | func application(_ application: UIApplication, 20 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 21 | return true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /iOS/CollectionView/Circular Cells/CircularCells/Cell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Cell.swift 3 | // CircularCells 4 | // 5 | // Created by Tibor Bödecs on 2018. 01. 24.. 6 | // Copyright © 2018. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class Cell: UICollectionViewCell { 12 | 13 | @IBOutlet weak var imageView: UIImageView! 14 | 15 | override var bounds: CGRect { 16 | didSet { 17 | self.layoutIfNeeded() 18 | } 19 | } 20 | 21 | override func awakeFromNib() { 22 | super.awakeFromNib() 23 | 24 | self.imageView.layer.masksToBounds = true 25 | } 26 | 27 | override func layoutSubviews() { 28 | super.layoutSubviews() 29 | 30 | self.setCircularImageView() 31 | } 32 | 33 | func setCircularImageView() { 34 | self.imageView.layer.cornerRadius = CGFloat(roundf(Float(self.imageView.frame.size.width / 2.0))) 35 | } 36 | 37 | } 38 | 39 | -------------------------------------------------------------------------------- /iOS/CollectionView/Circular Cells/CircularCells/Example.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/CollectionView/Circular Cells/CircularCells/Example.jpg -------------------------------------------------------------------------------- /iOS/CollectionView/IB/CollectionView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /iOS/CollectionView/IB/CollectionView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /iOS/CollectionView/IB/CollectionView.xcodeproj/project.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/CollectionView/IB/CollectionView.xcodeproj/project.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /iOS/CollectionView/IB/CollectionView.xcodeproj/xcuserdata/tib.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | CollectionView.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | CollectionView.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /iOS/CollectionView/IB/CollectionView/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // CollectionView 4 | // 5 | // Created by Tibor Bödecs on 2018. 04. 16.. 6 | // Copyright © 2018. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder { 13 | 14 | var window: UIWindow? 15 | 16 | } 17 | 18 | extension AppDelegate: UIApplicationDelegate { 19 | 20 | func application(_ application: UIApplication, 21 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 22 | return true 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /iOS/CollectionView/IB/CollectionView/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /iOS/CollectionView/Programmatically/CollectionView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /iOS/CollectionView/Programmatically/CollectionView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /iOS/CollectionView/Programmatically/CollectionView.xcodeproj/project.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/CollectionView/Programmatically/CollectionView.xcodeproj/project.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /iOS/CollectionView/Programmatically/CollectionView.xcodeproj/xcuserdata/tib.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | CollectionView.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | CollectionView.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /iOS/CollectionView/Programmatically/CollectionView/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // CollectionView 4 | // 5 | // Created by Tibor Bödecs on 2018. 04. 16.. 6 | // Copyright © 2018. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder { 13 | 14 | var window: UIWindow? 15 | 16 | } 17 | 18 | extension AppDelegate: UIApplicationDelegate { 19 | 20 | func application(_ application: UIApplication, 21 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 22 | return true 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /iOS/CollectionView/Programmatically/CollectionView/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /iOS/CollectionView/Sections/CollectionView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /iOS/CollectionView/Sections/CollectionView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /iOS/CollectionView/Sections/CollectionView.xcodeproj/project.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/CollectionView/Sections/CollectionView.xcodeproj/project.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /iOS/CollectionView/Sections/CollectionView.xcodeproj/xcuserdata/tib.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | CollectionView.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | CollectionView.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /iOS/CollectionView/Sections/CollectionView/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // CollectionView 4 | // 5 | // Created by Tibor Bödecs on 2018. 04. 16.. 6 | // Copyright © 2018. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder { 13 | 14 | var window: UIWindow? 15 | 16 | } 17 | 18 | extension AppDelegate: UIApplicationDelegate { 19 | 20 | func application(_ application: UIApplication, 21 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 22 | return true 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /iOS/CollectionView/Sections/CollectionView/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /iOS/CollectionView/Sections/CollectionView/Cell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Cell.swift 3 | // CollectionView 4 | // 5 | // Created by Tibor Bödecs on 2018. 04. 16.. 6 | // Copyright © 2018. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class Cell: UICollectionViewCell { 12 | 13 | @IBOutlet weak var textLabel: UILabel! 14 | 15 | override func awakeFromNib() { 16 | super.awakeFromNib() 17 | 18 | self.contentView.backgroundColor = .lightGray 19 | } 20 | 21 | override func prepareForReuse() { 22 | super.prepareForReuse() 23 | 24 | self.textLabel.text = nil 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /iOS/CollectionView/Sections/CollectionView/Section.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Section.swift 3 | // CollectionView 4 | // 5 | // Created by Tibor Bödecs on 2018. 04. 16.. 6 | // Copyright © 2018. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class Section: UICollectionViewCell { 12 | 13 | @IBOutlet weak var textLabel: UILabel! 14 | 15 | override func awakeFromNib() { 16 | super.awakeFromNib() 17 | 18 | self.contentView.backgroundColor = .darkGray 19 | self.textLabel.textColor = .white 20 | } 21 | 22 | override func prepareForReuse() { 23 | super.prepareForReuse() 24 | 25 | self.textLabel.text = nil 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /iOS/CollectionView/Self Sizing Cells/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | build 3 | .build 4 | -------------------------------------------------------------------------------- /iOS/CollectionView/Self Sizing Cells/SelfSizing.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /iOS/CollectionView/Self Sizing Cells/SelfSizing.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /iOS/CollectionView/Self Sizing Cells/SelfSizing.xcodeproj/project.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/CollectionView/Self Sizing Cells/SelfSizing.xcodeproj/project.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /iOS/CollectionView/Self Sizing Cells/SelfSizing.xcodeproj/xcuserdata/tib.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SelfSizing.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 16A093411D52A83100CF79AB 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /iOS/CollectionView/Self Sizing Cells/SelfSizing/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SelfSizing 4 | // 5 | // Created by Tibor Bodecs on 04/08/16. 6 | // Copyright © 2016 Tibor Bodecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder { 13 | 14 | var window: UIWindow? 15 | } 16 | 17 | extension AppDelegate: UIApplicationDelegate { 18 | 19 | func application(_ application: UIApplication, 20 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { 21 | return true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /iOS/CollectionView/Self Sizing Cells/SelfSizing/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "size" : "1024x1024", 46 | "scale" : "1x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } -------------------------------------------------------------------------------- /iOS/CollectionView/Self Sizing Cells/SelfSizing/TableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TableViewCell.swift 3 | // SelfSizing 4 | // 5 | // Created by Tibor Bodecs on 04/08/16. 6 | // Copyright © 2016 Tibor Bodecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class TableViewCell: UITableViewCell { 12 | 13 | @IBOutlet weak var dynamicLabel: UILabel! 14 | } 15 | -------------------------------------------------------------------------------- /iOS/Forms/StackForm/StackForm.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /iOS/Forms/StackForm/StackForm.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /iOS/Forms/StackForm/StackForm.xcodeproj/project.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/Forms/StackForm/StackForm.xcodeproj/project.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /iOS/Forms/StackForm/StackForm.xcodeproj/xcuserdata/tib.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | StackForm.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /iOS/Forms/StackForm/StackForm/Assets/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /iOS/Forms/StackForm/StackForm/Sources/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // StackForm 4 | // 5 | // Created by Tibor Bödecs on 2019. 10. 17.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder { 13 | 14 | 15 | } 16 | 17 | extension AppDelegate: UIApplicationDelegate { 18 | 19 | func application(_ application: UIApplication, 20 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 21 | return true 22 | } 23 | 24 | func application(_ application: UIApplication, 25 | configurationForConnecting connectingSceneSession: UISceneSession, 26 | options: UIScene.ConnectionOptions) -> UISceneConfiguration { 27 | return .init(name: "Default Configuration", sessionRole: connectingSceneSession.role) 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /iOS/Forms/StackForm/StackForm/Sources/Extensions/UIView+Id.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Id.swift 3 | // StackForm 4 | // 5 | // Created by Tibor Bödecs on 2019. 10. 20.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UIView { 12 | 13 | var id: String? { 14 | get { 15 | return self.accessibilityIdentifier 16 | } 17 | set { 18 | self.accessibilityIdentifier = newValue 19 | } 20 | } 21 | 22 | func view(withId id: String) -> UIView? { 23 | if self.id == id { 24 | return self 25 | } 26 | for view in self.subviews { 27 | if let view = view.view(withId: id) { 28 | return view 29 | } 30 | } 31 | return nil 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /iOS/Forms/StackForm/StackForm/Sources/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.swift 3 | // StackForm 4 | // 5 | // Created by Tibor Bödecs on 2019. 10. 17.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SceneDelegate: UIResponder { 12 | 13 | var window: UIWindow? 14 | } 15 | 16 | extension SceneDelegate: UIWindowSceneDelegate { 17 | 18 | func scene(_ scene: UIScene, 19 | willConnectTo session: UISceneSession, 20 | options connectionOptions: UIScene.ConnectionOptions) { 21 | guard let _ = (scene as? UIWindowScene) else { 22 | return 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /iOS/Forms/StackForm/StackForm/Sources/Views/Buttons/Button.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Button.swift 3 | // StackForm 4 | // 5 | // Created by Tibor Bödecs on 2019. 10. 20.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class Button: UIButton { 12 | 13 | @available(*, unavailable) 14 | override init(frame: CGRect) { 15 | super.init(frame: frame) 16 | 17 | self.initialize() 18 | } 19 | 20 | @available(*, unavailable) 21 | required init?(coder: NSCoder) { 22 | fatalError("init(coder:) has not been implemented") 23 | } 24 | 25 | init(id: String) { 26 | super.init(frame: .zero) 27 | 28 | self.id = id 29 | 30 | self.initialize() 31 | } 32 | 33 | func initialize() { 34 | self.translatesAutoresizingMaskIntoConstraints = false 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /iOS/Forms/StackForm/StackForm/Sources/Views/Buttons/SubmitButton.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SubmitButton.swift 3 | // StackForm 4 | // 5 | // Created by Tibor Bödecs on 2019. 10. 20.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SubmitButton: Button { 12 | 13 | var touchHandler: ((SubmitButton) -> Void)? 14 | 15 | init(id: String, title: String) { 16 | super.init(id: id) 17 | 18 | self.setTitle(title, for: .normal) 19 | } 20 | 21 | override func initialize() { 22 | super.initialize() 23 | 24 | self.setTitleColor(.systemBlue, for: .normal) 25 | self.addTarget(self, action: #selector(self.touchAction(_:)), for: .touchUpInside) 26 | } 27 | 28 | @objc func touchAction(_ sender: SubmitButton) { 29 | self.touchHandler?(sender) 30 | } 31 | 32 | func onTouch(_ handler: @escaping ((SubmitButton) -> Void)) -> Self { 33 | self.touchHandler = handler 34 | return self 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /iOS/Forms/StackForm/StackForm/Sources/Views/ScrollView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ScrollView.swift 3 | // StackForm 4 | // 5 | // Created by Tibor Bödecs on 2019. 10. 20.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ScrollView: UIScrollView { 12 | 13 | @available(*, unavailable) 14 | override init(frame: CGRect) { 15 | super.init(frame: frame) 16 | 17 | self.initialize() 18 | } 19 | 20 | @available(*, unavailable) 21 | required init?(coder: NSCoder) { 22 | fatalError("init(coder:) has not been implemented") 23 | } 24 | 25 | init() { 26 | super.init(frame: .zero) 27 | 28 | self.initialize() 29 | } 30 | 31 | func initialize() { 32 | self.translatesAutoresizingMaskIntoConstraints = false 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /iOS/Forms/StackForm/StackForm/Sources/Views/StackView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StackView.swift 3 | // StackForm 4 | // 5 | // Created by Tibor Bödecs on 2019. 10. 20.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class VerticalStackView: UIStackView { 12 | 13 | @available(*, unavailable) 14 | override init(frame: CGRect) { 15 | super.init(frame: frame) 16 | 17 | self.initialize() 18 | } 19 | 20 | @available(*, unavailable) 21 | required init(coder: NSCoder) { 22 | fatalError("init(coder:) has not been implemented") 23 | } 24 | 25 | init() { 26 | super.init(frame: .zero) 27 | 28 | self.initialize() 29 | } 30 | 31 | func initialize() { 32 | self.translatesAutoresizingMaskIntoConstraints = false 33 | 34 | self.axis = .vertical 35 | self.distribution = .fill 36 | self.alignment = .fill 37 | self.spacing = 16 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /iOS/Forms/StackForm/StackForm/Sources/Views/TextFields/EmailTextField.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EmailTextField.swift 3 | // StackForm 4 | // 5 | // Created by Tibor Bödecs on 2019. 10. 20.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class EmailTextField: TextField { 12 | 13 | override func initialize() { 14 | super.initialize() 15 | 16 | self.keyboardType = .emailAddress 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /iOS/Forms/StackForm/StackForm/Sources/Views/TextFields/PasswordTextField.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PasswordTextField.swift 3 | // StackForm 4 | // 5 | // Created by Tibor Bödecs on 2019. 10. 20.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | 12 | class PasswordTextField: TextField { 13 | 14 | override func initialize() { 15 | super.initialize() 16 | 17 | self.isSecureTextEntry = true 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /iOS/Forms/StackForm/StackForm/Sources/Views/TextFields/TextField.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TextField.swift 3 | // StackForm 4 | // 5 | // Created by Tibor Bödecs on 2019. 10. 20.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class TextField: UITextField { 12 | 13 | @available(*, unavailable) 14 | override init(frame: CGRect) { 15 | super.init(frame: frame) 16 | 17 | self.initialize() 18 | } 19 | 20 | @available(*, unavailable) 21 | required init?(coder: NSCoder) { 22 | fatalError("init(coder:) has not been implemented") 23 | } 24 | 25 | init(id: String, placeholder: String) { 26 | super.init(frame: .zero) 27 | 28 | self.id = id 29 | self.placeholder = placeholder 30 | 31 | self.initialize() 32 | } 33 | 34 | func initialize() { 35 | self.translatesAutoresizingMaskIntoConstraints = false 36 | 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /iOS/Pickers/Pickers.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /iOS/Pickers/Pickers.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /iOS/Pickers/Pickers.xcodeproj/xcuserdata/tib.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 9 | 16 | 17 | 18 | 20 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /iOS/Pickers/Pickers.xcodeproj/xcuserdata/tib.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Pickers.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /iOS/Pickers/Pickers/Assets/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /iOS/Pickers/Pickers/Sources/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.swift 3 | // Pickers 4 | // 5 | // Created by Tibor Bödecs on 2019. 08. 28.. 6 | // Copyright © 2019. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @available(iOS 13.0, *) 12 | class SceneDelegate: UIResponder { 13 | 14 | var window: UIWindow? 15 | } 16 | 17 | @available(iOS 13.0, *) 18 | extension SceneDelegate: UIWindowSceneDelegate { 19 | 20 | 21 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 22 | guard let _ = (scene as? UIWindowScene) else { return } 23 | } 24 | 25 | func sceneDidDisconnect(_ scene: UIScene) { 26 | 27 | } 28 | 29 | func sceneDidBecomeActive(_ scene: UIScene) { 30 | 31 | } 32 | 33 | func sceneWillResignActive(_ scene: UIScene) { 34 | 35 | } 36 | 37 | func sceneWillEnterForeground(_ scene: UIScene) { 38 | 39 | } 40 | 41 | func sceneDidEnterBackground(_ scene: UIScene) { 42 | 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /iOS/SpriteKit/Best Practices/SpriteKitBestPractices.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /iOS/SpriteKit/Best Practices/SpriteKitBestPractices.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /iOS/SpriteKit/Best Practices/SpriteKitBestPractices.xcodeproj/project.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/SpriteKit/Best Practices/SpriteKitBestPractices.xcodeproj/project.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /iOS/SpriteKit/Best Practices/SpriteKitBestPractices.xcodeproj/xcuserdata/tib.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /iOS/SpriteKit/Best Practices/SpriteKitBestPractices.xcodeproj/xcuserdata/tib.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SpriteKitBestPractices.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | SpriteKitBestPractices.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /iOS/SpriteKit/Best Practices/SpriteKitBestPractices/Assets/Scenes/Actions.sks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/SpriteKit/Best Practices/SpriteKitBestPractices/Assets/Scenes/Actions.sks -------------------------------------------------------------------------------- /iOS/SpriteKit/Best Practices/SpriteKitBestPractices/Assets/Scenes/GameScene.sks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/SpriteKit/Best Practices/SpriteKitBestPractices/Assets/Scenes/GameScene.sks -------------------------------------------------------------------------------- /iOS/SpriteKit/Best Practices/SpriteKitBestPractices/Sources/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SpriteKitBestPractices 4 | // 5 | // Created by Tibor Bödecs on 2017. 10. 24.. 6 | // Copyright © 2017. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder { 13 | 14 | var window: UIWindow? 15 | } 16 | 17 | extension AppDelegate: UIApplicationDelegate { 18 | 19 | func application(_ application: UIApplication, 20 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 21 | return true 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /iOS/ViewController/Custom Transitions/CustomTransition.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /iOS/ViewController/Custom Transitions/CustomTransition.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /iOS/ViewController/Custom Transitions/CustomTransition.xcodeproj/project.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theswiftdev/tutorials/207bed48e480d744bd8b268401e3c562227b18c0/iOS/ViewController/Custom Transitions/CustomTransition.xcodeproj/project.xcworkspace/xcuserdata/tib.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /iOS/ViewController/Custom Transitions/CustomTransition.xcodeproj/xcuserdata/tib.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /iOS/ViewController/Custom Transitions/CustomTransition.xcodeproj/xcuserdata/tib.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | CustomTransition.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | CustomTransition.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /iOS/ViewController/Custom Transitions/CustomTransition/Assets/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /iOS/ViewController/Custom Transitions/CustomTransition/Sources/Animators/CustomAnimator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CustomAnimator.swift 3 | // CustomTransition 4 | // 5 | // Created by Tibor Bödecs on 2018. 04. 26.. 6 | // Copyright © 2018. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | open class CustomAnimator: NSObject, UIViewControllerAnimatedTransitioning { 12 | 13 | public enum TransitionType { 14 | case navigation 15 | case modal 16 | } 17 | 18 | let type: TransitionType 19 | let duration: TimeInterval 20 | 21 | public init(type: TransitionType, duration: TimeInterval = 0.25) { 22 | self.type = type 23 | self.duration = duration 24 | 25 | super.init() 26 | } 27 | 28 | open func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { 29 | return self.duration 30 | } 31 | 32 | open func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { 33 | fatalError("You have to implement this method for yourself!") 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /iOS/ViewController/Custom Transitions/CustomTransition/Sources/Animators/FadePushAnimator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FadePushAnimator.swift 3 | // CustomTransition 4 | // 5 | // Created by Tibor Bödecs on 2018. 04. 26.. 6 | // Copyright © 2018. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | open class FadePushAnimator: CustomAnimator { 12 | 13 | open override func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { 14 | guard 15 | let toViewController = transitionContext.viewController(forKey: .to) 16 | else { 17 | return 18 | } 19 | transitionContext.containerView.addSubview(toViewController.view) 20 | toViewController.view.alpha = 0 21 | 22 | let duration = self.transitionDuration(using: transitionContext) 23 | UIView.animate(withDuration: duration, animations: { 24 | toViewController.view.alpha = 1 25 | }, completion: { _ in 26 | transitionContext.completeTransition(!transitionContext.transitionWasCancelled) 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /iOS/ViewController/Custom Transitions/CustomTransition/Sources/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // CustomTransition 4 | // 5 | // Created by Tibor Bödecs on 2018. 04. 25.. 6 | // Copyright © 2018. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder { 13 | 14 | var window: UIWindow? 15 | } 16 | 17 | extension AppDelegate: UIApplicationDelegate { 18 | 19 | func application(_ application: UIApplication, 20 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 21 | return true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /iOS/ViewController/Custom Transitions/CustomTransition/Sources/Controllers/ModalViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ModalViewController.swift 3 | // CustomTransition 4 | // 5 | // Created by Tibor Bödecs on 2018. 04. 25.. 6 | // Copyright © 2018. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ModalViewController: UIViewController { 12 | 13 | var interactionController: LeftEdgeInteractionController? 14 | 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | 18 | self.view.backgroundColor = .orange 19 | 20 | self.interactionController = LeftEdgeInteractionController(viewController: self) 21 | } 22 | 23 | @IBAction func dismiss(_ sender: Any) { 24 | self.dismiss(animated: true, completion: nil) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /iOS/iCloud drive/iCloudDrive.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /iOS/iCloud drive/iCloudDrive.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /iOS/iCloud drive/iCloudDrive.xcodeproj/xcuserdata/tib.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | iCloudDrive.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 166623DA20AD693A004E00E7 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /iOS/iCloud drive/iCloudDrive/Assets/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /iOS/iCloud drive/iCloudDrive/Assets/iCloudDrive.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.icloud-container-identifiers 6 | 7 | iCloud.$(CFBundleIdentifier) 8 | 9 | com.apple.developer.icloud-services 10 | 11 | CloudDocuments 12 | 13 | com.apple.developer.ubiquity-container-identifiers 14 | 15 | iCloud.$(CFBundleIdentifier) 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /iOS/iCloud drive/iCloudDrive/Sources/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // iCloudDrive 4 | // 5 | // Created by Tibor Bödecs on 2018. 05. 17.. 6 | // Copyright © 2018. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder { 13 | 14 | var window: UIWindow? 15 | } 16 | 17 | extension AppDelegate: UIApplicationDelegate { 18 | 19 | func application(_ application: UIApplication, 20 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 21 | return true 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /macOS/Launcher/LauncherApplication/LauncherApplication.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macOS/Launcher/MainApplication.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /macOS/Launcher/MainApplication.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macOS/Launcher/MainApplication.xcodeproj/xcuserdata/tib.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | LauncherApplication.xcscheme 8 | 9 | orderHint 10 | 1 11 | 12 | MainApplication.xcscheme 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | 163C6BAA1BAB395C003DC7DA 21 | 22 | primary 23 | 24 | 25 | 163C6BC11BAB3C55003DC7DA 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /macOS/Launcher/MainApplication/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // MainApplication 4 | // 5 | // Created by Tibor Bodecs on 2015. 09. 17.. 6 | // Copyright © 2015. Tibor Bodecs. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import ServiceManagement 11 | 12 | extension Notification.Name { 13 | static let killLauncher = Notification.Name("killLauncher") 14 | } 15 | 16 | @NSApplicationMain 17 | class AppDelegate: NSObject {} 18 | 19 | 20 | extension AppDelegate: NSApplicationDelegate { 21 | 22 | func applicationDidFinishLaunching(_ aNotification: Notification) { 23 | 24 | let launcherAppId = "com.tiborbodecs.LauncherApplication" 25 | let runningApps = NSWorkspace.shared.runningApplications 26 | let isRunning = !runningApps.filter { $0.bundleIdentifier == launcherAppId }.isEmpty 27 | 28 | SMLoginItemSetEnabled(launcherAppId as CFString, true) 29 | 30 | if isRunning { 31 | DistributedNotificationCenter.default().post(name: .killLauncher, 32 | object: Bundle.main.bundleIdentifier!) 33 | } 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /macOS/Launcher/MainApplication/MainApplication.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macOS/Launcher/MainApplication/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // MainApplication 4 | // 5 | // Created by Tibor Bodecs on 2015. 09. 17.. 6 | // Copyright © 2015. Tibor Bodecs. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class ViewController: NSViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | // Do any additional setup after loading the view. 17 | } 18 | 19 | override var representedObject: Any? { 20 | didSet { 21 | // Update the view, if already loaded. 22 | } 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /macOS/Networking/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | Carthage 3 | 4 | 5 | -------------------------------------------------------------------------------- /macOS/Networking/Networking.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /macOS/Networking/Networking.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macOS/Networking/Shared/Sources/BluetoothConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BluetoothConfig.swift 3 | // Networking 4 | // 5 | // Created by Tibor Bödecs on 2018. 02. 22.. 6 | // Copyright © 2018. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import CoreBluetooth 11 | 12 | struct BluetoothConfig { 13 | 14 | static let service = CBUUID(string: "E20A39F4-73F5-4BC4-A12F-17D1AD07A961") 15 | static let characteristics = CBUUID(string: "08590F7E-DB05-467E-8757-72F6FAEB13D4") 16 | 17 | static let EOM = "EOM" 18 | static let EOMData = BluetoothConfig.EOM.data(using: .utf8)! 19 | } 20 | -------------------------------------------------------------------------------- /macOS/Networking/Shared/Sources/NetworkDevice.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NetworkDevice.swift 3 | // Networking 4 | // 5 | // Created by Tibor Bödecs on 2018. 02. 23.. 6 | // Copyright © 2018. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | #if os(iOS) || os(tvOS) 11 | import UIKit 12 | #endif 13 | 14 | struct NetworkDevice { 15 | #if os(macOS) 16 | static let name = Host.current().localizedName! 17 | #else 18 | static let name = UIDevice.current.name 19 | #endif 20 | } 21 | -------------------------------------------------------------------------------- /macOS/Networking/Shared/Sources/TCPConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TCPConfig.swift 3 | // Networking 4 | // 5 | // Created by Tibor Bödecs on 2018. 02. 22.. 6 | // Copyright © 2018. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct TCPConfig { 12 | static let domain = "local." 13 | static let service = "_myservice._tcp." 14 | } 15 | -------------------------------------------------------------------------------- /macOS/Networking/Shared/Sources/UDPConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UDPConfig.swift 3 | // Networking 4 | // 5 | // Created by Tibor Bödecs on 2018. 02. 22.. 6 | // Copyright © 2018. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct UDPConfig { 12 | static let domain = "local." 13 | static let service = "_udp_discovery._udp." 14 | } 15 | -------------------------------------------------------------------------------- /macOS/Networking/iOS/Application/Sources/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Networking 4 | // 5 | // Created by Tibor Bödecs on 2018. 02. 22.. 6 | // Copyright © 2018. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder { 13 | 14 | var window: UIWindow? 15 | 16 | } 17 | 18 | extension AppDelegate: UIApplicationDelegate { 19 | 20 | func application(_ application: UIApplication, 21 | didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunch.OptionsKey: Any]?) -> Bool { 22 | return true 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /macOS/Networking/macOS/Application/Assets/macOS.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /macOS/Networking/macOS/Application/Sources/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // macOS 4 | // 5 | // Created by Tibor Bödecs on 2018. 02. 22.. 6 | // Copyright © 2018. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject { 13 | 14 | 15 | } 16 | 17 | extension AppDelegate: NSApplicationDelegate { 18 | 19 | func applicationDidFinishLaunching(_ aNotification: Notification) { 20 | 21 | } 22 | 23 | func applicationWillTerminate(_ aNotification: Notification) { 24 | 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /macOS/Networking/macOS/Application/Sources/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // macOS 4 | // 5 | // Created by Tibor Bödecs on 2018. 02. 22.. 6 | // Copyright © 2018. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class ViewController: NSViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | TCPServer.shared.dataReceivedCallback = { data in 17 | print(data) 18 | } 19 | UDPServer.shared.callback = { message, address in 20 | print("Message: \(message), from: \(address)") 21 | } 22 | BluetoothServer.shared.start() 23 | } 24 | 25 | override var representedObject: Any? { 26 | didSet { 27 | // Update the view, if already loaded. 28 | } 29 | } 30 | 31 | 32 | } 33 | 34 | -------------------------------------------------------------------------------- /macOS/Networking/tvOS/Application/Assets/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv" 5 | } 6 | ], 7 | "info" : { 8 | "version" : 1, 9 | "author" : "xcode" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /macOS/Networking/tvOS/Application/Assets/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /macOS/Networking/tvOS/Application/Assets/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers" : [ 3 | { 4 | "filename" : "Front.imagestacklayer" 5 | }, 6 | { 7 | "filename" : "Middle.imagestacklayer" 8 | }, 9 | { 10 | "filename" : "Back.imagestacklayer" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } -------------------------------------------------------------------------------- /macOS/Networking/tvOS/Application/Assets/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv" 5 | } 6 | ], 7 | "info" : { 8 | "version" : 1, 9 | "author" : "xcode" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /macOS/Networking/tvOS/Application/Assets/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /macOS/Networking/tvOS/Application/Assets/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv" 5 | } 6 | ], 7 | "info" : { 8 | "version" : 1, 9 | "author" : "xcode" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /macOS/Networking/tvOS/Application/Assets/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /macOS/Networking/tvOS/Application/Assets/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /macOS/Networking/tvOS/Application/Assets/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /macOS/Networking/tvOS/Application/Assets/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers" : [ 3 | { 4 | "filename" : "Front.imagestacklayer" 5 | }, 6 | { 7 | "filename" : "Middle.imagestacklayer" 8 | }, 9 | { 10 | "filename" : "Back.imagestacklayer" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } -------------------------------------------------------------------------------- /macOS/Networking/tvOS/Application/Assets/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /macOS/Networking/tvOS/Application/Assets/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /macOS/Networking/tvOS/Application/Assets/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /macOS/Networking/tvOS/Application/Assets/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /macOS/Networking/tvOS/Application/Assets/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "assets" : [ 3 | { 4 | "size" : "1280x768", 5 | "idiom" : "tv", 6 | "filename" : "App Icon - App Store.imagestack", 7 | "role" : "primary-app-icon" 8 | }, 9 | { 10 | "size" : "400x240", 11 | "idiom" : "tv", 12 | "filename" : "App Icon.imagestack", 13 | "role" : "primary-app-icon" 14 | }, 15 | { 16 | "size" : "2320x720", 17 | "idiom" : "tv", 18 | "filename" : "Top Shelf Image Wide.imageset", 19 | "role" : "top-shelf-image-wide" 20 | }, 21 | { 22 | "size" : "1920x720", 23 | "idiom" : "tv", 24 | "filename" : "Top Shelf Image.imageset", 25 | "role" : "top-shelf-image" 26 | } 27 | ], 28 | "info" : { 29 | "version" : 1, 30 | "author" : "xcode" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /macOS/Networking/tvOS/Application/Assets/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /macOS/Networking/tvOS/Application/Assets/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /macOS/Networking/tvOS/Application/Assets/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /macOS/Networking/tvOS/Application/Assets/Assets.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "landscape", 5 | "idiom" : "tv", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "9.0", 8 | "scale" : "1x" 9 | } 10 | ], 11 | "info" : { 12 | "version" : 1, 13 | "author" : "xcode" 14 | } 15 | } -------------------------------------------------------------------------------- /macOS/Networking/tvOS/Application/Assets/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIMainStoryboardFile 24 | Main 25 | UIRequiredDeviceCapabilities 26 | 27 | arm64 28 | 29 | UIUserInterfaceStyle 30 | Automatic 31 | 32 | 33 | -------------------------------------------------------------------------------- /macOS/Networking/tvOS/Application/Sources/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // tvOS 4 | // 5 | // Created by Tibor Bödecs on 2018. 02. 22.. 6 | // Copyright © 2018. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder { 13 | 14 | var window: UIWindow? 15 | 16 | } 17 | 18 | extension AppDelegate: UIApplicationDelegate { 19 | 20 | func application(_ application: UIApplication, 21 | didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 22 | return true 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /macOS/Networking/tvOS/Application/Sources/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // tvOS 4 | // 5 | // Created by Tibor Bödecs on 2018. 02. 22.. 6 | // Copyright © 2018. Tibor Bödecs. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | TCPServer.shared.dataReceivedCallback = { data in 17 | print(data) 18 | } 19 | UDPServer.shared.callback = { message, address in 20 | print("Message: \(message), from: \(address)") 21 | } 22 | BluetoothServer.shared.start() 23 | } 24 | 25 | override func didReceiveMemoryWarning() { 26 | super.didReceiveMemoryWarning() 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /macOS/Networking/watchOS/Extension/Assets/Assets.xcassets/Complication.complicationset/Circular.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "screenWidth" : "{130,145}", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "screenWidth" : "{146,165}", 11 | "scale" : "2x" 12 | } 13 | ], 14 | "info" : { 15 | "version" : 1, 16 | "author" : "xcode" 17 | } 18 | } -------------------------------------------------------------------------------- /macOS/Networking/watchOS/Extension/Assets/Assets.xcassets/Complication.complicationset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "assets" : [ 3 | { 4 | "idiom" : "watch", 5 | "filename" : "Circular.imageset", 6 | "role" : "circular" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "filename" : "Extra Large.imageset", 11 | "role" : "extra-large" 12 | }, 13 | { 14 | "idiom" : "watch", 15 | "filename" : "Modular.imageset", 16 | "role" : "modular" 17 | }, 18 | { 19 | "idiom" : "watch", 20 | "filename" : "Utilitarian.imageset", 21 | "role" : "utilitarian" 22 | } 23 | ], 24 | "info" : { 25 | "version" : 1, 26 | "author" : "xcode" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /macOS/Networking/watchOS/Extension/Assets/Assets.xcassets/Complication.complicationset/Extra Large.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "screenWidth" : "{130,145}", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "screenWidth" : "{146,165}", 11 | "scale" : "2x" 12 | } 13 | ], 14 | "info" : { 15 | "version" : 1, 16 | "author" : "xcode" 17 | } 18 | } -------------------------------------------------------------------------------- /macOS/Networking/watchOS/Extension/Assets/Assets.xcassets/Complication.complicationset/Modular.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "screenWidth" : "{130,145}", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "screenWidth" : "{146,165}", 11 | "scale" : "2x" 12 | } 13 | ], 14 | "info" : { 15 | "version" : 1, 16 | "author" : "xcode" 17 | } 18 | } -------------------------------------------------------------------------------- /macOS/Networking/watchOS/Extension/Assets/Assets.xcassets/Complication.complicationset/Utilitarian.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "screenWidth" : "{130,145}", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "screenWidth" : "{146,165}", 11 | "scale" : "2x" 12 | } 13 | ], 14 | "info" : { 15 | "version" : 1, 16 | "author" : "xcode" 17 | } 18 | } -------------------------------------------------------------------------------- /macOS/Networking/watchOS/Extension/Assets/PushNotificationPayload.apns: -------------------------------------------------------------------------------- 1 | { 2 | "aps": { 3 | "alert": { 4 | "body": "Test message", 5 | "title": "Optional title" 6 | }, 7 | "category": "myCategory", 8 | "thread-id":"5280" 9 | }, 10 | 11 | "WatchKit Simulator Actions": [ 12 | { 13 | "title": "First Button", 14 | "identifier": "firstButtonAction" 15 | } 16 | ], 17 | 18 | "customKey": "Use this file to define a testing payload for your notifications. The aps dictionary specifies the category, alert text and title. The WatchKit Simulator Actions array can provide info for one or more action buttons in addition to the standard Dismiss button. Any other top level keys are custom payload. If you have multiple such JSON files in your project, you'll be able to select them when choosing to debug the notification interface of your Watch App." 19 | } 20 | --------------------------------------------------------------------------------