├── .gitignore ├── FontAndColorThemes ├── iOS on practice (Dark).xccolortheme └── iOS on practice (Light).xccolortheme ├── README.md ├── SimpleCalculator ├── LogicForCalcApp │ ├── LogicForCalcApp.xcodeproj │ │ └── project.pbxproj │ └── LogicForCalcApp │ │ └── main.swift └── SimpleCalcFBL │ ├── SimpleCalcFBL.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── SimpleCalcFBL │ ├── App │ ├── AppDelegate.swift │ └── SceneDelegate.swift │ ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json │ ├── Info.plist │ ├── Model │ ├── AppColors.swift │ ├── CalcService.swift │ ├── Constants.swift │ └── Operations.swift │ └── ViewController │ ├── Base.lproj │ └── LaunchScreen.storyboard │ └── MainView │ └── ViewController.swift ├── SwiftUI └── LaunchScreeenSwitftUI │ ├── LaunchScreeenSwitftUI.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── LaunchScreeenSwitftUI │ ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── backgroundColor.colorset │ │ └── Contents.json │ └── launchLogo.imageset │ │ ├── Contents.json │ │ └── LaunchLogo.png │ ├── ContentView.swift │ ├── Info.plist │ ├── LaunchScreeenSwitftUIApp.swift │ ├── LaunchScreenView.swift │ └── Preview Content │ └── Preview Assets.xcassets │ └── Contents.json ├── UIKit ├── v057-UiSearchBarTutorial │ ├── UiSearchBarTutorial.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ ├── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ └── xcuserdata │ │ │ │ └── lexone01.xcuserdatad │ │ │ │ └── UserInterfaceState.xcuserstate │ │ └── xcuserdata │ │ │ └── lexone01.xcuserdatad │ │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ └── UiSearchBarTutorial │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ ├── SceneDelegate.swift │ │ └── ViewController.swift ├── v061-UIKitWithSWiftUI │ └── SwiftUIintegration │ │ ├── SwiftUIintegration.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ ├── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ └── xcuserdata │ │ │ │ └── lexone01.xcuserdatad │ │ │ │ └── UserInterfaceState.xcuserstate │ │ └── xcuserdata │ │ │ └── lexone01.xcuserdatad │ │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ │ └── SwiftUIintegration │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ ├── SceneDelegate.swift │ │ ├── SwiftUIView.swift │ │ └── ViewController.swift ├── v064-UIKitProgrammatically │ ├── UIKitProgrammatically.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ ├── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ └── xcuserdata │ │ │ │ └── lexone01.xcuserdatad │ │ │ │ └── UserInterfaceState.xcuserstate │ │ └── xcuserdata │ │ │ └── lexone01.xcuserdatad │ │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ └── UIKitProgrammatically │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ │ ├── Base.lproj │ │ └── LaunchScreen.storyboard │ │ ├── Info.plist │ │ ├── SceneDelegate.swift │ │ └── ViewController.swift ├── v066-UIKit-Frame-Based-Layout │ ├── UIKitProgrammatically.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ ├── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ └── xcuserdata │ │ │ │ └── lexone01.xcuserdatad │ │ │ │ └── UserInterfaceState.xcuserstate │ │ └── xcuserdata │ │ │ └── lexone01.xcuserdatad │ │ │ ├── xcdebugger │ │ │ └── Breakpoints_v2.xcbkptlist │ │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ └── UIKitProgrammatically │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ │ ├── Base.lproj │ │ └── LaunchScreen.storyboard │ │ ├── Info.plist │ │ ├── SceneDelegate.swift │ │ └── ViewController.swift ├── v077-IntrinsicContentSize │ └── IntrinsicContentSize │ │ ├── IntrinsicContentSize.xcodeproj │ │ ├── project.pbxproj │ │ └── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── IntrinsincContentSize │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ ├── SceneDelegate.swift │ │ ├── UIDynamicLabel.swift │ │ └── ViewController.swift ├── v78-UIScrollView │ └── UIScrollViewProgrammatically │ │ ├── UIScrollViewProgrammatically.xcodeproj │ │ ├── project.pbxproj │ │ └── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── UIScrollViewProgrammatically │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ ├── SceneDelegate.swift │ │ └── ViewController.swift ├── v83-@discarableResult │ └── DiscarableResult │ │ ├── DiscarableResult.xcodeproj │ │ ├── project.pbxproj │ │ └── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── DiscarableResult │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ ├── SceneDelegate.swift │ │ └── ViewController.swift └── v84-Netfox+SwiftPM │ └── DiscarableResult │ ├── DiscarableResult.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── swiftpm │ │ └── Package.resolved │ └── DiscarableResult │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── SceneDelegate.swift │ └── ViewController.swift ├── algorithms-on-swift ├── README.md ├── v004-Binary-search │ ├── BinarySearch.swift │ └── README.md └── v011-Butterfly │ ├── ButterflyPattern.swift │ └── README.md └── patterns-and-architectures ├── v001-True-Delegation-Story ├── README.md └── TrueDelegationStory.swift ├── v002-MVP ├── LICENSE ├── MVP-v002.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── lexone01.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── lexone01.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── MVP-v002 │ ├── App │ │ ├── AppDelegate.swift │ │ └── SceneDelegate.swift │ ├── Assets.xcassets │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ ├── Contents.json │ │ └── my_logo.imageset │ │ │ ├── Contents.json │ │ │ └── my_logo.png │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ ├── Models │ │ └── Crypto.swift │ ├── Presenters │ │ └── Presenter.swift │ └── Views │ │ ├── ViewController.swift │ │ ├── ViewInputDelegate.swift │ │ └── ViewOutputDelegate.swift └── README.md ├── v003-Coordinator-example ├── README.md ├── v003-Coordtinator.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── lexone01.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── lexone01.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist └── v003-Coordtinator │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ └── my_logo.imageset │ │ ├── Contents.json │ │ └── my_logo.png │ ├── Base.lproj │ └── LaunchScreen.storyboard │ ├── Coordinators │ ├── AppCoordinator.swift │ └── Protocols │ │ └── Coordinator.swift │ ├── Info.plist │ └── Views │ ├── Base.lproj │ └── Main.storyboard │ ├── FirstViewController.swift │ ├── SecondViewController.swift │ ├── Storyboardable.swift │ └── ThirdViewController.swift ├── v005-MVC ├── Readme.md ├── v005-MVC.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── lexone01.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── lexone01.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist └── v005-MVC │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ └── my_logo.imageset │ │ ├── Contents.json │ │ └── my_logo.png │ ├── Controllers │ └── ViewController.swift │ ├── Info.plist │ ├── Models │ ├── Crypto.swift │ └── Hellpers │ │ └── RandomCount.swift │ ├── SceneDelegate.swift │ └── Views │ └── Storyboards │ └── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── v028-CompletionHandlers ├── CompletionHandlers.playground │ ├── Contents.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ └── lexone01.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── Readme.md ├── v029-MVVM_simple ├── MVVM_simple.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── lexone01.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── lexone01.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── MVVM_simple │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Info.plist │ ├── Models │ │ └── User.swift │ ├── SceneDelegate.swift │ ├── ViewModels │ │ ├── Bindings │ │ │ └── Dynamic.swift │ │ └── ViewModel.swift │ └── Views │ │ ├── Stryboards │ │ └── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ └── ViewController.swift └── Readme.md ├── v030-MVVMC_simple ├── MVVM_simple.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── lexone01.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── lexone01.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── MVVM_simple │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Coordinators │ │ ├── AppCoordinator.swift │ │ └── Protocols │ │ │ └── Coordinator.swift │ ├── Info.plist │ ├── Models │ │ ├── User.swift │ │ └── UserData.swift │ ├── ViewModels │ │ ├── Bindings │ │ │ └── Dynamic.swift │ │ ├── DetailViewModel.swift │ │ ├── LoginViewModel.swift │ │ └── MainViewModel.swift │ └── Views │ │ ├── DetailViewController.swift │ │ ├── LoginViewController.swift │ │ ├── MainViewController.swift │ │ ├── Protocols │ │ └── Stoeyboardable.swift │ │ └── Stryboards │ │ └── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard └── Readme.md ├── v039-URLSessionExample ├── Readme.md ├── URLSessionExample.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── lexone01.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── lexone01.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist └── URLSessionExample │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── SceneDelegate.swift │ └── ViewController.swift ├── v052-UnwrappingOptionals └── UnwrapOptional.playground │ ├── Contents.swift │ ├── contents.xcplayground │ ├── playground.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── lexone01.xcuserdatad │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ └── lexone01.xcuserdatad │ └── xcschemes │ └── xcschememanagement.plist ├── v073-MVVM+Combine ├── MVVM_simple.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── MVVM_simple │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json │ ├── Extensions │ └── String+Extension.swift │ ├── Info.plist │ ├── Models │ └── User.swift │ ├── SceneDelegate.swift │ ├── ViewModels │ └── ViewModel.swift │ └── Views │ ├── Stryboards │ └── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ └── ViewController.swift └── v074-SingletonExample ├── SingletonExample.xcodeproj ├── project.pbxproj └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist └── SingletonExample ├── AppDelegate.swift ├── Assets.xcassets ├── AccentColor.colorset │ └── Contents.json ├── AppIcon.appiconset │ └── Contents.json └── Contents.json ├── Base.lproj ├── LaunchScreen.storyboard └── Main.storyboard ├── EditViewController.swift ├── Info.plist ├── SalatCell.swift ├── SalatModel.swift ├── SceneDelegate.swift └── ViewController.swift /.gitignore: -------------------------------------------------------------------------------- 1 | ### Xcode .gitignore ### 2 | 3 | ## User settings 4 | xcuserdata/ 5 | 6 | ## Pods 7 | Pods 8 | Podfile.lock 9 | undo.ios.xcworkspace 10 | 11 | ## Build generated 12 | build/ 13 | DerivedData/ 14 | 15 | ## Xcode 8 and earlier 16 | *.xcscmblueprint 17 | *.xccheckout 18 | 19 | ### Xcode Patch ### 20 | *.xcodeproj/* 21 | !*.xcodeproj/project.pbxproj 22 | !*.xcodeproj/xcshareddata/ 23 | !*.xcworkspace/contents.xcworkspacedata 24 | /*.gcno 25 | **/xcshareddata/WorkspaceSettings.xcsettings 26 | 27 | # Ignore Mac DS_Store files 28 | .DS_Store 29 | *.xcuserstate 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # YoutTube канал "iOS на практике" 2 | 3 | Данный репозиторий содержит ссылки на все мои проекты, которые я освещаю на [YouTube канале](https://www.youtube.com/channel/UCNp8ItQbZqAz97ACiVEe62g). 4 | 5 | Так же вы можете ознакомиться с информацией на [моем сайте](https://www.lexone.ru). 6 | -------------------------------------------------------------------------------- /SimpleCalculator/SimpleCalcFBL/SimpleCalcFBL.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SimpleCalculator/SimpleCalcFBL/SimpleCalcFBL/App/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SimpleCalcFBL 4 | // 5 | // Created by Alex Krzywicki on 03.09.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | @main 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | 13 | 14 | 15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 16 | // Override point for customization after application launch. 17 | return true 18 | } 19 | 20 | // MARK: UISceneSession Lifecycle 21 | 22 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 23 | // Called when a new scene session is being created. 24 | // Use this method to select a configuration to create the new scene with. 25 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 26 | } 27 | 28 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 29 | // Called when the user discards a scene session. 30 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 31 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 32 | } 33 | 34 | 35 | } 36 | 37 | -------------------------------------------------------------------------------- /SimpleCalculator/SimpleCalcFBL/SimpleCalcFBL/App/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.swift 3 | // SimpleCalcFBL 4 | // 5 | // Created by Alex Krzywicki on 03.09.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | class SceneDelegate: UIResponder, UIWindowSceneDelegate { 11 | 12 | var window: UIWindow? 13 | 14 | 15 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 16 | guard let windowScene = (scene as? UIWindowScene) else { return } 17 | let window = UIWindow(windowScene: windowScene) 18 | let viewViewController = ViewController() 19 | window.rootViewController = viewViewController 20 | window.makeKeyAndVisible() 21 | self.window = window 22 | } 23 | 24 | func sceneDidDisconnect(_ scene: UIScene) { 25 | // Called as the scene is being released by the system. 26 | // This occurs shortly after the scene enters the background, or when its session is discarded. 27 | // Release any resources associated with this scene that can be re-created the next time the scene connects. 28 | // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). 29 | } 30 | 31 | func sceneDidBecomeActive(_ scene: UIScene) { 32 | // Called when the scene has moved from an inactive state to an active state. 33 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 34 | } 35 | 36 | func sceneWillResignActive(_ scene: UIScene) { 37 | // Called when the scene will move from an active state to an inactive state. 38 | // This may occur due to temporary interruptions (ex. an incoming phone call). 39 | } 40 | 41 | func sceneWillEnterForeground(_ scene: UIScene) { 42 | // Called as the scene transitions from the background to the foreground. 43 | // Use this method to undo the changes made on entering the background. 44 | } 45 | 46 | func sceneDidEnterBackground(_ scene: UIScene) { 47 | // Called as the scene transitions from the foreground to the background. 48 | // Use this method to save data, release shared resources, and store enough scene-specific state information 49 | // to restore the scene back to its current state. 50 | } 51 | 52 | 53 | } 54 | 55 | -------------------------------------------------------------------------------- /SimpleCalculator/SimpleCalcFBL/SimpleCalcFBL/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SimpleCalculator/SimpleCalcFBL/SimpleCalcFBL/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "2x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "83.5x83.5" 82 | }, 83 | { 84 | "idiom" : "ios-marketing", 85 | "scale" : "1x", 86 | "size" : "1024x1024" 87 | } 88 | ], 89 | "info" : { 90 | "author" : "xcode", 91 | "version" : 1 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /SimpleCalculator/SimpleCalcFBL/SimpleCalcFBL/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /SimpleCalculator/SimpleCalcFBL/SimpleCalcFBL/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIApplicationSceneManifest 6 | 7 | UIApplicationSupportsMultipleScenes 8 | 9 | UISceneConfigurations 10 | 11 | UIWindowSceneSessionRoleApplication 12 | 13 | 14 | UISceneConfigurationName 15 | Default Configuration 16 | UISceneDelegateClassName 17 | $(PRODUCT_MODULE_NAME).SceneDelegate 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /SimpleCalculator/SimpleCalcFBL/SimpleCalcFBL/Model/AppColors.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppColors.swift 3 | // SimpleCalcFBL 4 | // 5 | // Created by Alex Krzywicki on 03.09.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | enum AppColors { 11 | static let background = #colorLiteral(red: 0.3224516809, green: 0.3664748371, blue: 0.4647035599, alpha: 1) 12 | static let buttons = #colorLiteral(red: 0.4680640101, green: 0.5762557387, blue: 0.5453882813, alpha: 1) 13 | static let topButtons = #colorLiteral(red: 0.5731319785, green: 0.7244241834, blue: 0.5732836723, alpha: 1) 14 | static let actions = #colorLiteral(red: 0.9441030622, green: 0.8663714528, blue: 0.7488588691, alpha: 1) 15 | } 16 | -------------------------------------------------------------------------------- /SimpleCalculator/SimpleCalcFBL/SimpleCalcFBL/Model/Constants.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Constants.swift 3 | // SimpleCalcFBL 4 | // 5 | // Created by Alex Krzywicki on 03.09.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | struct Constants { 11 | static let screenRect = UIScreen.main.bounds 12 | static let screenWidth = screenRect.size.width 13 | static let scrennHeight = screenRect.size.height 14 | } 15 | 16 | -------------------------------------------------------------------------------- /SimpleCalculator/SimpleCalcFBL/SimpleCalcFBL/Model/Operations.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Operations.swift 3 | // SimpleCalcFBL 4 | // 5 | // Created by Alex Krzywicki on 03.09.2022. 6 | // 7 | 8 | import Foundation 9 | 10 | enum Operations { 11 | case noAction 12 | case addition 13 | case substraction 14 | case multiplication 15 | case division 16 | } 17 | -------------------------------------------------------------------------------- /SimpleCalculator/SimpleCalcFBL/SimpleCalcFBL/ViewController/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /SwiftUI/LaunchScreeenSwitftUI/LaunchScreeenSwitftUI.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SwiftUI/LaunchScreeenSwitftUI/LaunchScreeenSwitftUI/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SwiftUI/LaunchScreeenSwitftUI/LaunchScreeenSwitftUI/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "platform" : "ios", 6 | "size" : "1024x1024" 7 | }, 8 | { 9 | "appearances" : [ 10 | { 11 | "appearance" : "luminosity", 12 | "value" : "dark" 13 | } 14 | ], 15 | "idiom" : "universal", 16 | "platform" : "ios", 17 | "size" : "1024x1024" 18 | }, 19 | { 20 | "appearances" : [ 21 | { 22 | "appearance" : "luminosity", 23 | "value" : "tinted" 24 | } 25 | ], 26 | "idiom" : "universal", 27 | "platform" : "ios", 28 | "size" : "1024x1024" 29 | } 30 | ], 31 | "info" : { 32 | "author" : "xcode", 33 | "version" : 1 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /SwiftUI/LaunchScreeenSwitftUI/LaunchScreeenSwitftUI/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /SwiftUI/LaunchScreeenSwitftUI/LaunchScreeenSwitftUI/Assets.xcassets/backgroundColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0xD5", 9 | "green" : "0xD5", 10 | "red" : "0xD5" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0x92", 27 | "green" : "0x92", 28 | "red" : "0x92" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /SwiftUI/LaunchScreeenSwitftUI/LaunchScreeenSwitftUI/Assets.xcassets/launchLogo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "LaunchLogo.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /SwiftUI/LaunchScreeenSwitftUI/LaunchScreeenSwitftUI/Assets.xcassets/launchLogo.imageset/LaunchLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lexonerus/ios-on-practice/e37d09dac8cf947f231c2eefcd0766815e4f075c/SwiftUI/LaunchScreeenSwitftUI/LaunchScreeenSwitftUI/Assets.xcassets/launchLogo.imageset/LaunchLogo.png -------------------------------------------------------------------------------- /SwiftUI/LaunchScreeenSwitftUI/LaunchScreeenSwitftUI/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // LaunchScreeenSwitftUI 4 | // 5 | // Created by Alex Krzywicki on 13.10.2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ContentView: View { 11 | var body: some View { 12 | VStack { 13 | Image(systemName: "globe") 14 | .imageScale(.large) 15 | .foregroundStyle(.tint) 16 | Text("Hello, world!") 17 | } 18 | .padding() 19 | } 20 | } 21 | 22 | #Preview { 23 | ContentView() 24 | } 25 | -------------------------------------------------------------------------------- /SwiftUI/LaunchScreeenSwitftUI/LaunchScreeenSwitftUI/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UILaunchScreen 6 | 7 | UIColorName 8 | backgroundColor 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /SwiftUI/LaunchScreeenSwitftUI/LaunchScreeenSwitftUI/LaunchScreeenSwitftUIApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LaunchScreeenSwitftUIApp.swift 3 | // LaunchScreeenSwitftUI 4 | // 5 | // Created by Alex Krzywicki on 13.10.2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | @main 11 | struct LaunchScreeenSwitftUIApp: App { 12 | var body: some Scene { 13 | WindowGroup { 14 | LaunchScreenView() 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /SwiftUI/LaunchScreeenSwitftUI/LaunchScreeenSwitftUI/LaunchScreenView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LaunchScreenView.swift 3 | // LaunchScreeenSwitftUI 4 | // 5 | // Created by Alex Krzywicki on 13.10.2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct LaunchScreenView: View { 11 | 12 | @State var isFirstLaunch: Bool = true 13 | @State private var size = 0.8 14 | @State private var opacity = 0.4 15 | 16 | var body: some View { 17 | if !isFirstLaunch { 18 | ContentView() 19 | } else { 20 | ZStack { 21 | Color(.background) 22 | .ignoresSafeArea() 23 | VStack { 24 | Image("launchLogo") 25 | .resizable() 26 | .frame(width: 64, height: 64) 27 | .scaleEffect(size) 28 | } 29 | .opacity(opacity) 30 | .onAppear { 31 | withAnimation(.easeInOut(duration: 1.0)) { 32 | self.size = 1.2 33 | self.opacity = 1.0 34 | } 35 | DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { 36 | withAnimation { 37 | self.isFirstLaunch = false 38 | } 39 | } 40 | } 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /SwiftUI/LaunchScreeenSwitftUI/LaunchScreeenSwitftUI/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /UIKit/v057-UiSearchBarTutorial/UiSearchBarTutorial.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /UIKit/v057-UiSearchBarTutorial/UiSearchBarTutorial.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /UIKit/v057-UiSearchBarTutorial/UiSearchBarTutorial.xcodeproj/project.xcworkspace/xcuserdata/lexone01.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lexonerus/ios-on-practice/e37d09dac8cf947f231c2eefcd0766815e4f075c/UIKit/v057-UiSearchBarTutorial/UiSearchBarTutorial.xcodeproj/project.xcworkspace/xcuserdata/lexone01.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /UIKit/v057-UiSearchBarTutorial/UiSearchBarTutorial.xcodeproj/xcuserdata/lexone01.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | UiSearchBarTutorial.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /UIKit/v057-UiSearchBarTutorial/UiSearchBarTutorial/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // UiSearchBarTutorial 4 | // 5 | // Created by Alex Krzywicki on 13.06.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | @main 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | 13 | 14 | 15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 16 | // Override point for customization after application launch. 17 | return true 18 | } 19 | 20 | // MARK: UISceneSession Lifecycle 21 | 22 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 23 | // Called when a new scene session is being created. 24 | // Use this method to select a configuration to create the new scene with. 25 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 26 | } 27 | 28 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 29 | // Called when the user discards a scene session. 30 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 31 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 32 | } 33 | 34 | 35 | } 36 | 37 | -------------------------------------------------------------------------------- /UIKit/v057-UiSearchBarTutorial/UiSearchBarTutorial/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /UIKit/v057-UiSearchBarTutorial/UiSearchBarTutorial/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "2x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "83.5x83.5" 82 | }, 83 | { 84 | "idiom" : "ios-marketing", 85 | "scale" : "1x", 86 | "size" : "1024x1024" 87 | } 88 | ], 89 | "info" : { 90 | "author" : "xcode", 91 | "version" : 1 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /UIKit/v057-UiSearchBarTutorial/UiSearchBarTutorial/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /UIKit/v057-UiSearchBarTutorial/UiSearchBarTutorial/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /UIKit/v057-UiSearchBarTutorial/UiSearchBarTutorial/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIApplicationSceneManifest 6 | 7 | UIApplicationSupportsMultipleScenes 8 | 9 | UISceneConfigurations 10 | 11 | UIWindowSceneSessionRoleApplication 12 | 13 | 14 | UISceneConfigurationName 15 | Default Configuration 16 | UISceneDelegateClassName 17 | $(PRODUCT_MODULE_NAME).SceneDelegate 18 | UISceneStoryboardFile 19 | Main 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /UIKit/v057-UiSearchBarTutorial/UiSearchBarTutorial/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.swift 3 | // UiSearchBarTutorial 4 | // 5 | // Created by Alex Krzywicki on 13.06.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | class SceneDelegate: UIResponder, UIWindowSceneDelegate { 11 | 12 | var window: UIWindow? 13 | 14 | 15 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 16 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. 17 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. 18 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). 19 | guard let _ = (scene as? UIWindowScene) else { return } 20 | } 21 | 22 | func sceneDidDisconnect(_ scene: UIScene) { 23 | // Called as the scene is being released by the system. 24 | // This occurs shortly after the scene enters the background, or when its session is discarded. 25 | // Release any resources associated with this scene that can be re-created the next time the scene connects. 26 | // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). 27 | } 28 | 29 | func sceneDidBecomeActive(_ scene: UIScene) { 30 | // Called when the scene has moved from an inactive state to an active state. 31 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 32 | } 33 | 34 | func sceneWillResignActive(_ scene: UIScene) { 35 | // Called when the scene will move from an active state to an inactive state. 36 | // This may occur due to temporary interruptions (ex. an incoming phone call). 37 | } 38 | 39 | func sceneWillEnterForeground(_ scene: UIScene) { 40 | // Called as the scene transitions from the background to the foreground. 41 | // Use this method to undo the changes made on entering the background. 42 | } 43 | 44 | func sceneDidEnterBackground(_ scene: UIScene) { 45 | // Called as the scene transitions from the foreground to the background. 46 | // Use this method to save data, release shared resources, and store enough scene-specific state information 47 | // to restore the scene back to its current state. 48 | } 49 | 50 | 51 | } 52 | 53 | -------------------------------------------------------------------------------- /UIKit/v061-UIKitWithSWiftUI/SwiftUIintegration/SwiftUIintegration.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /UIKit/v061-UIKitWithSWiftUI/SwiftUIintegration/SwiftUIintegration.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /UIKit/v061-UIKitWithSWiftUI/SwiftUIintegration/SwiftUIintegration.xcodeproj/project.xcworkspace/xcuserdata/lexone01.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lexonerus/ios-on-practice/e37d09dac8cf947f231c2eefcd0766815e4f075c/UIKit/v061-UIKitWithSWiftUI/SwiftUIintegration/SwiftUIintegration.xcodeproj/project.xcworkspace/xcuserdata/lexone01.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /UIKit/v061-UIKitWithSWiftUI/SwiftUIintegration/SwiftUIintegration.xcodeproj/xcuserdata/lexone01.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SwiftUIintegration.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /UIKit/v061-UIKitWithSWiftUI/SwiftUIintegration/SwiftUIintegration/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SwiftUIintegration 4 | // 5 | // Created by Alex Krzywicki on 10.07.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | @main 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | 13 | 14 | 15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 16 | // Override point for customization after application launch. 17 | return true 18 | } 19 | 20 | // MARK: UISceneSession Lifecycle 21 | 22 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 23 | // Called when a new scene session is being created. 24 | // Use this method to select a configuration to create the new scene with. 25 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 26 | } 27 | 28 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 29 | // Called when the user discards a scene session. 30 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 31 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 32 | } 33 | 34 | 35 | } 36 | 37 | -------------------------------------------------------------------------------- /UIKit/v061-UIKitWithSWiftUI/SwiftUIintegration/SwiftUIintegration/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /UIKit/v061-UIKitWithSWiftUI/SwiftUIintegration/SwiftUIintegration/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "2x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "83.5x83.5" 82 | }, 83 | { 84 | "idiom" : "ios-marketing", 85 | "scale" : "1x", 86 | "size" : "1024x1024" 87 | } 88 | ], 89 | "info" : { 90 | "author" : "xcode", 91 | "version" : 1 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /UIKit/v061-UIKitWithSWiftUI/SwiftUIintegration/SwiftUIintegration/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /UIKit/v061-UIKitWithSWiftUI/SwiftUIintegration/SwiftUIintegration/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /UIKit/v061-UIKitWithSWiftUI/SwiftUIintegration/SwiftUIintegration/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIApplicationSceneManifest 6 | 7 | UIApplicationSupportsMultipleScenes 8 | 9 | UISceneConfigurations 10 | 11 | UIWindowSceneSessionRoleApplication 12 | 13 | 14 | UISceneConfigurationName 15 | Default Configuration 16 | UISceneDelegateClassName 17 | $(PRODUCT_MODULE_NAME).SceneDelegate 18 | UISceneStoryboardFile 19 | Main 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /UIKit/v061-UIKitWithSWiftUI/SwiftUIintegration/SwiftUIintegration/SwiftUIView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwiftUIView.swift 3 | // SwiftUIintegration 4 | // 5 | // Created by Alex Krzywicki on 10.07.2022. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct SwiftUIView: View { 11 | var body: some View { 12 | Text("Hello from SwiftUI!") 13 | } 14 | } 15 | 16 | struct SwiftUIView_Previews: PreviewProvider { 17 | static var previews: some View { 18 | SwiftUIView() 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /UIKit/v061-UIKitWithSWiftUI/SwiftUIintegration/SwiftUIintegration/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // SwiftUIintegration 4 | // 5 | // Created by Alex Krzywicki on 10.07.2022. 6 | // 7 | 8 | import UIKit 9 | import SwiftUI 10 | 11 | class ViewController: UIViewController { 12 | 13 | @IBOutlet weak var firstLabel: UILabel! 14 | 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | firstLabel.text = "Hello from UIKit View!" 18 | 19 | } 20 | 21 | @IBAction func pushButtonPressed(_ sender: Any) { 22 | let host = UIHostingController(rootView: SwiftUIView()) 23 | navigationController?.pushViewController(host, animated: true) 24 | } 25 | 26 | @IBSegueAction func segueToSwiftUI(_ coder: NSCoder) -> UIViewController? { 27 | return UIHostingController(coder: coder, rootView: SwiftUIView()) 28 | } 29 | 30 | } 31 | 32 | -------------------------------------------------------------------------------- /UIKit/v064-UIKitProgrammatically/UIKitProgrammatically.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /UIKit/v064-UIKitProgrammatically/UIKitProgrammatically.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /UIKit/v064-UIKitProgrammatically/UIKitProgrammatically.xcodeproj/project.xcworkspace/xcuserdata/lexone01.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lexonerus/ios-on-practice/e37d09dac8cf947f231c2eefcd0766815e4f075c/UIKit/v064-UIKitProgrammatically/UIKitProgrammatically.xcodeproj/project.xcworkspace/xcuserdata/lexone01.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /UIKit/v064-UIKitProgrammatically/UIKitProgrammatically.xcodeproj/xcuserdata/lexone01.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | UIKitProgrammatically.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /UIKit/v064-UIKitProgrammatically/UIKitProgrammatically/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // UIKitProgrammatically 4 | // 5 | // Created by Alex Krzywicki on 24.07.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | @main 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | 13 | 14 | 15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 16 | // Override point for customization after application launch. 17 | return true 18 | } 19 | 20 | // MARK: UISceneSession Lifecycle 21 | 22 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 23 | // Called when a new scene session is being created. 24 | // Use this method to select a configuration to create the new scene with. 25 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 26 | } 27 | 28 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 29 | // Called when the user discards a scene session. 30 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 31 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 32 | } 33 | 34 | 35 | } 36 | 37 | -------------------------------------------------------------------------------- /UIKit/v064-UIKitProgrammatically/UIKitProgrammatically/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /UIKit/v064-UIKitProgrammatically/UIKitProgrammatically/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "2x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "83.5x83.5" 82 | }, 83 | { 84 | "idiom" : "ios-marketing", 85 | "scale" : "1x", 86 | "size" : "1024x1024" 87 | } 88 | ], 89 | "info" : { 90 | "author" : "xcode", 91 | "version" : 1 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /UIKit/v064-UIKitProgrammatically/UIKitProgrammatically/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /UIKit/v064-UIKitProgrammatically/UIKitProgrammatically/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /UIKit/v064-UIKitProgrammatically/UIKitProgrammatically/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIApplicationSceneManifest 6 | 7 | UIApplicationSupportsMultipleScenes 8 | 9 | UISceneConfigurations 10 | 11 | UIWindowSceneSessionRoleApplication 12 | 13 | 14 | UISceneConfigurationName 15 | Default Configuration 16 | UISceneDelegateClassName 17 | $(PRODUCT_MODULE_NAME).SceneDelegate 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /UIKit/v064-UIKitProgrammatically/UIKitProgrammatically/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // UIKitProgrammatically 4 | // 5 | // Created by Alex Krzywicki on 24.07.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | class ViewController: UIViewController { 11 | 12 | override func viewDidLoad() { 13 | super.viewDidLoad() 14 | view.backgroundColor = .blue 15 | // Do any additional setup after loading the view. 16 | } 17 | 18 | 19 | } 20 | 21 | -------------------------------------------------------------------------------- /UIKit/v066-UIKit-Frame-Based-Layout/UIKitProgrammatically.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /UIKit/v066-UIKit-Frame-Based-Layout/UIKitProgrammatically.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /UIKit/v066-UIKit-Frame-Based-Layout/UIKitProgrammatically.xcodeproj/project.xcworkspace/xcuserdata/lexone01.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lexonerus/ios-on-practice/e37d09dac8cf947f231c2eefcd0766815e4f075c/UIKit/v066-UIKit-Frame-Based-Layout/UIKitProgrammatically.xcodeproj/project.xcworkspace/xcuserdata/lexone01.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /UIKit/v066-UIKit-Frame-Based-Layout/UIKitProgrammatically.xcodeproj/xcuserdata/lexone01.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /UIKit/v066-UIKit-Frame-Based-Layout/UIKitProgrammatically.xcodeproj/xcuserdata/lexone01.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | UIKitProgrammatically.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /UIKit/v066-UIKit-Frame-Based-Layout/UIKitProgrammatically/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // UIKitProgrammatically 4 | // 5 | // Created by Alex Krzywicki on 24.07.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | @main 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | 13 | 14 | 15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 16 | // Override point for customization after application launch. 17 | return true 18 | } 19 | 20 | // MARK: UISceneSession Lifecycle 21 | 22 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 23 | // Called when a new scene session is being created. 24 | // Use this method to select a configuration to create the new scene with. 25 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 26 | } 27 | 28 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 29 | // Called when the user discards a scene session. 30 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 31 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 32 | } 33 | 34 | 35 | } 36 | 37 | -------------------------------------------------------------------------------- /UIKit/v066-UIKit-Frame-Based-Layout/UIKitProgrammatically/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /UIKit/v066-UIKit-Frame-Based-Layout/UIKitProgrammatically/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "2x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "83.5x83.5" 82 | }, 83 | { 84 | "idiom" : "ios-marketing", 85 | "scale" : "1x", 86 | "size" : "1024x1024" 87 | } 88 | ], 89 | "info" : { 90 | "author" : "xcode", 91 | "version" : 1 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /UIKit/v066-UIKit-Frame-Based-Layout/UIKitProgrammatically/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /UIKit/v066-UIKit-Frame-Based-Layout/UIKitProgrammatically/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /UIKit/v066-UIKit-Frame-Based-Layout/UIKitProgrammatically/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIApplicationSceneManifest 6 | 7 | UIApplicationSupportsMultipleScenes 8 | 9 | UISceneConfigurations 10 | 11 | UIWindowSceneSessionRoleApplication 12 | 13 | 14 | UISceneConfigurationName 15 | Default Configuration 16 | UISceneDelegateClassName 17 | $(PRODUCT_MODULE_NAME).SceneDelegate 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /UIKit/v066-UIKit-Frame-Based-Layout/UIKitProgrammatically/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // UIKitProgrammatically 4 | // 5 | // Created by Alex Krzywicki on 24.07.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | class ViewController: UIViewController { 11 | 12 | let newView = UIView() 13 | let textField = UITextField() 14 | let textField2 = UITextField() 15 | let frame = UIScreen.main.bounds 16 | 17 | 18 | override func viewDidLoad() { 19 | super.viewDidLoad() 20 | view.backgroundColor = #colorLiteral(red: 0.2588235438, green: 0.7568627596, blue: 0.9686274529, alpha: 1) 21 | view.addSubview(newView) 22 | print(frame) 23 | 24 | let size = CGSize(width: 300, height: 300) 25 | let point = CGPoint(x: (frame.width/2-(size.width/2)), y: (frame.height/2-(size.height/2))) 26 | 27 | newView.frame = CGRect(origin: point, size: size) 28 | newView.backgroundColor = #colorLiteral(red: 0.721568644, green: 0.8862745166, blue: 0.5921568871, alpha: 1) 29 | 30 | newView.addSubview(textField) 31 | newView.addSubview(textField2) 32 | textField.frame = CGRect(x: 5, y: 5, width: 290, height: 50) 33 | textField.text = "x: \(newView.frame.minX) y: \(newView.frame.minY) w: \(newView.frame.width) h: \(newView.frame.height)" 34 | 35 | textField2.frame = CGRect(x: 5, y: 60, width: 290, height: 50) 36 | textField2.text = "x: \(newView.bounds.minX) y: \(newView.bounds.minY) w: \(newView.bounds.width) h: \(newView.bounds.height)" 37 | 38 | textField.backgroundColor = #colorLiteral(red: 0.9764705896, green: 0.850980401, blue: 0.5490196347, alpha: 1) 39 | textField2.backgroundColor = #colorLiteral(red: 0.9568627477, green: 0.6588235497, blue: 0.5450980663, alpha: 1) 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | } 48 | 49 | 50 | } 51 | 52 | -------------------------------------------------------------------------------- /UIKit/v077-IntrinsicContentSize/IntrinsicContentSize/IntrinsicContentSize.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /UIKit/v077-IntrinsicContentSize/IntrinsicContentSize/IntrinsicContentSize.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /UIKit/v077-IntrinsicContentSize/IntrinsicContentSize/IntrinsincContentSize/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // IntrinsincContentSize 4 | // 5 | // Created by Alexey Krzywicki on 11.03.2023. 6 | // 7 | 8 | import UIKit 9 | 10 | @main 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | 13 | 14 | 15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 16 | // Override point for customization after application launch. 17 | return true 18 | } 19 | 20 | // MARK: UISceneSession Lifecycle 21 | 22 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 23 | // Called when a new scene session is being created. 24 | // Use this method to select a configuration to create the new scene with. 25 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 26 | } 27 | 28 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 29 | // Called when the user discards a scene session. 30 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 31 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 32 | } 33 | 34 | 35 | } 36 | 37 | -------------------------------------------------------------------------------- /UIKit/v077-IntrinsicContentSize/IntrinsicContentSize/IntrinsincContentSize/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /UIKit/v077-IntrinsicContentSize/IntrinsicContentSize/IntrinsincContentSize/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "platform" : "ios", 6 | "size" : "1024x1024" 7 | } 8 | ], 9 | "info" : { 10 | "author" : "xcode", 11 | "version" : 1 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /UIKit/v077-IntrinsicContentSize/IntrinsicContentSize/IntrinsincContentSize/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /UIKit/v077-IntrinsicContentSize/IntrinsicContentSize/IntrinsincContentSize/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /UIKit/v077-IntrinsicContentSize/IntrinsicContentSize/IntrinsincContentSize/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIApplicationSceneManifest 6 | 7 | UIApplicationSupportsMultipleScenes 8 | 9 | UISceneConfigurations 10 | 11 | UIWindowSceneSessionRoleApplication 12 | 13 | 14 | UISceneConfigurationName 15 | Default Configuration 16 | UISceneDelegateClassName 17 | $(PRODUCT_MODULE_NAME).SceneDelegate 18 | UISceneStoryboardFile 19 | Main 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /UIKit/v077-IntrinsicContentSize/IntrinsicContentSize/IntrinsincContentSize/UIDynamicLabel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIDynamicLabel.swift 3 | // IntrinsincContentSize 4 | // 5 | // Created by Alexey Krzywicki on 11.03.2023. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class UIDynamicLabel: UILabel { 12 | override var intrinsicContentSize: CGSize { 13 | let size = self.sizeThatFits(CGSize(width: self.frame.size.width, height: CGFloat.greatestFiniteMagnitude)) 14 | return CGSize(width: size.width, height: size.height + 5) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /UIKit/v077-IntrinsicContentSize/IntrinsicContentSize/IntrinsincContentSize/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // IntrinsincContentSize 4 | // 5 | // Created by Alexey Krzywicki on 11.03.2023. 6 | // 7 | 8 | import UIKit 9 | 10 | class ViewController: UIViewController { 11 | 12 | @IBOutlet weak var labelHeightCT: NSLayoutConstraint! 13 | @IBOutlet weak var label: UIDynamicLabel! 14 | 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | 18 | label.text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. " 19 | 20 | labelHeightCT.constant = label.intrinsicContentSize.height 21 | label.layoutIfNeeded() 22 | 23 | print("intrinsicContentSize: \(label.intrinsicContentSize)") 24 | print("Frame: \(label.frame)") 25 | } 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /UIKit/v78-UIScrollView/UIScrollViewProgrammatically/UIScrollViewProgrammatically.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /UIKit/v78-UIScrollView/UIScrollViewProgrammatically/UIScrollViewProgrammatically.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /UIKit/v78-UIScrollView/UIScrollViewProgrammatically/UIScrollViewProgrammatically/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // UIScrollViewProgrammatically 4 | // 5 | // Created by Alexey Krzywicki on 02.04.2023. 6 | // 7 | 8 | import UIKit 9 | 10 | @main 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | 13 | 14 | 15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 16 | // Override point for customization after application launch. 17 | return true 18 | } 19 | 20 | // MARK: UISceneSession Lifecycle 21 | 22 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 23 | // Called when a new scene session is being created. 24 | // Use this method to select a configuration to create the new scene with. 25 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 26 | } 27 | 28 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 29 | // Called when the user discards a scene session. 30 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 31 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 32 | } 33 | 34 | 35 | } 36 | 37 | -------------------------------------------------------------------------------- /UIKit/v78-UIScrollView/UIScrollViewProgrammatically/UIScrollViewProgrammatically/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /UIKit/v78-UIScrollView/UIScrollViewProgrammatically/UIScrollViewProgrammatically/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "platform" : "ios", 6 | "size" : "1024x1024" 7 | } 8 | ], 9 | "info" : { 10 | "author" : "xcode", 11 | "version" : 1 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /UIKit/v78-UIScrollView/UIScrollViewProgrammatically/UIScrollViewProgrammatically/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /UIKit/v78-UIScrollView/UIScrollViewProgrammatically/UIScrollViewProgrammatically/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /UIKit/v78-UIScrollView/UIScrollViewProgrammatically/UIScrollViewProgrammatically/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /UIKit/v78-UIScrollView/UIScrollViewProgrammatically/UIScrollViewProgrammatically/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIApplicationSceneManifest 6 | 7 | UIApplicationSupportsMultipleScenes 8 | 9 | UISceneConfigurations 10 | 11 | UIWindowSceneSessionRoleApplication 12 | 13 | 14 | UISceneConfigurationName 15 | Default Configuration 16 | UISceneDelegateClassName 17 | $(PRODUCT_MODULE_NAME).SceneDelegate 18 | UISceneStoryboardFile 19 | Main 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /UIKit/v83-@discarableResult/DiscarableResult/DiscarableResult.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /UIKit/v83-@discarableResult/DiscarableResult/DiscarableResult.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /UIKit/v83-@discarableResult/DiscarableResult/DiscarableResult/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // DiscarableResult 4 | // 5 | // Created by Alexey Krzywicki on 23.07.2023. 6 | // 7 | 8 | import UIKit 9 | 10 | @main 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | 13 | 14 | 15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 16 | // Override point for customization after application launch. 17 | return true 18 | } 19 | 20 | // MARK: UISceneSession Lifecycle 21 | 22 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 23 | // Called when a new scene session is being created. 24 | // Use this method to select a configuration to create the new scene with. 25 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 26 | } 27 | 28 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 29 | // Called when the user discards a scene session. 30 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 31 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 32 | } 33 | 34 | 35 | } 36 | 37 | -------------------------------------------------------------------------------- /UIKit/v83-@discarableResult/DiscarableResult/DiscarableResult/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /UIKit/v83-@discarableResult/DiscarableResult/DiscarableResult/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "platform" : "ios", 6 | "size" : "1024x1024" 7 | } 8 | ], 9 | "info" : { 10 | "author" : "xcode", 11 | "version" : 1 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /UIKit/v83-@discarableResult/DiscarableResult/DiscarableResult/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /UIKit/v83-@discarableResult/DiscarableResult/DiscarableResult/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /UIKit/v83-@discarableResult/DiscarableResult/DiscarableResult/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /UIKit/v83-@discarableResult/DiscarableResult/DiscarableResult/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIApplicationSceneManifest 6 | 7 | UIApplicationSupportsMultipleScenes 8 | 9 | UISceneConfigurations 10 | 11 | UIWindowSceneSessionRoleApplication 12 | 13 | 14 | UISceneConfigurationName 15 | Default Configuration 16 | UISceneDelegateClassName 17 | $(PRODUCT_MODULE_NAME).SceneDelegate 18 | UISceneStoryboardFile 19 | Main 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /UIKit/v84-Netfox+SwiftPM/DiscarableResult/DiscarableResult.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /UIKit/v84-Netfox+SwiftPM/DiscarableResult/DiscarableResult.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /UIKit/v84-Netfox+SwiftPM/DiscarableResult/DiscarableResult.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "pins" : [ 3 | { 4 | "identity" : "netfox", 5 | "kind" : "remoteSourceControl", 6 | "location" : "https://github.com/kasketis/netfox", 7 | "state" : { 8 | "revision" : "557576032736fd3140422baefb68b8f76c55088f", 9 | "version" : "1.21.0" 10 | } 11 | } 12 | ], 13 | "version" : 2 14 | } 15 | -------------------------------------------------------------------------------- /UIKit/v84-Netfox+SwiftPM/DiscarableResult/DiscarableResult/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // DiscarableResult 4 | // 5 | // Created by Alexey Krzywicki on 23.07.2023. 6 | // 7 | 8 | import UIKit 9 | import netfox 10 | 11 | @main 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | 15 | 16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 17 | // Override point for customization after application launch. 18 | NFX.sharedInstance().start() 19 | return true 20 | } 21 | 22 | // MARK: UISceneSession Lifecycle 23 | 24 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 25 | // Called when a new scene session is being created. 26 | // Use this method to select a configuration to create the new scene with. 27 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 28 | } 29 | 30 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 31 | // Called when the user discards a scene session. 32 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 33 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 34 | } 35 | 36 | 37 | } 38 | 39 | -------------------------------------------------------------------------------- /UIKit/v84-Netfox+SwiftPM/DiscarableResult/DiscarableResult/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /UIKit/v84-Netfox+SwiftPM/DiscarableResult/DiscarableResult/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "platform" : "ios", 6 | "size" : "1024x1024" 7 | } 8 | ], 9 | "info" : { 10 | "author" : "xcode", 11 | "version" : 1 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /UIKit/v84-Netfox+SwiftPM/DiscarableResult/DiscarableResult/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /UIKit/v84-Netfox+SwiftPM/DiscarableResult/DiscarableResult/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /UIKit/v84-Netfox+SwiftPM/DiscarableResult/DiscarableResult/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIApplicationSceneManifest 6 | 7 | UIApplicationSupportsMultipleScenes 8 | 9 | UISceneConfigurations 10 | 11 | UIWindowSceneSessionRoleApplication 12 | 13 | 14 | UISceneConfigurationName 15 | Default Configuration 16 | UISceneDelegateClassName 17 | $(PRODUCT_MODULE_NAME).SceneDelegate 18 | UISceneStoryboardFile 19 | Main 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /algorithms-on-swift/README.md: -------------------------------------------------------------------------------- 1 | # EN 🇬🇧 Algorithms written on swift 2 | This project include realization of basic algorithms 3 | written on Swift language. 4 | 5 | List of algos: 6 | - [Binary search](https://github.com/lexonerus/ios-on-practice/blob/main/algorithms-on-swift/v004-Binary-search/BinarySearch.swift) 7 | 8 | 9 | # RU 🇷🇺 Алгоритмы написанные на Swift 10 | Данный проект включает в себя реализацию различных 11 | базовых алогоритмов, написанных с помощью 12 | языка программирования Swift. 13 | 14 | Список алгоритмов: 15 | - [Бинарный поиск](https://github.com/lexonerus/ios-on-practice/blob/main/algorithms-on-swift/v004-Binary-search/BinarySearch.swift) 16 | -------------------------------------------------------------------------------- /algorithms-on-swift/v004-Binary-search/BinarySearch.swift: -------------------------------------------------------------------------------- 1 | /* 2 | 21.04.2021 3 | Alexey Krzywicki 4 | binary search algorithm in Swift 5 | */ 6 | 7 | import Foundation 8 | 9 | var greeting = "Hello, playground" 10 | 11 | var list: [Int] = [] 12 | 13 | func binarySearch(list: Array, item: Int) -> Any { 14 | var low = 0 15 | var high = list.count - 1 16 | 17 | while low <= high { 18 | let mid = (low + high) / 2 19 | let guess = list[mid] 20 | if guess == item { 21 | return "item found at index - \(mid + 1)" 22 | } 23 | if guess > item { 24 | high = mid - 1 25 | } else { 26 | low = mid + 1 27 | } 28 | 29 | } 30 | 31 | return "item doesnt exist" 32 | 33 | } 34 | 35 | 36 | // test 37 | 38 | list = [1, 2, 3, 23, 24, 26, 35, 40, 55, 74, 78, 99] 39 | var result = binarySearch(list: list, item: 99) 40 | 41 | print(result) 42 | 43 | 44 | // For search in 4bil-list you need only 32 guesses!.. 45 | print(log2(Double(4000000000))) 46 | -------------------------------------------------------------------------------- /algorithms-on-swift/v004-Binary-search/README.md: -------------------------------------------------------------------------------- 1 | # Алгоритм бинарного поиска 2 | 3 | *Данный материал является дополнением к видеоматериалу на [YouTube](https://youtu.be/KDXjjOT4aFU)* 4 | 5 | ## Инструкция по установке 6 | 7 | - Необходимо скачать или клонировать весь проект [ios на практике](https://github.com/lexonerus/ios-on-practice) 8 | - Перейти в каталог /ios-on-practice/algorithms-on-swift/v004-Binary-search/ 9 | - Затем открыть файл BinarySearch.swift с помощью SwiftPlayground или через любой другой удобный редактор. 10 | Так же код можно запустить через терминал. 11 | 12 | 13 | Подписывайтесь на мой YouTube канал. 14 | -------------------------------------------------------------------------------- /algorithms-on-swift/v011-Butterfly/ButterflyPattern.swift: -------------------------------------------------------------------------------- 1 | // Batterfly pattern on swift 2 | 3 | var row: Int = 0 4 | var input: Int? 5 | 6 | print("Enter a number of rows: ") 7 | 8 | if let input = Int(readLine()!) { 9 | row = input 10 | } 11 | 12 | print("You entered - \(row)") 13 | // Upper part 14 | for i in (0...row) { 15 | for j in 1...(2*row-1) { 16 | if (j>=i) && (j<=2*row-i) { 17 | print(" ", terminator: "") 18 | } else { 19 | print("0", terminator: "") 20 | } 21 | } 22 | print("") 23 | } 24 | 25 | // Lower part 26 | for i in (0...row).reversed() { 27 | for j in (1...(2*row-1)).reversed() { 28 | if (j>=i) && (j<=2*row-i) { 29 | print(" ", terminator: "") 30 | } else { 31 | print("0", terminator: "") 32 | } 33 | } 34 | print("") 35 | } 36 | -------------------------------------------------------------------------------- /algorithms-on-swift/v011-Butterfly/README.md: -------------------------------------------------------------------------------- 1 | # EN Implementation Butterfly algorithm on Swift 2 | 3 | 4 | ## How to 5 | Open in terminal like this: `swift ButterflyPattern.swift` 6 | Enter amount of rows. 7 | 8 | Windows example: 9 | ``` 10 | (swift) C:\Swift\dev>swift ButterflyPattern.swift 11 | Enter a number of rows: 12 | 5 13 | You entered - 5 14 | 15 | 16 | 0 0 17 | 00 00 18 | 000 000 19 | 0000 0000 20 | 0000 0000 21 | 000 000 22 | 00 00 23 | 0 0 24 | ``` 25 | 26 | 27 | 28 | # RU Алгоритмы написанные на Swift 29 | Реализация алгоритма Бабочка на языке Swift. 30 | 31 | ## Как использовать 32 | Открыть в консоли с помощью `swift ButterflyPattern.swift` 33 | На запрос количества строк вводим любое число. 34 | 35 | Пример на Windows: 36 | ``` 37 | (swift) C:\Swift\dev>swift ButterflyPattern.swift 38 | Enter a number of rows: 39 | 5 40 | You entered - 5 41 | 42 | 43 | 0 0 44 | 00 00 45 | 000 000 46 | 0000 0000 47 | 0000 0000 48 | 000 000 49 | 00 00 50 | 0 0 51 | ``` 52 | -------------------------------------------------------------------------------- /patterns-and-architectures/v001-True-Delegation-Story/README.md: -------------------------------------------------------------------------------- 1 | # Делегирование на Swift, iOS разработка, Playground 2 | 3 | *Данный материал является дополнением к видеоматериалу на [YouTube](https://youtu.be/Zv5wBYVYdEU)* 4 | 5 | ## Инструкция по установке 6 | 7 | - Необходимо скачать или клонировать весь проект [ios на практике](https://github.com/lexonerus/ios-on-practice) 8 | - Перейти в каталог /patterns-and-architectures/v001-True-Delegation-Story/ 9 | - Затем открыть файл TrueDelegationStory.swift с помощью SwiftPlayground или через любой другой удобный редактор. 10 | Так же код можно запустить через терминал. 11 | 12 | Подписывайтесь на мой YouTube канал. 13 | -------------------------------------------------------------------------------- /patterns-and-architectures/v002-MVP/LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /patterns-and-architectures/v002-MVP/MVP-v002.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /patterns-and-architectures/v002-MVP/MVP-v002.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /patterns-and-architectures/v002-MVP/MVP-v002.xcodeproj/project.xcworkspace/xcuserdata/lexone01.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lexonerus/ios-on-practice/e37d09dac8cf947f231c2eefcd0766815e4f075c/patterns-and-architectures/v002-MVP/MVP-v002.xcodeproj/project.xcworkspace/xcuserdata/lexone01.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /patterns-and-architectures/v002-MVP/MVP-v002.xcodeproj/xcuserdata/lexone01.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | MVP-v002.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /patterns-and-architectures/v002-MVP/MVP-v002/App/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // MVP-v002 4 | // 5 | // Created by Alex Krzywicki on 09.10.2021. 6 | // 7 | 8 | import UIKit 9 | 10 | @main 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | 13 | 14 | 15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 16 | // Override point for customization after application launch. 17 | return true 18 | } 19 | 20 | // MARK: UISceneSession Lifecycle 21 | 22 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 23 | // Called when a new scene session is being created. 24 | // Use this method to select a configuration to create the new scene with. 25 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 26 | } 27 | 28 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 29 | // Called when the user discards a scene session. 30 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 31 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 32 | } 33 | 34 | 35 | } 36 | 37 | -------------------------------------------------------------------------------- /patterns-and-architectures/v002-MVP/MVP-v002/App/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.swift 3 | // MVP-v002 4 | // 5 | // Created by Alex Krzywicki on 09.10.2021. 6 | // 7 | 8 | import UIKit 9 | 10 | class SceneDelegate: UIResponder, UIWindowSceneDelegate { 11 | 12 | var window: UIWindow? 13 | 14 | 15 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 16 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. 17 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. 18 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). 19 | guard let _ = (scene as? UIWindowScene) else { return } 20 | } 21 | 22 | func sceneDidDisconnect(_ scene: UIScene) { 23 | // Called as the scene is being released by the system. 24 | // This occurs shortly after the scene enters the background, or when its session is discarded. 25 | // Release any resources associated with this scene that can be re-created the next time the scene connects. 26 | // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). 27 | } 28 | 29 | func sceneDidBecomeActive(_ scene: UIScene) { 30 | // Called when the scene has moved from an inactive state to an active state. 31 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 32 | } 33 | 34 | func sceneWillResignActive(_ scene: UIScene) { 35 | // Called when the scene will move from an active state to an inactive state. 36 | // This may occur due to temporary interruptions (ex. an incoming phone call). 37 | } 38 | 39 | func sceneWillEnterForeground(_ scene: UIScene) { 40 | // Called as the scene transitions from the background to the foreground. 41 | // Use this method to undo the changes made on entering the background. 42 | } 43 | 44 | func sceneDidEnterBackground(_ scene: UIScene) { 45 | // Called as the scene transitions from the foreground to the background. 46 | // Use this method to save data, release shared resources, and store enough scene-specific state information 47 | // to restore the scene back to its current state. 48 | } 49 | 50 | 51 | } 52 | 53 | -------------------------------------------------------------------------------- /patterns-and-architectures/v002-MVP/MVP-v002/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /patterns-and-architectures/v002-MVP/MVP-v002/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | } 93 | ], 94 | "info" : { 95 | "author" : "xcode", 96 | "version" : 1 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /patterns-and-architectures/v002-MVP/MVP-v002/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /patterns-and-architectures/v002-MVP/MVP-v002/Assets.xcassets/my_logo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "my_logo.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /patterns-and-architectures/v002-MVP/MVP-v002/Assets.xcassets/my_logo.imageset/my_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lexonerus/ios-on-practice/e37d09dac8cf947f231c2eefcd0766815e4f075c/patterns-and-architectures/v002-MVP/MVP-v002/Assets.xcassets/my_logo.imageset/my_logo.png -------------------------------------------------------------------------------- /patterns-and-architectures/v002-MVP/MVP-v002/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 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | UISceneConfigurations 28 | 29 | UIWindowSceneSessionRoleApplication 30 | 31 | 32 | UISceneConfigurationName 33 | Default Configuration 34 | UISceneDelegateClassName 35 | $(PRODUCT_MODULE_NAME).SceneDelegate 36 | UISceneStoryboardFile 37 | Main 38 | 39 | 40 | 41 | 42 | UIApplicationSupportsIndirectInputEvents 43 | 44 | UILaunchStoryboardName 45 | LaunchScreen 46 | UIMainStoryboardFile 47 | Main 48 | UIRequiredDeviceCapabilities 49 | 50 | armv7 51 | 52 | UISupportedInterfaceOrientations 53 | 54 | UIInterfaceOrientationPortrait 55 | UIInterfaceOrientationLandscapeLeft 56 | UIInterfaceOrientationLandscapeRight 57 | 58 | UISupportedInterfaceOrientations~ipad 59 | 60 | UIInterfaceOrientationPortrait 61 | UIInterfaceOrientationPortraitUpsideDown 62 | UIInterfaceOrientationLandscapeLeft 63 | UIInterfaceOrientationLandscapeRight 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /patterns-and-architectures/v002-MVP/MVP-v002/Models/Crypto.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Crypto.swift 3 | // MVP-v002 4 | // 5 | // Created by Alex Krzywicki on 09.10.2021. 6 | // 7 | 8 | import Foundation 9 | 10 | struct Crypto { 11 | var name: String 12 | var ticker: String 13 | var value: Int 14 | } 15 | 16 | extension Crypto { 17 | static var testData = [ 18 | Crypto(name: "Bitcion", ticker: "BTC", value: 55000), 19 | Crypto(name: "Etherium", ticker: "ETH", value: 3500), 20 | Crypto(name: "Ripple", ticker: "XRP", value: 589), 21 | Crypto(name: "Stellar", ticker: "XLM", value: 20), 22 | Crypto(name: "Algorand", ticker: "ALGO", value: 3) 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /patterns-and-architectures/v002-MVP/MVP-v002/Presenters/Presenter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Presentor.swift 3 | // MVP-v002 4 | // 5 | // Created by Alex Krzywicki on 09.10.2021. 6 | // 7 | 8 | import Foundation 9 | 10 | class Presenter { 11 | 12 | weak private var viewInputDelegate: ViewInputDelegate? 13 | var testData = Crypto.testData 14 | 15 | func setViewInputDelegate(viewInputDelegate: ViewInputDelegate?) { 16 | self.viewInputDelegate = viewInputDelegate 17 | } 18 | 19 | private func loadTestData() { 20 | self.viewInputDelegate?.setupData(with: self.testData) 21 | } 22 | 23 | private func random() { 24 | let randomCount = Int.random(in: 0 ..< testData.count) 25 | self.viewInputDelegate?.displayData(i: randomCount) 26 | } 27 | 28 | } 29 | 30 | extension Presenter: ViewOutputDelegate { 31 | 32 | func getRandomCount() { 33 | random() 34 | } 35 | 36 | func getData() { 37 | self.loadTestData() 38 | self.viewInputDelegate?.setupInitialState() 39 | } 40 | 41 | func saveData() { 42 | 43 | } 44 | 45 | 46 | } 47 | -------------------------------------------------------------------------------- /patterns-and-architectures/v002-MVP/MVP-v002/Views/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // MVP-v002 4 | // 5 | // Created by Alex Krzywicki on 09.10.2021. 6 | // 7 | 8 | import UIKit 9 | 10 | class ViewController: UIViewController { 11 | 12 | @IBOutlet var nameLabel: UILabel! 13 | @IBOutlet var tickerLabel: UILabel! 14 | @IBOutlet var valueLabel: UILabel! 15 | @IBAction func buttonPressed(_ sender: Any) { 16 | self.viewOutputDelegate?.getRandomCount() 17 | } 18 | 19 | private var count = 0 20 | private var testData: [Crypto] = [] 21 | private let presenter = Presenter() 22 | weak private var viewOutputDelegate: ViewOutputDelegate? 23 | 24 | override func viewDidLoad() { 25 | super.viewDidLoad() 26 | presenter.setViewInputDelegate(viewInputDelegate: self) 27 | self.viewOutputDelegate = presenter 28 | self.viewOutputDelegate?.getData() 29 | 30 | } 31 | 32 | 33 | } 34 | 35 | extension ViewController: ViewInputDelegate { 36 | func setupInitialState() { 37 | displayData(i: count) 38 | } 39 | 40 | func setupData(with testData: ([Crypto])) { 41 | self.testData = testData 42 | } 43 | 44 | func displayData(i: Int) { 45 | if testData.count >= 0 && count <= (testData.count - 1) && count >= 0 { 46 | nameLabel.text = testData[i].name 47 | tickerLabel.text = testData[i].ticker 48 | valueLabel.text = String(testData[i].value) 49 | 50 | } else { 51 | print("Sorry, no data") 52 | } 53 | } 54 | 55 | 56 | } 57 | 58 | -------------------------------------------------------------------------------- /patterns-and-architectures/v002-MVP/MVP-v002/Views/ViewInputDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewInputDelegate.swift 3 | // MVP-v002 4 | // 5 | // Created by Alex Krzywicki on 09.10.2021. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol ViewInputDelegate: AnyObject { 11 | func setupInitialState() 12 | func setupData(with testData: ([Crypto])) 13 | func displayData(i: Int) 14 | } 15 | -------------------------------------------------------------------------------- /patterns-and-architectures/v002-MVP/MVP-v002/Views/ViewOutputDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewOutputDelegate.swift 3 | // MVP-v002 4 | // 5 | // Created by Alex Krzywicki on 09.10.2021. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol ViewOutputDelegate: AnyObject { 11 | func getData() 12 | func saveData() 13 | func getRandomCount() 14 | } 15 | -------------------------------------------------------------------------------- /patterns-and-architectures/v002-MVP/README.md: -------------------------------------------------------------------------------- 1 | # MVP на Swift, iOS разработка, Xcode 2 | 3 | *Данный материал является дополнением к видеоматериалу на [YouTube](https://youtu.be/Qrv94QN_gz4)* 4 | 5 | ## Инструкция по установке 6 | 7 | - Необходимо скачать или клонировать весь проект [ios на практике](https://github.com/lexonerus/ios-on-practice) 8 | - Перейти в каталог /patterns-and-architectures/v002-MVP 9 | - Затем открыть файл MVP-v002.xcodeproj с помощью Xcode 10 | 11 | Подписывайтесь на мой YouTube канал. 12 | -------------------------------------------------------------------------------- /patterns-and-architectures/v003-Coordinator-example/README.md: -------------------------------------------------------------------------------- 1 | # Coordinator на Swift пример паттерна , iOS разработка, Xcode 2 | 3 | *Данный материал является дополнением к видеоматериалу на [YouTube](https://youtu.be/lHk0BfJcN2E)* 4 | 5 | ## Инструкция по установке 6 | 7 | - Необходимо скачать или клонировать весь проект [ios на практике](https://github.com/lexonerus/ios-on-practice) 8 | - Перейти в каталог /patterns-and-architectures/v003-Coordinator-example/ 9 | - Затем открыть файл v003-Coordtinator.xcodeproj с помощью Xcode 10 | 11 | Подписывайтесь на мой YouTube канал. 12 | -------------------------------------------------------------------------------- /patterns-and-architectures/v003-Coordinator-example/v003-Coordtinator.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /patterns-and-architectures/v003-Coordinator-example/v003-Coordtinator.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /patterns-and-architectures/v003-Coordinator-example/v003-Coordtinator.xcodeproj/project.xcworkspace/xcuserdata/lexone01.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lexonerus/ios-on-practice/e37d09dac8cf947f231c2eefcd0766815e4f075c/patterns-and-architectures/v003-Coordinator-example/v003-Coordtinator.xcodeproj/project.xcworkspace/xcuserdata/lexone01.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /patterns-and-architectures/v003-Coordinator-example/v003-Coordtinator.xcodeproj/xcuserdata/lexone01.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | v003-Coordtinator.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /patterns-and-architectures/v003-Coordinator-example/v003-Coordtinator/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // v003-Coordtinator 4 | // 5 | // Created by Alex Krzywicki on 21.10.2021. 6 | // 7 | 8 | import UIKit 9 | 10 | @UIApplicationMain 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | 13 | var window: UIWindow? 14 | var coordinator: AppCoordinator? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 18 | 19 | let navController = UINavigationController() 20 | coordinator = AppCoordinator(navigationController: navController) 21 | coordinator?.start() 22 | 23 | window = UIWindow(frame: UIScreen.main.bounds) 24 | window?.rootViewController = navController 25 | window?.makeKeyAndVisible() 26 | 27 | return true 28 | } 29 | 30 | } 31 | 32 | -------------------------------------------------------------------------------- /patterns-and-architectures/v003-Coordinator-example/v003-Coordtinator/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /patterns-and-architectures/v003-Coordinator-example/v003-Coordtinator/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | } 93 | ], 94 | "info" : { 95 | "author" : "xcode", 96 | "version" : 1 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /patterns-and-architectures/v003-Coordinator-example/v003-Coordtinator/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /patterns-and-architectures/v003-Coordinator-example/v003-Coordtinator/Assets.xcassets/my_logo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "my_logo.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /patterns-and-architectures/v003-Coordinator-example/v003-Coordtinator/Assets.xcassets/my_logo.imageset/my_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lexonerus/ios-on-practice/e37d09dac8cf947f231c2eefcd0766815e4f075c/patterns-and-architectures/v003-Coordinator-example/v003-Coordtinator/Assets.xcassets/my_logo.imageset/my_logo.png -------------------------------------------------------------------------------- /patterns-and-architectures/v003-Coordinator-example/v003-Coordtinator/Coordinators/AppCoordinator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppCoordinator.swift 3 | // v003-Coordtinator 4 | // 5 | // Created by Alex Krzywicki on 21.10.2021. 6 | // 7 | 8 | import UIKit 9 | 10 | class AppCoordinator: Coordinator { 11 | var navigationController: UINavigationController 12 | 13 | init(navigationController: UINavigationController) { 14 | self.navigationController = navigationController 15 | } 16 | 17 | func start() { 18 | let vc = FirstViewController.createObject() 19 | vc.coordinator = self 20 | navigationController.pushViewController(vc, animated: false) 21 | } 22 | 23 | func openFirstVC() { 24 | let vc = FirstViewController.createObject() 25 | vc.coordinator = self 26 | navigationController.pushViewController(vc, animated: true) 27 | } 28 | 29 | func openSecondVC() { 30 | let vc = SecondViewController.createObject() 31 | vc.coordinator = self 32 | navigationController.pushViewController(vc, animated: true) 33 | } 34 | 35 | func openThirdVC() { 36 | let vc = ThirdViewController.createObject() 37 | vc.coordinator = self 38 | navigationController.pushViewController(vc, animated: true) 39 | } 40 | 41 | 42 | } 43 | -------------------------------------------------------------------------------- /patterns-and-architectures/v003-Coordinator-example/v003-Coordtinator/Coordinators/Protocols/Coordinator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Coordinator.swift 3 | // v003-Coordtinator 4 | // 5 | // Created by Alex Krzywicki on 21.10.2021. 6 | // 7 | 8 | import UIKit 9 | 10 | protocol Coordinator { 11 | var navigationController: UINavigationController { get set } 12 | 13 | func start() 14 | } 15 | -------------------------------------------------------------------------------- /patterns-and-architectures/v003-Coordinator-example/v003-Coordtinator/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 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSupportsIndirectInputEvents 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /patterns-and-architectures/v003-Coordinator-example/v003-Coordtinator/Views/FirstViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // v003-Coordtinator 4 | // 5 | // Created by Alex Krzywicki on 21.10.2021. 6 | // 7 | 8 | import UIKit 9 | 10 | class FirstViewController: UIViewController, Storyboardable { 11 | 12 | weak var coordinator: AppCoordinator? 13 | 14 | override func viewDidLoad() { 15 | super.viewDidLoad() 16 | title = "First VC" 17 | } 18 | 19 | @IBAction func openSecondVC(_ sender: Any) { 20 | coordinator?.openSecondVC() 21 | } 22 | 23 | @IBAction func openThirdVC(_ sender: Any) { 24 | coordinator?.openThirdVC() 25 | } 26 | 27 | } 28 | 29 | -------------------------------------------------------------------------------- /patterns-and-architectures/v003-Coordinator-example/v003-Coordtinator/Views/SecondViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SecondViewController.swift 3 | // v003-Coordtinator 4 | // 5 | // Created by Alex Krzywicki on 21.10.2021. 6 | // 7 | 8 | import UIKit 9 | 10 | class SecondViewController: UIViewController, Storyboardable { 11 | 12 | weak var coordinator: AppCoordinator? 13 | 14 | override func viewDidLoad() { 15 | super.viewDidLoad() 16 | title = "Second VC" 17 | } 18 | 19 | @IBAction func openFirstVC(_ sender: Any) { 20 | coordinator?.openFirstVC() 21 | } 22 | @IBAction func openThirdVC(_ sender: Any) { 23 | coordinator?.openThirdVC() 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /patterns-and-architectures/v003-Coordinator-example/v003-Coordtinator/Views/Storyboardable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Storyboardable.swift 3 | // v003-Coordtinator 4 | // 5 | // Created by Alex Krzywicki on 21.10.2021. 6 | // 7 | 8 | import UIKit 9 | 10 | protocol Storyboardable { 11 | static func createObject() -> Self 12 | } 13 | 14 | extension Storyboardable where Self: UIViewController { 15 | static func createObject() -> Self { 16 | let id = String(describing: self) 17 | let storyboard = UIStoryboard(name: "Main", bundle: nil) 18 | return storyboard.instantiateViewController(identifier: id) as! Self 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /patterns-and-architectures/v003-Coordinator-example/v003-Coordtinator/Views/ThirdViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ThirdViewController.swift 3 | // v003-Coordtinator 4 | // 5 | // Created by Alex Krzywicki on 21.10.2021. 6 | // 7 | 8 | import UIKit 9 | 10 | class ThirdViewController: UIViewController, Storyboardable { 11 | 12 | weak var coordinator: AppCoordinator? 13 | 14 | override func viewDidLoad() { 15 | super.viewDidLoad() 16 | title = "Third VC" 17 | 18 | } 19 | @IBAction func openFirstVC(_ sender: Any) { 20 | coordinator?.openFirstVC() 21 | } 22 | @IBAction func openSecondVC(_ sender: Any) { 23 | coordinator?.openSecondVC() 24 | 25 | } 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /patterns-and-architectures/v005-MVC/Readme.md: -------------------------------------------------------------------------------- 1 | # MVC простая реализация паттерна для iOS 2 | 3 | *Данный материал является дополнением к видеоматериалу на [YouTube](https://youtu.be/2L7KGGoD7ZE)* 4 | 5 | ## Инструкция по установке 6 | 7 | - Необходимо скачать или клонировать весь проект [ios на практике](https://github.com/lexonerus/ios-on-practice) 8 | - Перейти в каталог /patterns-and-architectures/v005-MVC 9 | - Затем открыть файл v005-MVC.xcodeproj с помощью Xcode 10 | 11 | Подписывайтесь на мой YouTube канал. 12 | -------------------------------------------------------------------------------- /patterns-and-architectures/v005-MVC/v005-MVC.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /patterns-and-architectures/v005-MVC/v005-MVC.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /patterns-and-architectures/v005-MVC/v005-MVC.xcodeproj/project.xcworkspace/xcuserdata/lexone01.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lexonerus/ios-on-practice/e37d09dac8cf947f231c2eefcd0766815e4f075c/patterns-and-architectures/v005-MVC/v005-MVC.xcodeproj/project.xcworkspace/xcuserdata/lexone01.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /patterns-and-architectures/v005-MVC/v005-MVC.xcodeproj/xcuserdata/lexone01.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | v005-MVC.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /patterns-and-architectures/v005-MVC/v005-MVC/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // v005-MVC 4 | // 5 | // Created by Alex Krzywicki on 05.11.2021. 6 | // 7 | 8 | import UIKit 9 | 10 | @main 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | 13 | 14 | 15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 16 | // Override point for customization after application launch. 17 | return true 18 | } 19 | 20 | // MARK: UISceneSession Lifecycle 21 | 22 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 23 | // Called when a new scene session is being created. 24 | // Use this method to select a configuration to create the new scene with. 25 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 26 | } 27 | 28 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 29 | // Called when the user discards a scene session. 30 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 31 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 32 | } 33 | 34 | 35 | } 36 | 37 | -------------------------------------------------------------------------------- /patterns-and-architectures/v005-MVC/v005-MVC/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /patterns-and-architectures/v005-MVC/v005-MVC/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | } 93 | ], 94 | "info" : { 95 | "author" : "xcode", 96 | "version" : 1 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /patterns-and-architectures/v005-MVC/v005-MVC/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /patterns-and-architectures/v005-MVC/v005-MVC/Assets.xcassets/my_logo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "my_logo.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /patterns-and-architectures/v005-MVC/v005-MVC/Assets.xcassets/my_logo.imageset/my_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lexonerus/ios-on-practice/e37d09dac8cf947f231c2eefcd0766815e4f075c/patterns-and-architectures/v005-MVC/v005-MVC/Assets.xcassets/my_logo.imageset/my_logo.png -------------------------------------------------------------------------------- /patterns-and-architectures/v005-MVC/v005-MVC/Controllers/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // v005-MVC 4 | // 5 | // Created by Alex Krzywicki on 05.11.2021. 6 | // 7 | 8 | import UIKit 9 | 10 | class ViewController: UIViewController { 11 | @IBOutlet var nameLabel: UILabel! 12 | @IBOutlet var tickerLabel: UILabel! 13 | @IBOutlet var valueLabel: UILabel! 14 | @IBAction func buttonPressed(_ sender: Any) { 15 | displayData(i: randomCount.getRandomCount(data: testData)) 16 | } 17 | 18 | private var count = 0 19 | private var testData: [Crypto] = [] 20 | private let randomCount = RandomCount() 21 | 22 | override func viewDidLoad() { 23 | super.viewDidLoad() 24 | let model = Crypto.testData 25 | setupData(with: model) 26 | setupInitialState() 27 | } 28 | 29 | func setupInitialState() { 30 | displayData(i: count) 31 | } 32 | 33 | func setupData(with testData: ([Crypto])) { 34 | self.testData = testData 35 | } 36 | 37 | func displayData(i: Int) { 38 | if testData.count >= 0 && count <= (testData.count - 1) && count >= 0 { 39 | nameLabel.text = testData[i].name 40 | tickerLabel.text = testData[i].ticker 41 | valueLabel.text = String(testData[i].value) 42 | } else { 43 | print("Sorry, no data") 44 | } 45 | } 46 | 47 | 48 | } 49 | 50 | -------------------------------------------------------------------------------- /patterns-and-architectures/v005-MVC/v005-MVC/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 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | UISceneConfigurations 28 | 29 | UIWindowSceneSessionRoleApplication 30 | 31 | 32 | UISceneConfigurationName 33 | Default Configuration 34 | UISceneDelegateClassName 35 | $(PRODUCT_MODULE_NAME).SceneDelegate 36 | UISceneStoryboardFile 37 | Main 38 | 39 | 40 | 41 | 42 | UIApplicationSupportsIndirectInputEvents 43 | 44 | UILaunchStoryboardName 45 | LaunchScreen 46 | UIMainStoryboardFile 47 | Main 48 | UIRequiredDeviceCapabilities 49 | 50 | armv7 51 | 52 | UISupportedInterfaceOrientations 53 | 54 | UIInterfaceOrientationPortrait 55 | UIInterfaceOrientationLandscapeLeft 56 | UIInterfaceOrientationLandscapeRight 57 | 58 | UISupportedInterfaceOrientations~ipad 59 | 60 | UIInterfaceOrientationPortrait 61 | UIInterfaceOrientationPortraitUpsideDown 62 | UIInterfaceOrientationLandscapeLeft 63 | UIInterfaceOrientationLandscapeRight 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /patterns-and-architectures/v005-MVC/v005-MVC/Models/Crypto.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Crypto.swift 3 | // v005-MVC 4 | // 5 | // Created by Alex Krzywicki on 05.11.2021. 6 | // 7 | 8 | // Model 9 | 10 | import Foundation 11 | 12 | struct Crypto { 13 | var name: String 14 | var ticker: String 15 | var value: Int 16 | } 17 | 18 | extension Crypto { 19 | static var testData = [ 20 | Crypto(name: "Bitcion", ticker: "BTC", value: 55000), 21 | Crypto(name: "Etherium", ticker: "ETH", value: 3500), 22 | Crypto(name: "Ripple", ticker: "XRP", value: 589), 23 | Crypto(name: "Stellar", ticker: "XLM", value: 20), 24 | Crypto(name: "Algorand", ticker: "ALGO", value: 3) 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /patterns-and-architectures/v005-MVC/v005-MVC/Models/Hellpers/RandomCount.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RandomCount.swift 3 | // v005-MVC 4 | // 5 | // Created by Alex Krzywicki on 05.11.2021. 6 | // 7 | 8 | import Foundation 9 | 10 | class RandomCount { 11 | func getRandomCount(data: [Crypto]) -> Int { 12 | let randomCount = Int.random(in: 0 ..< data.count) 13 | return randomCount 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /patterns-and-architectures/v005-MVC/v005-MVC/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.swift 3 | // v005-MVC 4 | // 5 | // Created by Alex Krzywicki on 05.11.2021. 6 | // 7 | 8 | import UIKit 9 | 10 | class SceneDelegate: UIResponder, UIWindowSceneDelegate { 11 | 12 | var window: UIWindow? 13 | 14 | 15 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 16 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. 17 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. 18 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). 19 | guard let _ = (scene as? UIWindowScene) else { return } 20 | } 21 | 22 | func sceneDidDisconnect(_ scene: UIScene) { 23 | // Called as the scene is being released by the system. 24 | // This occurs shortly after the scene enters the background, or when its session is discarded. 25 | // Release any resources associated with this scene that can be re-created the next time the scene connects. 26 | // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). 27 | } 28 | 29 | func sceneDidBecomeActive(_ scene: UIScene) { 30 | // Called when the scene has moved from an inactive state to an active state. 31 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 32 | } 33 | 34 | func sceneWillResignActive(_ scene: UIScene) { 35 | // Called when the scene will move from an active state to an inactive state. 36 | // This may occur due to temporary interruptions (ex. an incoming phone call). 37 | } 38 | 39 | func sceneWillEnterForeground(_ scene: UIScene) { 40 | // Called as the scene transitions from the background to the foreground. 41 | // Use this method to undo the changes made on entering the background. 42 | } 43 | 44 | func sceneDidEnterBackground(_ scene: UIScene) { 45 | // Called as the scene transitions from the foreground to the background. 46 | // Use this method to save data, release shared resources, and store enough scene-specific state information 47 | // to restore the scene back to its current state. 48 | } 49 | 50 | 51 | } 52 | 53 | -------------------------------------------------------------------------------- /patterns-and-architectures/v028-CompletionHandlers/CompletionHandlers.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | var greeting = "Hello, playground" 4 | 5 | let myCompletionHandler: (Bool) -> Void = { doneWotking in 6 | if doneWotking { 7 | print("Work is done.") 8 | } 9 | } 10 | 11 | func myFunc(using completionHandler: (Bool) -> Void ) { 12 | sleep(2) 13 | print("Stage 1 passed...") 14 | sleep(2) 15 | print("Stage 2 passed...") 16 | sleep(2) 17 | print("Stage 3 passed...") 18 | sleep(1) 19 | completionHandler(true) 20 | } 21 | 22 | myFunc(using: myCompletionHandler) 23 | -------------------------------------------------------------------------------- /patterns-and-architectures/v028-CompletionHandlers/CompletionHandlers.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /patterns-and-architectures/v028-CompletionHandlers/CompletionHandlers.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /patterns-and-architectures/v028-CompletionHandlers/CompletionHandlers.playground/playground.xcworkspace/xcuserdata/lexone01.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lexonerus/ios-on-practice/e37d09dac8cf947f231c2eefcd0766815e4f075c/patterns-and-architectures/v028-CompletionHandlers/CompletionHandlers.playground/playground.xcworkspace/xcuserdata/lexone01.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /patterns-and-architectures/v028-CompletionHandlers/Readme.md: -------------------------------------------------------------------------------- 1 | # Completion Handler простая реализация паттерна для iOS 2 | 3 | *Данный материал является дополнением к видеоматериалу на YouTube* 4 | 5 | ## Инструкция по установке 6 | 7 | - Необходимо скачать или клонировать весь проект [ios на практике](https://github.com/lexonerus/ios-on-practice) 8 | - Перейти в каталог /patterns-and-architectures/v028-CompletionHandlers 9 | - Затем открыть файл CompletionHandlers.playground с помощью Xcode 10 | 11 | Подписывайтесь на мой YouTube канал. 12 | -------------------------------------------------------------------------------- /patterns-and-architectures/v029-MVVM_simple/MVVM_simple.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /patterns-and-architectures/v029-MVVM_simple/MVVM_simple.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /patterns-and-architectures/v029-MVVM_simple/MVVM_simple.xcodeproj/project.xcworkspace/xcuserdata/lexone01.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lexonerus/ios-on-practice/e37d09dac8cf947f231c2eefcd0766815e4f075c/patterns-and-architectures/v029-MVVM_simple/MVVM_simple.xcodeproj/project.xcworkspace/xcuserdata/lexone01.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /patterns-and-architectures/v029-MVVM_simple/MVVM_simple.xcodeproj/xcuserdata/lexone01.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | MVVM_simple.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /patterns-and-architectures/v029-MVVM_simple/MVVM_simple/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // MVVM_simple 4 | // 5 | // Created by Alex Krzywicki on 23.12.2021. 6 | // 7 | 8 | import UIKit 9 | 10 | @main 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | 13 | 14 | 15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 16 | // Override point for customization after application launch. 17 | return true 18 | } 19 | 20 | // MARK: UISceneSession Lifecycle 21 | 22 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 23 | // Called when a new scene session is being created. 24 | // Use this method to select a configuration to create the new scene with. 25 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 26 | } 27 | 28 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 29 | // Called when the user discards a scene session. 30 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 31 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 32 | } 33 | 34 | 35 | } 36 | 37 | -------------------------------------------------------------------------------- /patterns-and-architectures/v029-MVVM_simple/MVVM_simple/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /patterns-and-architectures/v029-MVVM_simple/MVVM_simple/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | } 93 | ], 94 | "info" : { 95 | "author" : "xcode", 96 | "version" : 1 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /patterns-and-architectures/v029-MVVM_simple/MVVM_simple/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /patterns-and-architectures/v029-MVVM_simple/MVVM_simple/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIApplicationSceneManifest 6 | 7 | UIApplicationSupportsMultipleScenes 8 | 9 | UISceneConfigurations 10 | 11 | UIWindowSceneSessionRoleApplication 12 | 13 | 14 | UISceneConfigurationName 15 | Default Configuration 16 | UISceneDelegateClassName 17 | $(PRODUCT_MODULE_NAME).SceneDelegate 18 | UISceneStoryboardFile 19 | Main 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /patterns-and-architectures/v029-MVVM_simple/MVVM_simple/Models/User.swift: -------------------------------------------------------------------------------- 1 | // 2 | // User.swift 3 | // MVVM_simple 4 | // 5 | // Created by Alex Krzywicki on 23.12.2021. 6 | // 7 | 8 | import Foundation 9 | 10 | struct User { 11 | let login: String? 12 | let passwords: String? 13 | } 14 | 15 | extension User { 16 | static var logins = [ 17 | User(login: "lexone", passwords: "12345") 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /patterns-and-architectures/v029-MVVM_simple/MVVM_simple/ViewModels/Bindings/Dynamic.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Dynamic.swift 3 | // MVVM_simple 4 | // 5 | // Created by Alex Krzywicki on 23.12.2021. 6 | // 7 | 8 | import Foundation 9 | 10 | class Dynamic { 11 | typealias Listener = (T) -> Void 12 | private var listener: Listener? 13 | 14 | func bind(_ listener: Listener?) { 15 | self.listener = listener 16 | } 17 | 18 | var value: T { 19 | didSet { 20 | listener?(value) 21 | } 22 | } 23 | 24 | init(_ v: T) { 25 | value = v 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /patterns-and-architectures/v029-MVVM_simple/MVVM_simple/ViewModels/ViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewModel.swift 3 | // MVVM_simple 4 | // 5 | // Created by Alex Krzywicki on 23.12.2021. 6 | // 7 | 8 | import Foundation 9 | import UIKit.UIColor 10 | 11 | class ViewModel { 12 | var statusText = Dynamic("") 13 | var statusColor = Dynamic(#colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)) 14 | 15 | func userButtonPressed(login: String, password: String) { 16 | if login != User.logins[0].login || password != User.logins[0].passwords { 17 | statusText.value = "Log in failed." 18 | statusColor.value = #colorLiteral(red: 0.5725490451, green: 0, blue: 0.2313725501, alpha: 1) 19 | } else { 20 | statusText.value = "You successfully logged in." 21 | statusColor.value = #colorLiteral(red: 0.3411764801, green: 0.6235294342, blue: 0.1686274558, alpha: 1) 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /patterns-and-architectures/v029-MVVM_simple/MVVM_simple/Views/Stryboards/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /patterns-and-architectures/v029-MVVM_simple/MVVM_simple/Views/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // MVVM_simple 4 | // 5 | // Created by Alex Krzywicki on 23.12.2021. 6 | // 7 | 8 | import UIKit 9 | 10 | class ViewController: UIViewController { 11 | @IBOutlet var loginField: UITextField! 12 | @IBOutlet var passField: UITextField! 13 | @IBAction func loginButtonPressed(_ sender: Any) { 14 | viewModel.userButtonPressed(login: (loginField.text ?? ""), password: passField.text ?? "") 15 | } 16 | @IBOutlet var label: UILabel! 17 | 18 | var viewModel = ViewModel() 19 | 20 | func initialState() { 21 | label.textColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1) 22 | label.text = "" 23 | } 24 | 25 | override func viewDidLoad() { 26 | super.viewDidLoad() 27 | bindViewModel() 28 | initialState() 29 | } 30 | 31 | 32 | func bindViewModel() { 33 | viewModel.statusText.bind({ (statusText) in 34 | DispatchQueue.main.async { 35 | self.label.text = statusText 36 | } 37 | }) 38 | viewModel.statusColor.bind({(statusColor) in 39 | DispatchQueue.main.async { 40 | self.label.textColor = statusColor 41 | } 42 | }) 43 | } 44 | } 45 | 46 | -------------------------------------------------------------------------------- /patterns-and-architectures/v029-MVVM_simple/Readme.md: -------------------------------------------------------------------------------- 1 | # MVVM простая реализация паттерна для iOS 2 | 3 | *Данный материал является дополнением к видеоматериалу на YouTube* 4 | 5 | ## Инструкция по установке 6 | 7 | - Необходимо скачать или клонировать весь проект [ios на практике](https://github.com/lexonerus/ios-on-practice) 8 | - Перейти в каталог /patterns-and-architectures/м029-MVVM_simple 9 | - Затем открыть файл м029-MVVM_simple.xcodeproj с помощью Xcode 10 | 11 | Подписывайтесь на мой YouTube канал. 12 | -------------------------------------------------------------------------------- /patterns-and-architectures/v030-MVVMC_simple/MVVM_simple.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /patterns-and-architectures/v030-MVVMC_simple/MVVM_simple.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /patterns-and-architectures/v030-MVVMC_simple/MVVM_simple.xcodeproj/project.xcworkspace/xcuserdata/lexone01.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lexonerus/ios-on-practice/e37d09dac8cf947f231c2eefcd0766815e4f075c/patterns-and-architectures/v030-MVVMC_simple/MVVM_simple.xcodeproj/project.xcworkspace/xcuserdata/lexone01.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /patterns-and-architectures/v030-MVVMC_simple/MVVM_simple.xcodeproj/xcuserdata/lexone01.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | MVVM_simple.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /patterns-and-architectures/v030-MVVMC_simple/MVVM_simple/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // MVVM_simple 4 | // 5 | // Created by Alex Krzywicki on 23.12.2021. 6 | // 7 | 8 | import UIKit 9 | 10 | @UIApplicationMain 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | 13 | var window: UIWindow? 14 | var coordinator: AppCoordinator? 15 | 16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 17 | // Override point for customization after application launch. 18 | let navController = UINavigationController() 19 | coordinator = AppCoordinator(navigationController: navController) 20 | coordinator?.start() 21 | window = UIWindow(frame: UIScreen.main.bounds) 22 | window?.rootViewController = navController 23 | window?.makeKeyAndVisible() 24 | return true 25 | } 26 | 27 | 28 | 29 | } 30 | 31 | -------------------------------------------------------------------------------- /patterns-and-architectures/v030-MVVMC_simple/MVVM_simple/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /patterns-and-architectures/v030-MVVMC_simple/MVVM_simple/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | } 93 | ], 94 | "info" : { 95 | "author" : "xcode", 96 | "version" : 1 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /patterns-and-architectures/v030-MVVMC_simple/MVVM_simple/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /patterns-and-architectures/v030-MVVMC_simple/MVVM_simple/Coordinators/AppCoordinator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppCoordinator.swift 3 | // MVVM_simple 4 | // 5 | // Created by Alex Krzywicki on 13.01.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | class AppCoordinator: Coordinator { 11 | var navigationController: UINavigationController 12 | var isLoggedIn: Bool = false 13 | 14 | init(navigationController: UINavigationController) { 15 | self.navigationController = navigationController 16 | } 17 | 18 | func start() { 19 | if isLoggedIn { 20 | showMain(login: User.logins[0].login!) 21 | } else { 22 | showLogin() 23 | } 24 | } 25 | 26 | func showLogin() { 27 | let vc = LoginViewController.createObject() 28 | vc.coordinator = self 29 | vc.viewModel = LoginViewModel() 30 | vc.viewModel?.isLoggedIn = isLoggedIn 31 | navigationController.pushViewController(vc, animated: true) 32 | } 33 | 34 | func showMain(login: String) { 35 | let vc = MainViewController.createObject() 36 | let viewModel = MainViewModel() 37 | viewModel.login = login 38 | vc.coordinator = self 39 | vc.viewModel = viewModel 40 | navigationController.viewControllers.removeAll() 41 | navigationController.pushViewController(vc, animated: true) 42 | 43 | } 44 | 45 | func showDetail() { 46 | let vc = DetailViewController.createObject() 47 | let viewModel = DetailViewModel() 48 | viewModel.model = UserData.userData 49 | vc.coordinator = self 50 | vc.viewModel = viewModel 51 | navigationController.pushViewController(vc, animated: true) 52 | 53 | } 54 | 55 | 56 | } 57 | 58 | -------------------------------------------------------------------------------- /patterns-and-architectures/v030-MVVMC_simple/MVVM_simple/Coordinators/Protocols/Coordinator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Coordinator.swift 3 | // MVVM_simple 4 | // 5 | // Created by Alex Krzywicki on 13.01.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | protocol Coordinator { 11 | var navigationController: UINavigationController { get set } 12 | func start() 13 | } 14 | 15 | -------------------------------------------------------------------------------- /patterns-and-architectures/v030-MVVMC_simple/MVVM_simple/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /patterns-and-architectures/v030-MVVMC_simple/MVVM_simple/Models/User.swift: -------------------------------------------------------------------------------- 1 | // 2 | // User.swift 3 | // MVVM_simple 4 | // 5 | // Created by Alex Krzywicki on 23.12.2021. 6 | // 7 | 8 | import Foundation 9 | 10 | struct User { 11 | let login: String? 12 | let passwords: String? 13 | } 14 | 15 | extension User { 16 | static var logins = [ 17 | User(login: "lexone", passwords: "12345") 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /patterns-and-architectures/v030-MVVMC_simple/MVVM_simple/Models/UserData.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UserData.swift 3 | // MVVM_simple 4 | // 5 | // Created by Alex Krzywicki on 13.01.2022. 6 | // 7 | 8 | import Foundation 9 | 10 | 11 | struct UserData { 12 | var name: String? 13 | var city: String? 14 | var email: String? 15 | var phone: String? 16 | } 17 | 18 | extension UserData { 19 | static var userData = UserData(name: "Alexey", city: "Moscow", email: "test@mail.com", phone: "+7(999)432-33-42") 20 | } 21 | -------------------------------------------------------------------------------- /patterns-and-architectures/v030-MVVMC_simple/MVVM_simple/ViewModels/Bindings/Dynamic.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Dynamic.swift 3 | // MVVM_simple 4 | // 5 | // Created by Alex Krzywicki on 23.12.2021. 6 | // 7 | 8 | import Foundation 9 | 10 | class Dynamic { 11 | typealias Listener = (T) -> Void 12 | private var listener: Listener? 13 | 14 | func bind(_ listener: Listener?) { 15 | self.listener = listener 16 | } 17 | 18 | var value: T { 19 | didSet { 20 | listener?(value) 21 | } 22 | } 23 | 24 | init(_ v: T) { 25 | value = v 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /patterns-and-architectures/v030-MVVMC_simple/MVVM_simple/ViewModels/DetailViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DetailViewModel.swift 3 | // MVVM_simple 4 | // 5 | // Created by Alex Krzywicki on 13.01.2022. 6 | // 7 | 8 | import Foundation 9 | 10 | class DetailViewModel { 11 | var model: UserData? 12 | } 13 | -------------------------------------------------------------------------------- /patterns-and-architectures/v030-MVVMC_simple/MVVM_simple/ViewModels/LoginViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewModel.swift 3 | // MVVM_simple 4 | // 5 | // Created by Alex Krzywicki on 23.12.2021. 6 | // 7 | 8 | import Foundation 9 | import UIKit.UIColor 10 | 11 | class LoginViewModel { 12 | var statusText = Dynamic("") 13 | var statusColor = Dynamic(#colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)) 14 | var isLoggedIn = false 15 | 16 | func userButtonPressed(login: String, password: String) { 17 | if login != User.logins[0].login || password != User.logins[0].passwords { 18 | statusText.value = "Log in failed." 19 | statusColor.value = #colorLiteral(red: 0.5725490451, green: 0, blue: 0.2313725501, alpha: 1) 20 | isLoggedIn = false 21 | } else { 22 | statusText.value = "You successfully logged in." 23 | statusColor.value = #colorLiteral(red: 0.3411764801, green: 0.6235294342, blue: 0.1686274558, alpha: 1) 24 | isLoggedIn = true 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /patterns-and-architectures/v030-MVVMC_simple/MVVM_simple/ViewModels/MainViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MainViewModel.swift 3 | // MVVM_simple 4 | // 5 | // Created by Alex Krzywicki on 13.01.2022. 6 | // 7 | 8 | import Foundation 9 | 10 | class MainViewModel { 11 | var login = "" 12 | } 13 | -------------------------------------------------------------------------------- /patterns-and-architectures/v030-MVVMC_simple/MVVM_simple/Views/DetailViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DetailViewController.swift 3 | // MVVM_simple 4 | // 5 | // Created by Alex Krzywicki on 13.01.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | class DetailViewController: UIViewController, Storyboardable { 11 | 12 | @IBOutlet var nameLabel: UILabel! 13 | @IBOutlet var cityLabel: UILabel! 14 | @IBOutlet var emailLabel: UILabel! 15 | @IBOutlet var phoneLabel: UILabel! 16 | 17 | weak var coordinator: AppCoordinator? 18 | var viewModel: DetailViewModel? 19 | 20 | override func viewDidLoad() { 21 | super.viewDidLoad() 22 | print("Detail view loaded") 23 | updateUI() 24 | } 25 | 26 | func updateUI() { 27 | nameLabel.text = viewModel?.model?.name 28 | cityLabel.text = viewModel?.model?.city 29 | emailLabel.text = viewModel?.model?.email 30 | phoneLabel.text = viewModel?.model?.phone 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /patterns-and-architectures/v030-MVVMC_simple/MVVM_simple/Views/LoginViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // MVVM_simple 4 | // 5 | // Created by Alex Krzywicki on 23.12.2021. 6 | // 7 | 8 | import UIKit 9 | 10 | class LoginViewController: UIViewController, Storyboardable { 11 | @IBOutlet var loginField: UITextField! 12 | @IBOutlet var passField: UITextField! 13 | @IBAction func loginButtonPressed(_ sender: Any) { 14 | viewModel!.userButtonPressed(login: (loginField.text ?? ""), password: passField.text ?? "") 15 | if viewModel!.isLoggedIn { 16 | coordinator?.isLoggedIn = viewModel!.isLoggedIn 17 | coordinator?.showMain(login: loginField.text ?? "") 18 | } 19 | } 20 | @IBOutlet var label: UILabel! 21 | 22 | var viewModel: LoginViewModel? 23 | var coordinator: AppCoordinator? 24 | 25 | func initialState() { 26 | label.textColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1) 27 | label.text = "" 28 | } 29 | 30 | override func viewDidLoad() { 31 | super.viewDidLoad() 32 | bindViewModel() 33 | initialState() 34 | } 35 | 36 | 37 | func bindViewModel() { 38 | viewModel!.statusText.bind({ (statusText) in 39 | DispatchQueue.main.async { 40 | self.label.text = statusText 41 | } 42 | }) 43 | viewModel!.statusColor.bind({(statusColor) in 44 | DispatchQueue.main.async { 45 | self.label.textColor = statusColor 46 | } 47 | }) 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /patterns-and-architectures/v030-MVVMC_simple/MVVM_simple/Views/MainViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MainViewController.swift 3 | // MVVM_simple 4 | // 5 | // Created by Alex Krzywicki on 13.01.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | class MainViewController: UIViewController, Storyboardable { 11 | 12 | @IBOutlet var mainLabel: UILabel! 13 | @IBAction func aboutButtonPressed(_ sender: Any) { 14 | coordinator?.showDetail() 15 | } 16 | 17 | weak var coordinator: AppCoordinator? 18 | var viewModel: MainViewModel? 19 | 20 | override func viewDidLoad() { 21 | super.viewDidLoad() 22 | print("Main screen loaded") 23 | mainLabel.text = "Hello \(viewModel?.login ?? "Default")" 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /patterns-and-architectures/v030-MVVMC_simple/MVVM_simple/Views/Protocols/Stoeyboardable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Stoeyboardable.swift 3 | // MVVM_simple 4 | // 5 | // Created by Alex Krzywicki on 13.01.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | protocol Storyboardable { 11 | static func createObject() -> Self 12 | } 13 | 14 | extension Storyboardable where Self: UIViewController { 15 | static func createObject() -> Self { 16 | let id = String(describing: self) 17 | let storyboard = UIStoryboard(name: "Main", bundle: nil) 18 | return storyboard.instantiateViewController(identifier: id) as! Self 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /patterns-and-architectures/v030-MVVMC_simple/MVVM_simple/Views/Stryboards/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /patterns-and-architectures/v030-MVVMC_simple/Readme.md: -------------------------------------------------------------------------------- 1 | # MVVMC простая реализация паттерна для iOS 2 | 3 | *Данный материал является дополнением к видеоматериалу на YouTube* 4 | 5 | ## Инструкция по установке 6 | 7 | - Необходимо скачать или клонировать весь проект [ios на практике](https://github.com/lexonerus/ios-on-practice) 8 | - Перейти в каталог /patterns-and-architectures/v030-MVVMC_simple 9 | - Затем открыть файл MVVM_simple.xcodeproj с помощью Xcode 10 | 11 | Подписывайтесь на мой YouTube канал. 12 | -------------------------------------------------------------------------------- /patterns-and-architectures/v039-URLSessionExample/Readme.md: -------------------------------------------------------------------------------- 1 | # Swift URLSession получаем данные от сервера за 5 шагов (iOS, Xcode, API) 2 | 3 | *Данный материал является дополнением к видеоматериалу на YouTube* 4 | 5 | ## Инструкция по установке 6 | 7 | - Необходимо скачать или клонировать весь проект [ios на практике](https://github.com/lexonerus/ios-on-practice) 8 | - Перейти в каталог /patterns-and-architectures/v039-URLSessionExample 9 | - Затем открыть файл URLSessionExample.xcodeproj с помощью Xcode 10 | 11 | Подписывайтесь на мой [YouTube канал](https://www.youtube.com/channel/UCNp8ItQbZqAz97ACiVEe62g). 12 | -------------------------------------------------------------------------------- /patterns-and-architectures/v039-URLSessionExample/URLSessionExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /patterns-and-architectures/v039-URLSessionExample/URLSessionExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /patterns-and-architectures/v039-URLSessionExample/URLSessionExample.xcodeproj/project.xcworkspace/xcuserdata/lexone01.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lexonerus/ios-on-practice/e37d09dac8cf947f231c2eefcd0766815e4f075c/patterns-and-architectures/v039-URLSessionExample/URLSessionExample.xcodeproj/project.xcworkspace/xcuserdata/lexone01.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /patterns-and-architectures/v039-URLSessionExample/URLSessionExample.xcodeproj/xcuserdata/lexone01.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | URLSessionExample.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /patterns-and-architectures/v039-URLSessionExample/URLSessionExample/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // URLSessionExample 4 | // 5 | // Created by Alex Krzywicki on 04.02.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | @main 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | 13 | 14 | 15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 16 | // Override point for customization after application launch. 17 | return true 18 | } 19 | 20 | // MARK: UISceneSession Lifecycle 21 | 22 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 23 | // Called when a new scene session is being created. 24 | // Use this method to select a configuration to create the new scene with. 25 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 26 | } 27 | 28 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 29 | // Called when the user discards a scene session. 30 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 31 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 32 | } 33 | 34 | 35 | } 36 | 37 | -------------------------------------------------------------------------------- /patterns-and-architectures/v039-URLSessionExample/URLSessionExample/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /patterns-and-architectures/v039-URLSessionExample/URLSessionExample/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | } 93 | ], 94 | "info" : { 95 | "author" : "xcode", 96 | "version" : 1 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /patterns-and-architectures/v039-URLSessionExample/URLSessionExample/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /patterns-and-architectures/v039-URLSessionExample/URLSessionExample/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /patterns-and-architectures/v039-URLSessionExample/URLSessionExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIApplicationSceneManifest 6 | 7 | UIApplicationSupportsMultipleScenes 8 | 9 | UISceneConfigurations 10 | 11 | UIWindowSceneSessionRoleApplication 12 | 13 | 14 | UISceneConfigurationName 15 | Default Configuration 16 | UISceneDelegateClassName 17 | $(PRODUCT_MODULE_NAME).SceneDelegate 18 | UISceneStoryboardFile 19 | Main 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /patterns-and-architectures/v039-URLSessionExample/URLSessionExample/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // URLSessionExample 4 | // 5 | // Created by Alex Krzywicki on 04.02.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | class ViewController: UIViewController { 11 | 12 | var imageWidth = "" 13 | var imageHeight = "" 14 | 15 | @IBOutlet var imageView: UIImageView! 16 | @IBAction func getImageButtonPressed(_ sender: Any) { 17 | // 1) Получаем API 18 | let API = "https://picsum.photos/" + imageWidth + "/" + imageHeight 19 | // 2) Создаение URL 20 | guard let apiURL = URL(string: API) else { 21 | fatalError("some Error") 22 | } 23 | // 3) Инициализировать сессию 24 | let session = URLSession(configuration: .default) 25 | // 4) Создать запрос dataTask 26 | let task = session.dataTask(with: apiURL) { (data, response, error) in 27 | // 5) Обработать полученные данные 28 | guard let data = data, error == nil else { return } 29 | DispatchQueue.main.async { 30 | // data = .jpeg 31 | self.imageView.image = UIImage(data: data) 32 | } 33 | } 34 | // Запустить запрос 35 | task.resume() 36 | 37 | 38 | } 39 | 40 | override func viewDidLoad() { 41 | super.viewDidLoad() 42 | // Do any additional setup after loading the view. 43 | let height = imageView.bounds.height 44 | self.imageHeight = String(format: "%.0f", Double(height)) 45 | let width = imageView.bounds.width 46 | self.imageWidth = String(format: "%.0f", Double(width)) 47 | } 48 | 49 | 50 | } 51 | 52 | -------------------------------------------------------------------------------- /patterns-and-architectures/v052-UnwrappingOptionals/UnwrapOptional.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | var text: String? = "some text" 2 | //var text: String? = nil 3 | 4 | // 1. Пинудительно (forced) - не безопасно 5 | //var unwrapped1: String = text! 6 | 7 | // 2. Неявно (implicitly) - не безопасно 8 | var unwrapped2: String! = text 9 | 10 | // 3. Опциональное привязывание (binding) - безопасно 11 | if let unwrapped3 = text { 12 | print("optional was successfully unwrapped and its value = \(unwrapped3)") 13 | } else { 14 | print("found nil in optional value") 15 | } 16 | 17 | // 4. Опциональная цепочка (chaining) - безопасно 18 | let unwrapped4 = text?.uppercased() 19 | print(unwrapped4 as Any) 20 | 21 | // 5. Значение по умолчанию - безопасно 22 | let unwrapped5 = text ?? "default value" 23 | print(unwrapped5 as Any) 24 | 25 | // 6. С помощью Guard - безопасно 26 | func guardTest() { 27 | guard let unwrapped6 = text else { 28 | return 29 | } 30 | print(unwrapped6 as Any) 31 | } 32 | guardTest() 33 | 34 | // 7. Optional паттерн - безопасно 35 | if case let unwrapped7? = text { 36 | print(unwrapped7) 37 | } 38 | -------------------------------------------------------------------------------- /patterns-and-architectures/v052-UnwrappingOptionals/UnwrapOptional.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /patterns-and-architectures/v052-UnwrappingOptionals/UnwrapOptional.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /patterns-and-architectures/v052-UnwrappingOptionals/UnwrapOptional.playground/playground.xcworkspace/xcuserdata/lexone01.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lexonerus/ios-on-practice/e37d09dac8cf947f231c2eefcd0766815e4f075c/patterns-and-architectures/v052-UnwrappingOptionals/UnwrapOptional.playground/playground.xcworkspace/xcuserdata/lexone01.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /patterns-and-architectures/v052-UnwrappingOptionals/UnwrapOptional.playground/xcuserdata/lexone01.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | UnwrapOptional (Playground).xcscheme 8 | 9 | isShown 10 | 11 | orderHint 12 | 0 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /patterns-and-architectures/v073-MVVM+Combine/MVVM_simple.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /patterns-and-architectures/v073-MVVM+Combine/MVVM_simple/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // MVVM_simple 4 | // 5 | // Created by Alex Krzywicki on 23.12.2021. 6 | // 7 | 8 | import UIKit 9 | 10 | @main 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | 13 | 14 | 15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 16 | // Override point for customization after application launch. 17 | return true 18 | } 19 | 20 | // MARK: UISceneSession Lifecycle 21 | 22 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 23 | // Called when a new scene session is being created. 24 | // Use this method to select a configuration to create the new scene with. 25 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 26 | } 27 | 28 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 29 | // Called when the user discards a scene session. 30 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 31 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 32 | } 33 | 34 | 35 | } 36 | 37 | -------------------------------------------------------------------------------- /patterns-and-architectures/v073-MVVM+Combine/MVVM_simple/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /patterns-and-architectures/v073-MVVM+Combine/MVVM_simple/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | } 93 | ], 94 | "info" : { 95 | "author" : "xcode", 96 | "version" : 1 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /patterns-and-architectures/v073-MVVM+Combine/MVVM_simple/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /patterns-and-architectures/v073-MVVM+Combine/MVVM_simple/Extensions/String+Extension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // String+Extension.swift 3 | // MVVM_simple 4 | // 5 | // Created by Alexey Krzywicki on 04.12.2022. 6 | // 7 | 8 | import Foundation 9 | 10 | extension String { 11 | struct EmailValidation { 12 | private static let firstpart = "[A-Z0-9a-z]([A-Z0-9a-z._%+-]{0,30}[A-Z0-9a-z])?" 13 | private static let serverpart = "([A-Z0-9a-z]([A-Z0-9a-z-]{0,30}[A-Z0-9a-z])?\\.){1,5}" 14 | private static let emailRegex = firstpart + "@" + serverpart + "[A-Za-z]{2,8}" 15 | static let emailPredicate = NSPredicate(format: "SELF MATCHES %@", emailRegex) 16 | } 17 | 18 | func isEmail() -> Bool { 19 | return EmailValidation.emailPredicate.evaluate(with: self) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /patterns-and-architectures/v073-MVVM+Combine/MVVM_simple/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIApplicationSceneManifest 6 | 7 | UIApplicationSupportsMultipleScenes 8 | 9 | UISceneConfigurations 10 | 11 | UIWindowSceneSessionRoleApplication 12 | 13 | 14 | UISceneConfigurationName 15 | Default Configuration 16 | UISceneDelegateClassName 17 | $(PRODUCT_MODULE_NAME).SceneDelegate 18 | UISceneStoryboardFile 19 | Main 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /patterns-and-architectures/v073-MVVM+Combine/MVVM_simple/Models/User.swift: -------------------------------------------------------------------------------- 1 | // 2 | // User.swift 3 | // MVVM_simple 4 | // 5 | // Created by Alex Krzywicki on 23.12.2021. 6 | // 7 | 8 | import Foundation 9 | 10 | struct User { 11 | let login: String? 12 | let passwords: String? 13 | } 14 | -------------------------------------------------------------------------------- /patterns-and-architectures/v073-MVVM+Combine/MVVM_simple/ViewModels/ViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewModel.swift 3 | // MVVM_simple 4 | // 5 | // Created by Alex Krzywicki on 23.12.2021. 6 | // 7 | 8 | import Foundation 9 | import Combine 10 | 11 | enum ViewState { 12 | case loading 13 | case success 14 | case failed 15 | case none 16 | } 17 | 18 | class ViewModel { 19 | 20 | @Published var email = "" 21 | @Published var password = "" 22 | @Published var state: ViewState = .none 23 | 24 | var isValidUsernamePublisher: AnyPublisher { 25 | $email 26 | .map { $0.isEmail() } 27 | .eraseToAnyPublisher() 28 | } 29 | 30 | var isValidPasswordPublisher: AnyPublisher { 31 | $password 32 | .map { !$0.isEmpty } 33 | .eraseToAnyPublisher() 34 | } 35 | 36 | var isLoginEnabled: AnyPublisher { 37 | Publishers.CombineLatest(isValidUsernamePublisher, isValidPasswordPublisher) 38 | .map { $0 && $1 } 39 | .eraseToAnyPublisher() 40 | } 41 | 42 | func submitLogin() { 43 | state = .loading 44 | 45 | DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2)) { [weak self] in 46 | guard let self = self else { return } 47 | if self.isCorrectLogin() { 48 | self.state = .success 49 | } else { 50 | self.state = .failed 51 | } 52 | } 53 | } 54 | 55 | func isCorrectLogin() -> Bool { 56 | return email == "test@mail.com" && password == "12345" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /patterns-and-architectures/v073-MVVM+Combine/MVVM_simple/Views/Stryboards/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /patterns-and-architectures/v074-SingletonExample/SingletonExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /patterns-and-architectures/v074-SingletonExample/SingletonExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /patterns-and-architectures/v074-SingletonExample/SingletonExample/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SingletonExample 4 | // 5 | // Created by Alexey Krzywicki on 01.01.2023. 6 | // 7 | 8 | import UIKit 9 | 10 | @main 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | 13 | 14 | 15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 16 | // Override point for customization after application launch. 17 | return true 18 | } 19 | 20 | // MARK: UISceneSession Lifecycle 21 | 22 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 23 | // Called when a new scene session is being created. 24 | // Use this method to select a configuration to create the new scene with. 25 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 26 | } 27 | 28 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 29 | // Called when the user discards a scene session. 30 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 31 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 32 | } 33 | 34 | 35 | } 36 | 37 | -------------------------------------------------------------------------------- /patterns-and-architectures/v074-SingletonExample/SingletonExample/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /patterns-and-architectures/v074-SingletonExample/SingletonExample/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "platform" : "ios", 6 | "size" : "1024x1024" 7 | } 8 | ], 9 | "info" : { 10 | "author" : "xcode", 11 | "version" : 1 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /patterns-and-architectures/v074-SingletonExample/SingletonExample/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /patterns-and-architectures/v074-SingletonExample/SingletonExample/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /patterns-and-architectures/v074-SingletonExample/SingletonExample/EditViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EditViewController.swift 3 | // SingletonExample 4 | // 5 | // Created by Alexey Krzywicki on 01.01.2023. 6 | // 7 | 8 | import UIKit 9 | 10 | class EditViewController: UIViewController { 11 | 12 | @IBOutlet weak var textField: UITextField! 13 | private let salats = SalatModel.shared 14 | 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | textField.text = salats.data[salats.currentIndex] 18 | } 19 | 20 | 21 | @IBAction func buttonPressed(_ sender: Any) { 22 | salats.editItem(oldSalat: salats.data[salats.currentIndex], newSalat: textField.text ?? "") 23 | navigationController?.popViewController(animated: true) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /patterns-and-architectures/v074-SingletonExample/SingletonExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIApplicationSceneManifest 6 | 7 | UIApplicationSupportsMultipleScenes 8 | 9 | UISceneConfigurations 10 | 11 | UIWindowSceneSessionRoleApplication 12 | 13 | 14 | UISceneConfigurationName 15 | Default Configuration 16 | UISceneDelegateClassName 17 | $(PRODUCT_MODULE_NAME).SceneDelegate 18 | UISceneStoryboardFile 19 | Main 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /patterns-and-architectures/v074-SingletonExample/SingletonExample/SalatCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SalatCell.swift 3 | // SingletonExample 4 | // 5 | // Created by Alexey Krzywicki on 01.01.2023. 6 | // 7 | 8 | import UIKit 9 | 10 | class SalatCell: UITableViewCell { 11 | 12 | @IBOutlet weak var titleLabel: UILabel! 13 | 14 | static let id = "SalatCell" 15 | 16 | override func awakeFromNib() { 17 | super.awakeFromNib() 18 | } 19 | 20 | override func setSelected(_ selected: Bool, animated: Bool) { 21 | super.setSelected(selected, animated: animated) 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /patterns-and-architectures/v074-SingletonExample/SingletonExample/SalatModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SalatModel.swift 3 | // SingletonExample 4 | // 5 | // Created by Alexey Krzywicki on 01.01.2023. 6 | // 7 | 8 | import Foundation 9 | 10 | class SalatModel: NSObject { 11 | 12 | static let shared = SalatModel() 13 | 14 | public var data = [String]() 15 | public var currentIndex = 0 16 | 17 | func addNewItem(salat: String) { 18 | data.append(salat) 19 | } 20 | 21 | func removeItem(salat: String) { 22 | data = data.filter { $0 != salat } 23 | } 24 | 25 | func editItem(oldSalat: String, newSalat: String) { 26 | let index = data.indices.filter { data[$0].localizedCaseInsensitiveContains(oldSalat) } 27 | data[index[0]] = newSalat 28 | } 29 | 30 | func deleteData() { 31 | data = [String]() 32 | } 33 | 34 | func fillWithTestData() { 35 | data = ["Оливье", "Мимоза", "Крабовый", "Селедка под шубой", "Домашний", "Мясной", "С кальмарами", "Винегрет"] 36 | } 37 | 38 | } 39 | --------------------------------------------------------------------------------