├── .gitattributes ├── .gitignore ├── Chapter01 └── Snippets.playground │ ├── Contents.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ └── emil.xcuserdatad │ └── UserInterfaceState.xcuserstate ├── Chapter02 ├── Swift 4 by examples.playground │ ├── Contents.swift │ ├── Resources │ │ └── open_xcode.png │ ├── Sources │ │ └── Functions.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ └── emil.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── Swift 4 workspace.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ └── emil.xcuserdatad │ ├── UserInterfaceState.xcuserstate │ └── xcschemes │ ├── test.xcscheme │ └── xcschememanagement.plist ├── Chapter03 └── My First iOS app │ ├── My First iOS app.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── emil.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── emil.xcuserdatad │ │ └── xcschemes │ │ ├── My First iOS app.xcscheme │ │ └── xcschememanagement.plist │ ├── My First iOS app │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ └── ViewController.swift │ └── My First iOS appUITests │ ├── Info.plist │ └── My_First_iOS_appUITests.swift ├── Chapter04 └── MyPlayground.playground │ ├── Contents.swift │ ├── Sources │ ├── ForecastData.swift │ ├── Weather.swift │ ├── WeatherController.swift │ ├── WeatherModel.swift │ ├── WeatherView.swift │ └── WindData.swift │ ├── contents.xcplayground │ ├── playground.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── emil.xcuserdatad │ │ └── UserInterfaceState.xcuserstate │ └── timeline.xctimeline ├── Chapter05 └── My First iOS app │ ├── My First iOS app.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── emil.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── emil.xcuserdatad │ │ └── xcschemes │ │ ├── My First iOS app.xcscheme │ │ └── xcschememanagement.plist │ ├── My First iOS app │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ └── ViewController.swift │ ├── My First iOS appUITests │ ├── Info.plist │ └── My_First_iOS_appUITests.swift │ └── swift_logo.png ├── Chapter06 ├── Chapter 6.playground │ ├── Contents.swift │ ├── contents.xcplayground │ ├── playground.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── emil.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── timeline.xctimeline └── CityPickerDemo │ ├── CityPickerDemo.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── emil.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── emil.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ ├── CityPickerDemo.xcscheme │ │ └── xcschememanagement.plist │ └── CityPickerDemo │ ├── AppDelegate.swift │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── DataStorage.swift │ ├── Info.plist │ └── ViewController.swift ├── Chapter07 ├── WeatherApp.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── emil.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── emil.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ ├── WeatherApp.xcscheme │ │ └── xcschememanagement.plist └── WeatherApp │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── cloudy.imageset │ │ ├── Contents.json │ │ └── cloudy.png │ ├── hail.imageset │ │ ├── Contents.json │ │ └── hail.png │ ├── heavy_rain.imageset │ │ ├── Contents.json │ │ └── heavy_rain.png │ ├── partly_cloudy.imageset │ │ ├── Contents.json │ │ └── partly_cloudy.png │ ├── rain.imageset │ │ ├── Contents.json │ │ └── rain.png │ ├── rainy_weather.imageset │ │ ├── Contents.json │ │ └── rainy_weather.png │ ├── show_storm.imageset │ │ ├── Contents.json │ │ └── show_storm.png │ ├── snow.imageset │ │ ├── Contents.json │ │ └── snow.png │ ├── snowflake.imageset │ │ ├── Contents.json │ │ └── snowflake.png │ ├── storm.imageset │ │ ├── Contents.json │ │ └── storm.png │ ├── sunny.imageset │ │ ├── Contents.json │ │ └── sunny.png │ ├── sunrise.imageset │ │ ├── Contents.json │ │ └── sunrise.png │ ├── sunset.imageset │ │ ├── Contents.json │ │ └── sunset.png │ └── windy.imageset │ │ ├── Contents.json │ │ └── windy.png │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── DailyForecastViewCell.swift │ ├── FavoriteViewCell.swift │ ├── FavoritesViewController.swift │ ├── Info.plist │ ├── LocationForecast.swift │ ├── PlacesViewCell.swift │ ├── PlacesViewController.swift │ ├── ViewController.swift │ ├── WeatherViewCell.swift │ └── ZoomInSegue.swift ├── Chapter08 ├── WeatherApp cocoapods │ ├── Podfile │ ├── WeatherApp.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcuserdata │ │ │ │ └── emil.xcuserdatad │ │ │ │ └── UserInterfaceState.xcuserstate │ │ └── xcuserdata │ │ │ └── emil.xcuserdatad │ │ │ ├── xcdebugger │ │ │ └── Breakpoints_v2.xcbkptlist │ │ │ └── xcschemes │ │ │ ├── WeatherApp.xcscheme │ │ │ └── xcschememanagement.plist │ ├── WeatherApp.xcworkspace │ │ └── contents.xcworkspacedata │ └── WeatherApp │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── cloudy.imageset │ │ │ ├── Contents.json │ │ │ └── cloudy.png │ │ ├── hail.imageset │ │ │ ├── Contents.json │ │ │ └── hail.png │ │ ├── heavy_rain.imageset │ │ │ ├── Contents.json │ │ │ └── heavy_rain.png │ │ ├── partly_cloudy.imageset │ │ │ ├── Contents.json │ │ │ └── partly_cloudy.png │ │ ├── rain.imageset │ │ │ ├── Contents.json │ │ │ └── rain.png │ │ ├── rainy_weather.imageset │ │ │ ├── Contents.json │ │ │ └── rainy_weather.png │ │ ├── show_storm.imageset │ │ │ ├── Contents.json │ │ │ └── show_storm.png │ │ ├── snow.imageset │ │ │ ├── Contents.json │ │ │ └── snow.png │ │ ├── snowflake.imageset │ │ │ ├── Contents.json │ │ │ └── snowflake.png │ │ ├── storm.imageset │ │ │ ├── Contents.json │ │ │ └── storm.png │ │ ├── sunny.imageset │ │ │ ├── Contents.json │ │ │ └── sunny.png │ │ ├── sunrise.imageset │ │ │ ├── Contents.json │ │ │ └── sunrise.png │ │ ├── sunset.imageset │ │ │ ├── Contents.json │ │ │ └── sunset.png │ │ └── windy.imageset │ │ │ ├── Contents.json │ │ │ └── windy.png │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── DailyForecastViewCell.swift │ │ ├── FavoriteViewCell.swift │ │ ├── FavoritesViewController.swift │ │ ├── Info.plist │ │ ├── LocationForecast.swift │ │ ├── PlacesViewCell.swift │ │ ├── PlacesViewController.swift │ │ ├── ViewController.swift │ │ ├── WeatherViewCell.swift │ │ └── ZoomInSegue.swift ├── swift-executable │ ├── .gitignore │ ├── Package.resolved │ ├── Package.swift │ ├── README.md │ └── Sources │ │ └── swift-executable │ │ └── main.swift └── swift-lib │ ├── .gitignore │ ├── Package.swift │ ├── README.md │ ├── Sources │ └── swift-lib │ │ └── swift_lib.swift │ └── Tests │ ├── LinuxMain.swift │ └── swift-libTests │ └── swift_libTests.swift ├── Chapter09 └── WeatherApp │ ├── Podfile │ ├── WeatherApp.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── emil.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── emil.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ ├── WeatherApp.xcscheme │ │ └── xcschememanagement.plist │ ├── WeatherApp.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── emil.xcuserdatad │ │ ├── UserInterfaceState.xcuserstate │ │ └── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ └── WeatherApp │ ├── AboutViewController.swift │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── cloudy.imageset │ │ ├── Contents.json │ │ └── cloudy.png │ ├── hail.imageset │ │ ├── Contents.json │ │ └── hail.png │ ├── heavy_rain.imageset │ │ ├── Contents.json │ │ └── heavy_rain.png │ ├── partly_cloudy.imageset │ │ ├── Contents.json │ │ └── partly_cloudy.png │ ├── rain.imageset │ │ ├── Contents.json │ │ └── rain.png │ ├── rainy_weather.imageset │ │ ├── Contents.json │ │ └── rainy_weather.png │ ├── show_storm.imageset │ │ ├── Contents.json │ │ └── show_storm.png │ ├── snow.imageset │ │ ├── Contents.json │ │ └── snow.png │ ├── snowflake.imageset │ │ ├── Contents.json │ │ └── snowflake.png │ ├── storm.imageset │ │ ├── Contents.json │ │ └── storm.png │ ├── sunny.imageset │ │ ├── Contents.json │ │ └── sunny.png │ ├── sunrise.imageset │ │ ├── Contents.json │ │ └── sunrise.png │ ├── sunset.imageset │ │ ├── Contents.json │ │ └── sunset.png │ └── windy.imageset │ │ ├── Contents.json │ │ └── windy.png │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── DailyForecastViewCell.swift │ ├── FavoriteViewCell.swift │ ├── FavoritesViewController.swift │ ├── ForecastStore.swift │ ├── Info.plist │ ├── LocationForecast.swift │ ├── PlacesViewCell.swift │ ├── PlacesViewController.swift │ ├── ViewController.swift │ ├── WeatherViewCell.swift │ └── ZoomInSegue.swift ├── Chapter10 ├── InstagramLikeApp │ ├── InstagramLikeApp.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ ├── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ └── xcuserdata │ │ │ │ └── emil.xcuserdatad │ │ │ │ └── UserInterfaceState.xcuserstate │ │ └── xcuserdata │ │ │ └── emil.xcuserdatad │ │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ ├── InstagramLikeApp │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ ├── favorites.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── favorites@x2.png │ │ │ ├── first.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── first.pdf │ │ │ ├── home.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── home@x2.png │ │ │ ├── photo.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── photo@x2.png │ │ │ ├── photo_verybig.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── photo_verybig.png │ │ │ │ └── photo_verybig@2x.png │ │ │ ├── search.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── search@x2.png │ │ │ ├── second.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── second.pdf │ │ │ └── user.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── user@x2.png │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── CreatePostViewController.swift │ │ ├── DataManager.swift │ │ ├── FirstViewController.swift │ │ ├── GoogleService-Info.plist │ │ ├── Info.plist │ │ ├── InstagramTabbarController.swift │ │ ├── SecondViewController.swift │ │ └── SignInViewController.swift │ └── Podfile └── icon-set │ ├── comment.png │ ├── comment@x2.png │ ├── create_post.png │ ├── create_post@2x.org.png │ ├── create_post@2x.png │ ├── favorite.png │ ├── favorites.png │ ├── favorites@x2.png │ ├── home.png │ ├── home@x2.png │ ├── org │ ├── comment.png │ ├── favorites.png │ ├── home.png │ ├── photo.png │ ├── search.png │ ├── send.png │ └── user.png │ ├── photo.png │ ├── photo@x2.png │ ├── search.png │ ├── search@x2.png │ ├── send.png │ ├── send@x2.png │ ├── user.png │ └── user@x2.png ├── Chapter11 └── InstagramLikeApp │ ├── InstagramLikeApp.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── emil.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── emil.xcuserdatad │ │ └── xcschemes │ │ ├── InstagramLikeApp.xcscheme │ │ └── xcschememanagement.plist │ ├── InstagramLikeApp │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── comment.imageset │ │ │ ├── Contents.json │ │ │ └── comment@x2.png │ │ ├── create_post.imageset │ │ │ ├── Contents.json │ │ │ ├── create_post.png │ │ │ └── create_post@2x.png │ │ ├── favorites.imageset │ │ │ ├── Contents.json │ │ │ └── favorites@x2.png │ │ ├── home.imageset │ │ │ ├── Contents.json │ │ │ └── home@x2.png │ │ ├── loading.imageset │ │ │ ├── Contents.json │ │ │ └── loading.png │ │ ├── photo.imageset │ │ │ ├── Contents.json │ │ │ └── photo@x2.png │ │ ├── photo_verybig.imageset │ │ │ ├── Contents.json │ │ │ ├── photo_verybig.png │ │ │ └── photo_verybig@2x.png │ │ ├── search.imageset │ │ │ ├── Contents.json │ │ │ └── search@x2.png │ │ ├── send.imageset │ │ │ ├── Contents.json │ │ │ └── send@x2.png │ │ └── user.imageset │ │ │ ├── Contents.json │ │ │ └── user@x2.png │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── CreatePostViewController.swift │ ├── DataManager.swift │ ├── FavoritesViewController.swift │ ├── FeedViewCell.swift │ ├── FeedViewCell.xib │ ├── FirstViewController.swift │ ├── GoogleService-Info.plist │ ├── GridLayout.swift │ ├── HomeFeedViewController.swift │ ├── Info.plist │ ├── InstagramTabbarController.swift │ ├── PhotoViewCell.swift │ ├── PhotoViewCell.xib │ ├── ProfileViewController.swift │ ├── SearchViewController.swift │ └── SignInViewController.swift │ └── Podfile ├── Chapter12 └── YPImagePicker_source_with_contribution │ ├── .gitignore │ ├── .swift-version │ ├── .swiftlint.yml │ ├── CODE_OF_CONDUCT.md │ ├── Cartfile │ ├── Cartfile.resolved │ ├── Images │ ├── filters.PNG │ ├── library.PNG │ ├── photo.PNG │ ├── video.PNG │ └── visual.jpg │ ├── LICENSE │ ├── README.md │ ├── Resources │ ├── Assets.xcassets │ │ ├── Contents.json │ │ ├── yp_arrow.imageset │ │ │ ├── Arrow.pdf │ │ │ └── Contents.json │ │ ├── yp_iconCapture.imageset │ │ │ ├── Contents.json │ │ │ └── iconCapture2.pdf │ │ ├── yp_iconCrop.imageset │ │ │ ├── Contents.json │ │ │ └── yp_iconCrop.pdf │ │ ├── yp_iconFlash_auto.imageset │ │ │ ├── Contents.json │ │ │ └── yp_iconFlash_auto.pdf │ │ ├── yp_iconFlash_off.imageset │ │ │ ├── Contents.json │ │ │ └── yp_icon_flash_off.pdf │ │ ├── yp_iconFlash_on.imageset │ │ │ ├── Contents.json │ │ │ └── yp_iconFlash.pdf │ │ ├── yp_iconLoop.imageset │ │ │ ├── Contents.json │ │ │ └── yp_iconLoop.pdf │ │ ├── yp_iconVideoCapture.imageset │ │ │ ├── Contents.json │ │ │ └── iconCapture Copy.pdf │ │ └── yp_iconVideoCaptureRecording.imageset │ │ │ ├── Contents.json │ │ │ └── iconCapture Copy 2.pdf │ ├── ar.lproj │ │ └── Localizable.strings │ ├── en.lproj │ │ └── Localizable.strings │ ├── es.lproj │ │ └── Localizable.strings │ ├── fr.lproj │ │ └── Localizable.strings │ ├── nl.lproj │ │ └── Localizable.strings │ ├── pt-BR.lproj │ │ └── Localizable.strings │ ├── ru.lproj │ │ └── Localizable.strings │ └── tr.lproj │ │ └── Localizable.strings │ ├── Source │ ├── BottomPager │ │ ├── YPBottomPager.swift │ │ ├── YPBottomPagerView.swift │ │ ├── YPMenuItem.swift │ │ └── YPPagerMenu.swift │ ├── Camera │ │ ├── PostiOS10PhotoCapture.swift │ │ ├── PreiOS10PhotoCapture.swift │ │ ├── YPCameraVC.swift │ │ ├── YPCameraView.swift │ │ ├── YPPhotoCapture.swift │ │ └── YPPhotoCaptureDefaults.swift │ ├── Configuration │ │ ├── YPFilterDescriptor.swift │ │ ├── YPImagePickerConfiguration.swift │ │ ├── YPLibraryImageSize.swift │ │ ├── YPPickerScreen.swift │ │ └── YPWordings.swift │ ├── Crop │ │ ├── YPCropVC.swift │ │ └── YPCropView.swift │ ├── Filters │ │ ├── YPFilter.swift │ │ ├── YPFilterCollectionViewCell.swift │ │ ├── YPFilterPreview.swift │ │ ├── YPFiltersVC.swift │ │ └── YPFiltersView.swift │ ├── Helpers │ │ ├── CGRect+Difference.swift │ │ ├── IndexSet+IndexPath.swift │ │ ├── PHCachingImageManager+Helpers.swift │ │ ├── PHFetchResult + IndexPath.swift │ │ ├── PermissionCheckable.swift │ │ ├── UICollectionView+IndexPath.swift │ │ ├── UIImage+ResetOrientation.swift │ │ ├── YPAlerts.swift │ │ ├── YPDragDirection.swift │ │ ├── YPHelpers.swift │ │ ├── YPPermissionDeniedPopup.swift │ │ └── YPPhotoSaver.swift │ ├── Info.plist │ ├── Library │ │ ├── LibraryMediaManager.swift │ │ ├── YPAlbum.swift │ │ ├── YPAlbumCell.swift │ │ ├── YPAlbumVC.swift │ │ ├── YPAlbumView.swift │ │ ├── YPAlbumsManager.swift │ │ ├── YPGridView.swift │ │ ├── YPImageCropView.swift │ │ ├── YPImageCropViewContainer.swift │ │ ├── YPLibrary+LibraryChange.swift │ │ ├── YPLibraryVC + UIHelpers.swift │ │ ├── YPLibraryVC+CollectionView.swift │ │ ├── YPLibraryVC+PanGesture.swift │ │ ├── YPLibraryVC.swift │ │ ├── YPLibraryView.swift │ │ ├── YPLibraryView.xib │ │ ├── YPLibraryViewCell.swift │ │ └── YPLibraryViewDelegate.swift │ ├── Video │ │ ├── YPVideoHelper.swift │ │ └── YPVideoVC.swift │ ├── YPImagePicker.swift │ ├── YPImagePickerHeader.h │ └── YPPickerVC.swift │ ├── YPImagePicker.podspec │ └── YPImagePicker.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ └── xcschemes │ └── YPImagePicker.xcscheme └── Readme.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /Chapter01/Snippets.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter01/Snippets.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Chapter01/Snippets.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter01/Snippets.playground/playground.xcworkspace/xcuserdata/emil.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter01/Snippets.playground/playground.xcworkspace/xcuserdata/emil.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Chapter02/Swift 4 by examples.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | // some comment 3 | import UIKit 4 | 5 | 6 | var str = "Hello, playground" 7 | 8 | switch str { 9 | case "swift": 10 | print("Hello, Swift 4!") 11 | default: 12 | print("Who are you?") 13 | } 14 | 15 | var sum = 0 16 | for i in 1...5 { 17 | print("\(i)") 18 | 19 | sum += i 20 | } 21 | 22 | test("hi") 23 | 24 | let img = UIImage(named: "open_xcode.png") 25 | 26 | 27 | //markup 28 | //: # Header Big 29 | //: ## Header Normal 30 | //: ### Header Small 31 | 32 | 33 | //: List 34 | //: * option 1 35 | //: * option 2 36 | //: * option 3 37 | //: - option 3.1 38 | 39 | //: Enumerated list 40 | //: 1. option 1 41 | //: 1. option 2 42 | //: 1. option 3 43 | 44 | 45 | //: This is _italic_ text. 46 | 47 | //: This is __bold__ text. 48 | 49 | //: This is ___bold & italic___ text. 50 | 51 | //: This is **bold** text. 52 | 53 | //: The code ```let x = 5``` has different style. 54 | 55 | //: An example follows: 56 | 57 | //: var a = 13 58 | //: var b = a + 7 59 | 60 | 61 | 62 | //: - Note: 63 | //:"You can learn Swift 4." 64 | //: \ 65 | //: \ 66 | //: Playgrounds are really nice place to learn Swift 4. 67 | 68 | //: ![Image from resources](open_xcode.png) 69 | 70 | //: [Swift](https://swift.org) 71 | 72 | -------------------------------------------------------------------------------- /Chapter02/Swift 4 by examples.playground/Resources/open_xcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter02/Swift 4 by examples.playground/Resources/open_xcode.png -------------------------------------------------------------------------------- /Chapter02/Swift 4 by examples.playground/Sources/Functions.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | /** 3 | * Don't forget to add public, to make your functions, vairables, classes, structures or any other types visible to the playground. 4 | **/ 5 | public func test(_ test:String) { 6 | print("Calling \(#function)") 7 | } 8 | -------------------------------------------------------------------------------- /Chapter02/Swift 4 by examples.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Chapter02/Swift 4 by examples.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Chapter02/Swift 4 by examples.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter02/Swift 4 by examples.playground/playground.xcworkspace/xcuserdata/emil.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter02/Swift 4 by examples.playground/playground.xcworkspace/xcuserdata/emil.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Chapter02/Swift 4 workspace.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Chapter02/Swift 4 workspace.xcworkspace/xcuserdata/emil.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter02/Swift 4 workspace.xcworkspace/xcuserdata/emil.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Chapter02/Swift 4 workspace.xcworkspace/xcuserdata/emil.xcuserdatad/xcschemes/test.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 14 | 15 | 16 | 17 | 18 | 19 | 29 | 30 | 31 | 32 | 38 | 39 | 41 | 42 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /Chapter02/Swift 4 workspace.xcworkspace/xcuserdata/emil.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | test.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Chapter03/My First iOS app/My First iOS app.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Chapter03/My First iOS app/My First iOS app.xcodeproj/project.xcworkspace/xcuserdata/emil.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter03/My First iOS app/My First iOS app.xcodeproj/project.xcworkspace/xcuserdata/emil.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Chapter03/My First iOS app/My First iOS app.xcodeproj/xcuserdata/emil.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | My First iOS app.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 2023BACB1EC0B9AD00F4ECD9 16 | 17 | primary 18 | 19 | 20 | 2023BADF1EC0B9AD00F4ECD9 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Chapter03/My First iOS app/My First iOS app/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 | 27 | 28 | -------------------------------------------------------------------------------- /Chapter03/My First iOS app/My First iOS app/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 | 26 | 27 | -------------------------------------------------------------------------------- /Chapter03/My First iOS app/My First iOS app/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Chapter03/My First iOS app/My First iOS app/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // My First iOS app 4 | // 5 | // Created by Emil Atanasov on 5/8/17. 6 | // Copyright © 2017 Appose Studio Inc. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | //my dummy comment 11 | class ViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | // Do any additional setup after loading the view, typically from a nib. 16 | } 17 | 18 | override func didReceiveMemoryWarning() { 19 | super.didReceiveMemoryWarning() 20 | // Dispose of any resources that can be recreated. 21 | } 22 | 23 | 24 | } 25 | 26 | -------------------------------------------------------------------------------- /Chapter03/My First iOS app/My First iOS appUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Chapter03/My First iOS app/My First iOS appUITests/My_First_iOS_appUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // My_First_iOS_appUITests.swift 3 | // My First iOS appUITests 4 | // 5 | // Created by Emil Atanasov on 5/8/17. 6 | // Copyright © 2017 Appose Studio Inc. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class My_First_iOS_appUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | 18 | // In UI tests it is usually best to stop immediately when a failure occurs. 19 | continueAfterFailure = false 20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 21 | XCUIApplication().launch() 22 | 23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 24 | } 25 | 26 | override func tearDown() { 27 | // Put teardown code here. This method is called after the invocation of each test method in the class. 28 | super.tearDown() 29 | } 30 | 31 | func testExample() { 32 | // Use recording to get started writing UI tests. 33 | // Use XCTAssert and related functions to verify your tests produce the correct results. 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Chapter04/MyPlayground.playground/Sources/ForecastData.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /** 4 | * Structure which describes the weather in specific point in time 5 | * It contians the most important details. 6 | **/ 7 | public struct ForecastData { 8 | public var hour: Int 9 | public var temp: Double 10 | public var minTemp: Double 11 | public var maxTemp: Double 12 | public var pressure: Double 13 | public var humidity: Double 14 | 15 | public var clouds: Double 16 | public var wind: WindData 17 | 18 | public var description: String 19 | public var icon: String? 20 | } 21 | 22 | public extension ForecastData { 23 | init() { 24 | self.hour = 0 25 | self.temp = 0 26 | self.minTemp = 0.0 27 | self.maxTemp = 0.0 28 | self.pressure = 0.0 29 | self.humidity = 0.0 30 | self.clouds = 0.0 31 | 32 | self.wind = WindData(speed: 0, degrees: 0, direction: "none") 33 | self.description = "Empty object" 34 | self.icon = nil 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Chapter04/MyPlayground.playground/Sources/Weather.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /*** 4 | * Structure which describes the Weather. It contains an array of ForcastData for each hour. 5 | * The location property contains the location where the forcast is applicable. 6 | * The date property contains the day of the forcast. 7 | **/ 8 | public struct Weather { 9 | public var hours: [ForecastData] 10 | internal (set) public var location: String 11 | internal (set) public var date: Date 12 | 13 | // public initializator, because it should be visible 14 | public init(hours:[ForecastData], location:String, date:Date) { 15 | self.hours = hours 16 | self.location = location 17 | self.date = date 18 | } 19 | } 20 | 21 | public extension Weather { 22 | init() { 23 | self.hours = [] 24 | self.location = "Nowhere" 25 | self.date = Date() 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Chapter04/MyPlayground.playground/Sources/WeatherController.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public class WeatherController { 4 | public var view:WeatherView? 5 | public var model:WeatherModel? 6 | 7 | public init() { 8 | 9 | } 10 | 11 | public var location:String { 12 | get { 13 | return model?.getWeather().location ?? "Unknown" 14 | } 15 | } 16 | 17 | public var date:Date { 18 | get { 19 | return model?.getWeather().date ?? Date() 20 | } 21 | } 22 | } 23 | 24 | extension WeatherController:WeatherViewListner { 25 | public func showWeather(forDate:Date) { 26 | print("[Controller] Handle all user interactions.") 27 | 28 | print("[Controller] If necessary the model is updated.") 29 | 30 | model?.update() 31 | } 32 | } 33 | 34 | extension WeatherController:WeatherModelObserver { 35 | public func modelHasChanged(model:WeatherModel) { 36 | print("[Controller] The model has been updated.") 37 | 38 | print("[Controller] Check if the view should be updated.") 39 | 40 | view?.refresh(location: "New York") 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Chapter04/MyPlayground.playground/Sources/WeatherModel.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public protocol WeatherModelObserver { 4 | func modelHasChanged(model:WeatherModel) 5 | } 6 | 7 | public class WeatherModel { 8 | private var weather:Weather 9 | public var modelObserver:WeatherModelObserver? 10 | 11 | public init(weather:Weather) { 12 | self.weather = weather 13 | } 14 | 15 | public func setNewWeater(weather:Weather) { 16 | print("[Model] The model has been changed.") 17 | self.weather = weather 18 | if modelObserver != nil { 19 | modelObserver?.modelHasChanged(model: self) 20 | } 21 | } 22 | 23 | public func getWeather() -> Weather { 24 | return self.weather 25 | } 26 | 27 | func update() { 28 | print("[Model] Update the model") 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /Chapter04/MyPlayground.playground/Sources/WeatherView.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public protocol WeatherViewListner { 4 | func showWeather(forDate:Date) 5 | } 6 | 7 | public class WeatherView { 8 | private var toNotify:WeatherViewListner? 9 | private var location:String 10 | private var date:Date 11 | private var dateFormatter:DateFormatter 12 | 13 | public init(location:String, date:Date, listener:WeatherViewListner?) { 14 | self.location = location 15 | self.date = date 16 | self.toNotify = listener 17 | 18 | self.dateFormatter = DateFormatter() 19 | dateFormatter.dateStyle = .medium 20 | dateFormatter.timeStyle = .none 21 | // DateFormatter.dateFormat(fromTemplate: "yyyy-MM-dd", options: 0, locale: Locale(identifier: "en_US")) 22 | 23 | } 24 | 25 | public func simulateUserAction() { 26 | print("[View] Detect user interactions and react.") 27 | // update the visual part 28 | // and notify the controller 29 | if toNotify != nil { 30 | toNotify?.showWeather(forDate: Date()) 31 | } 32 | } 33 | 34 | public func draw() { 35 | let d = self.dateFormatter.string(from: self.date) 36 | print("[View] \(d) - \(self.location) =>") 37 | } 38 | 39 | public func refresh(location:String) { 40 | print("[View] The view is updated and will be redrawn") 41 | 42 | draw() 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Chapter04/MyPlayground.playground/Sources/WindData.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | /** 3 | * Structure which contains extra data, describing the wind. 4 | **/ 5 | public struct WindData { 6 | public var speed: Double 7 | public var degrees: Double 8 | public var direction: String 9 | } 10 | -------------------------------------------------------------------------------- /Chapter04/MyPlayground.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter04/MyPlayground.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Chapter04/MyPlayground.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter04/MyPlayground.playground/playground.xcworkspace/xcuserdata/emil.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter04/MyPlayground.playground/playground.xcworkspace/xcuserdata/emil.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Chapter04/MyPlayground.playground/timeline.xctimeline: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Chapter05/My First iOS app/My First iOS app.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Chapter05/My First iOS app/My First iOS app.xcodeproj/project.xcworkspace/xcuserdata/emil.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter05/My First iOS app/My First iOS app.xcodeproj/project.xcworkspace/xcuserdata/emil.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Chapter05/My First iOS app/My First iOS app.xcodeproj/xcuserdata/emil.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | My First iOS app.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 2023BACB1EC0B9AD00F4ECD9 16 | 17 | primary 18 | 19 | 20 | 2023BADF1EC0B9AD00F4ECD9 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Chapter05/My First iOS app/My First iOS app/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Chapter05/My First iOS app/My First iOS app/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // My First iOS app 4 | // 5 | // Created by Emil Atanasov on 5/8/17. 6 | // Copyright © 2017 Appose Studio Inc. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | //my dummy comment 11 | class ViewController: UIViewController { 12 | 13 | @IBOutlet var fireButton:UIButton! 14 | 15 | @IBAction func clickHandler(_ sender: UIButton) { 16 | 17 | let red:CGFloat = CGFloat(drand48()) 18 | let green:CGFloat = CGFloat(drand48()) 19 | let blue:CGFloat = CGFloat(drand48()) 20 | //change the background color 21 | self.view.backgroundColor = UIColor.init(red: red, green: green, blue: blue, alpha: 1) 22 | } 23 | 24 | //image view 25 | @IBOutlet var imageView:UIImageView! 26 | 27 | @IBAction func switchHandle(_ sender: UISwitch) { 28 | 29 | imageView.isHidden = !sender.isOn 30 | } 31 | override func viewDidLoad() { 32 | super.viewDidLoad() 33 | // Do any additional setup after loading the view, typically from a nib. 34 | 35 | fireButton.addTarget(self, action: #selector(ViewController.fireClickHandler(_:)), for: UIControlEvents.touchUpInside) 36 | 37 | imageView.isHidden = true 38 | } 39 | 40 | override func didReceiveMemoryWarning() { 41 | super.didReceiveMemoryWarning() 42 | // Dispose of any resources that can be recreated. 43 | } 44 | 45 | func fireClickHandler(_ sender: UIButton) { 46 | print("Fire button was pressed!") 47 | self.view.backgroundColor = UIColor.red 48 | } 49 | 50 | } 51 | 52 | -------------------------------------------------------------------------------- /Chapter05/My First iOS app/My First iOS appUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Chapter05/My First iOS app/My First iOS appUITests/My_First_iOS_appUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // My_First_iOS_appUITests.swift 3 | // My First iOS appUITests 4 | // 5 | // Created by Emil Atanasov on 5/8/17. 6 | // Copyright © 2017 Appose Studio Inc. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class My_First_iOS_appUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | 18 | // In UI tests it is usually best to stop immediately when a failure occurs. 19 | continueAfterFailure = false 20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 21 | XCUIApplication().launch() 22 | 23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 24 | } 25 | 26 | override func tearDown() { 27 | // Put teardown code here. This method is called after the invocation of each test method in the class. 28 | super.tearDown() 29 | } 30 | 31 | func testExample() { 32 | // Use recording to get started writing UI tests. 33 | // Use XCTAssert and related functions to verify your tests produce the correct results. 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Chapter05/My First iOS app/swift_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter05/My First iOS app/swift_logo.png -------------------------------------------------------------------------------- /Chapter06/Chapter 6.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter06/Chapter 6.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Chapter06/Chapter 6.playground/playground.xcworkspace/xcuserdata/emil.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter06/Chapter 6.playground/playground.xcworkspace/xcuserdata/emil.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Chapter06/Chapter 6.playground/timeline.xctimeline: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Chapter06/CityPickerDemo/CityPickerDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Chapter06/CityPickerDemo/CityPickerDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter06/CityPickerDemo/CityPickerDemo.xcodeproj/project.xcworkspace/xcuserdata/emil.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter06/CityPickerDemo/CityPickerDemo.xcodeproj/project.xcworkspace/xcuserdata/emil.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Chapter06/CityPickerDemo/CityPickerDemo.xcodeproj/xcuserdata/emil.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /Chapter06/CityPickerDemo/CityPickerDemo.xcodeproj/xcuserdata/emil.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | CityPickerDemo.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 20489EE41F2E8E7A00294C3B 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Chapter06/CityPickerDemo/CityPickerDemo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /Chapter06/CityPickerDemo/CityPickerDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UIRequiresFullScreen 32 | 33 | UIStatusBarHidden 34 | 35 | UIStatusBarStyle 36 | UIStatusBarStyleDefault 37 | UISupportedInterfaceOrientations 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationLandscapeLeft 41 | UIInterfaceOrientationLandscapeRight 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /Chapter07/WeatherApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Chapter07/WeatherApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter07/WeatherApp.xcodeproj/project.xcworkspace/xcuserdata/emil.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter07/WeatherApp.xcodeproj/project.xcworkspace/xcuserdata/emil.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Chapter07/WeatherApp.xcodeproj/xcuserdata/emil.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | WeatherApp.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 202272221F5DD195000F04C8 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "size" : "1024x1024", 46 | "scale" : "1x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/cloudy.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "cloudy.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/cloudy.imageset/cloudy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter07/WeatherApp/Assets.xcassets/cloudy.imageset/cloudy.png -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/hail.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "hail.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/hail.imageset/hail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter07/WeatherApp/Assets.xcassets/hail.imageset/hail.png -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/heavy_rain.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "heavy_rain.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/heavy_rain.imageset/heavy_rain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter07/WeatherApp/Assets.xcassets/heavy_rain.imageset/heavy_rain.png -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/partly_cloudy.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "partly_cloudy.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/partly_cloudy.imageset/partly_cloudy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter07/WeatherApp/Assets.xcassets/partly_cloudy.imageset/partly_cloudy.png -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/rain.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "rain.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/rain.imageset/rain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter07/WeatherApp/Assets.xcassets/rain.imageset/rain.png -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/rainy_weather.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "rainy_weather.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/rainy_weather.imageset/rainy_weather.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter07/WeatherApp/Assets.xcassets/rainy_weather.imageset/rainy_weather.png -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/show_storm.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "show_storm.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/show_storm.imageset/show_storm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter07/WeatherApp/Assets.xcassets/show_storm.imageset/show_storm.png -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/snow.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "snow.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/snow.imageset/snow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter07/WeatherApp/Assets.xcassets/snow.imageset/snow.png -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/snowflake.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "snowflake.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/snowflake.imageset/snowflake.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter07/WeatherApp/Assets.xcassets/snowflake.imageset/snowflake.png -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/storm.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "storm.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/storm.imageset/storm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter07/WeatherApp/Assets.xcassets/storm.imageset/storm.png -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/sunny.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "sunny.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/sunny.imageset/sunny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter07/WeatherApp/Assets.xcassets/sunny.imageset/sunny.png -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/sunrise.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "sunrise.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/sunrise.imageset/sunrise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter07/WeatherApp/Assets.xcassets/sunrise.imageset/sunrise.png -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/sunset.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "sunset.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/sunset.imageset/sunset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter07/WeatherApp/Assets.xcassets/sunset.imageset/sunset.png -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/windy.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "windy.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Assets.xcassets/windy.imageset/windy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter07/WeatherApp/Assets.xcassets/windy.imageset/windy.png -------------------------------------------------------------------------------- /Chapter07/WeatherApp/DailyForecastViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DailyForecastViewCell.swift 3 | // WeatherApp 4 | // 5 | // Created by Emil Atanasov on 9/17/17. 6 | // Copyright © 2017 Appose Studio Inc. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import UIKit 12 | 13 | class DailyForecastViewCell: UITableViewCell { 14 | 15 | @IBOutlet weak var day: UILabel! 16 | 17 | @IBOutlet weak var icon: UIImageView! 18 | 19 | @IBOutlet weak var temperature: UILabel! 20 | } 21 | -------------------------------------------------------------------------------- /Chapter07/WeatherApp/FavoriteViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FavoriteViewCell.swift 3 | // WeatherApp 4 | // 5 | // Created by Emil Atanasov on 9/25/17. 6 | // Copyright © 2017 Appose Studio Inc. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | class FavoriteViewCell: UITableViewCell { 13 | 14 | @IBOutlet weak var time: UILabel! 15 | 16 | @IBOutlet weak var city: UILabel! 17 | 18 | @IBOutlet weak var temperature: UILabel! 19 | } 20 | 21 | class StaticViewCell: UITableViewCell { 22 | 23 | @IBOutlet weak var title: UILabel! 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /Chapter07/WeatherApp/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Chapter07/WeatherApp/PlacesViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PlacesViewCell.swift 3 | // WeatherApp 4 | // 5 | // Created by Emil Atanasov on 10/9/17. 6 | // Copyright © 2017 Appose Studio Inc. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | class PlacesViewCell: UITableViewCell { 13 | 14 | @IBOutlet weak var city: UILabel! 15 | } 16 | -------------------------------------------------------------------------------- /Chapter07/WeatherApp/WeatherViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WeatherViewCell.swift 3 | // WeatherApp 4 | // 5 | // Created by Emil Atanasov on 9/17/17. 6 | // Copyright © 2017 Appose Studio Inc. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | class WeatherViewCell: UICollectionViewCell { 13 | @IBOutlet weak var time: UILabel! 14 | 15 | @IBOutlet weak var icon: UIImageView! 16 | 17 | @IBOutlet weak var temperature: UILabel! 18 | } 19 | -------------------------------------------------------------------------------- /Chapter07/WeatherApp/ZoomInSegue.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ZoomInSegue.swift 3 | // WeatherApp 4 | // 5 | // Created by Emil Atanasov on 10/30/17. 6 | // Copyright © 2017 Appose Studio Inc. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | class ZoomInSegue : UIStoryboardSegue { 13 | 14 | override func perform() { 15 | zoomIn() 16 | } 17 | 18 | func zoomIn() { 19 | let superView = self.source.view.superview 20 | let center = self.source.view.center 21 | 22 | self.destination.view.transform = CGAffineTransform.init(scaleX: 0.05, y: 0.05).rotated(by: 90 * .pi / 180) 23 | self.destination.view.center = center 24 | 25 | superView?.addSubview(self.destination.view) 26 | 27 | UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseIn, animations: { 28 | self.destination.view.transform = CGAffineTransform.identity 29 | }, completion: { success in 30 | self.source.present(self.destination, animated: false, completion: nil) 31 | }) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | platform :ios, '9.0' 3 | 4 | target 'WeatherApp' do 5 | # Comment the next line if you're not using Swift and don't want to use dynamic frameworks 6 | use_frameworks! 7 | 8 | # Pods for WeatherApp 9 | pod 'Alamofire', '~> 4.4' 10 | 11 | end 12 | -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp.xcodeproj/project.xcworkspace/xcuserdata/emil.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter08/WeatherApp cocoapods/WeatherApp.xcodeproj/project.xcworkspace/xcuserdata/emil.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp.xcodeproj/xcuserdata/emil.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | WeatherApp.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 202272221F5DD195000F04C8 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "size" : "1024x1024", 46 | "scale" : "1x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/cloudy.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "cloudy.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/cloudy.imageset/cloudy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/cloudy.imageset/cloudy.png -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/hail.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "hail.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/hail.imageset/hail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/hail.imageset/hail.png -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/heavy_rain.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "heavy_rain.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/heavy_rain.imageset/heavy_rain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/heavy_rain.imageset/heavy_rain.png -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/partly_cloudy.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "partly_cloudy.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/partly_cloudy.imageset/partly_cloudy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/partly_cloudy.imageset/partly_cloudy.png -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/rain.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "rain.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/rain.imageset/rain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/rain.imageset/rain.png -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/rainy_weather.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "rainy_weather.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/rainy_weather.imageset/rainy_weather.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/rainy_weather.imageset/rainy_weather.png -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/show_storm.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "show_storm.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/show_storm.imageset/show_storm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/show_storm.imageset/show_storm.png -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/snow.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "snow.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/snow.imageset/snow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/snow.imageset/snow.png -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/snowflake.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "snowflake.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/snowflake.imageset/snowflake.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/snowflake.imageset/snowflake.png -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/storm.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "storm.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/storm.imageset/storm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/storm.imageset/storm.png -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/sunny.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "sunny.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/sunny.imageset/sunny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/sunny.imageset/sunny.png -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/sunrise.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "sunrise.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/sunrise.imageset/sunrise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/sunrise.imageset/sunrise.png -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/sunset.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "sunset.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/sunset.imageset/sunset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/sunset.imageset/sunset.png -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/windy.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "windy.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/windy.imageset/windy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter08/WeatherApp cocoapods/WeatherApp/Assets.xcassets/windy.imageset/windy.png -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/DailyForecastViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DailyForecastViewCell.swift 3 | // WeatherApp 4 | // 5 | // Created by Emil Atanasov on 9/17/17. 6 | // Copyright © 2017 Appose Studio Inc. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import UIKit 12 | 13 | class DailyForecastViewCell: UITableViewCell { 14 | 15 | @IBOutlet weak var day: UILabel! 16 | 17 | @IBOutlet weak var icon: UIImageView! 18 | 19 | @IBOutlet weak var temperature: UILabel! 20 | } 21 | -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/FavoriteViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FavoriteViewCell.swift 3 | // WeatherApp 4 | // 5 | // Created by Emil Atanasov on 9/25/17. 6 | // Copyright © 2017 Appose Studio Inc. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | class FavoriteViewCell: UITableViewCell { 13 | 14 | @IBOutlet weak var time: UILabel! 15 | 16 | @IBOutlet weak var city: UILabel! 17 | 18 | @IBOutlet weak var temperature: UILabel! 19 | } 20 | 21 | class StaticViewCell: UITableViewCell { 22 | 23 | @IBOutlet weak var title: UILabel! 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/PlacesViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PlacesViewCell.swift 3 | // WeatherApp 4 | // 5 | // Created by Emil Atanasov on 10/9/17. 6 | // Copyright © 2017 Appose Studio Inc. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | class PlacesViewCell: UITableViewCell { 13 | 14 | @IBOutlet weak var city: UILabel! 15 | } 16 | -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/WeatherViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WeatherViewCell.swift 3 | // WeatherApp 4 | // 5 | // Created by Emil Atanasov on 9/17/17. 6 | // Copyright © 2017 Appose Studio Inc. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | class WeatherViewCell: UICollectionViewCell { 13 | @IBOutlet weak var time: UILabel! 14 | 15 | @IBOutlet weak var icon: UIImageView! 16 | 17 | @IBOutlet weak var temperature: UILabel! 18 | } 19 | -------------------------------------------------------------------------------- /Chapter08/WeatherApp cocoapods/WeatherApp/ZoomInSegue.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ZoomInSegue.swift 3 | // WeatherApp 4 | // 5 | // Created by Emil Atanasov on 10/30/17. 6 | // Copyright © 2017 Appose Studio Inc. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | class ZoomInSegue : UIStoryboardSegue { 13 | 14 | override func perform() { 15 | zoomIn() 16 | } 17 | 18 | func zoomIn() { 19 | let superView = self.source.view.superview 20 | let center = self.source.view.center 21 | 22 | self.destination.view.transform = CGAffineTransform.init(scaleX: 0.05, y: 0.05).rotated(by: 90 * .pi / 180) 23 | self.destination.view.center = center 24 | 25 | superView?.addSubview(self.destination.view) 26 | 27 | UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseIn, animations: { 28 | self.destination.view.transform = CGAffineTransform.identity 29 | }, completion: { success in 30 | self.source.present(self.destination, animated: false, completion: nil) 31 | }) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Chapter08/swift-executable/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /Packages 4 | /*.xcodeproj 5 | -------------------------------------------------------------------------------- /Chapter08/swift-executable/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "object": { 3 | "pins": [ 4 | { 5 | "package": "swift-lib", 6 | "repositoryURL": "/Users/emil/Documents/Swift 4/Chapter 8/swift-lib", 7 | "state": { 8 | "branch": null, 9 | "revision": "4bdfe19b597e6d5e360d8b5b241b7d42489fa750", 10 | "version": "1.0.0" 11 | } 12 | } 13 | ] 14 | }, 15 | "version": 1 16 | } 17 | -------------------------------------------------------------------------------- /Chapter08/swift-executable/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:4.0 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "swift-executable", 8 | dependencies: [ 9 | // Dependencies declare other packages that this package depends on. 10 | .package(url:"../swift-lib/", from: "1.0.0"), 11 | ], 12 | targets: [ 13 | // Targets are the basic building blocks of a package. A target can define a module or a test suite. 14 | // Targets can depend on other targets in this package, and on products in packages which this package depends on. 15 | .target( 16 | name: "swift-executable", 17 | dependencies: ["swift-lib"]), 18 | ] 19 | ) 20 | -------------------------------------------------------------------------------- /Chapter08/swift-executable/README.md: -------------------------------------------------------------------------------- 1 | # swift-executable 2 | 3 | A description of this package. 4 | -------------------------------------------------------------------------------- /Chapter08/swift-executable/Sources/swift-executable/main.swift: -------------------------------------------------------------------------------- 1 | import swift_lib 2 | //print("Hello, world!") 3 | 4 | let toy = Toy(name: "Rex", age: 2, price: 99) 5 | print("Hello, \(toy.name)!") 6 | -------------------------------------------------------------------------------- /Chapter08/swift-lib/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /Packages 4 | /*.xcodeproj 5 | -------------------------------------------------------------------------------- /Chapter08/swift-lib/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:4.0 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "swift-lib", 8 | products: [ 9 | // Products define the executables and libraries produced by a package, and make them visible to other packages. 10 | .library( 11 | name: "swift-lib", 12 | targets: ["swift-lib"]), 13 | ], 14 | dependencies: [ 15 | // Dependencies declare other packages that this package depends on. 16 | // .package(url: /* package url */, from: "1.0.0"), 17 | ], 18 | targets: [ 19 | // Targets are the basic building blocks of a package. A target can define a module or a test suite. 20 | // Targets can depend on other targets in this package, and on products in packages which this package depends on. 21 | .target( 22 | name: "swift-lib", 23 | dependencies: []), 24 | .testTarget( 25 | name: "swift-libTests", 26 | dependencies: ["swift-lib"]), 27 | ] 28 | ) 29 | -------------------------------------------------------------------------------- /Chapter08/swift-lib/README.md: -------------------------------------------------------------------------------- 1 | # swift-lib 2 | 3 | A description of this package. 4 | -------------------------------------------------------------------------------- /Chapter08/swift-lib/Sources/swift-lib/swift_lib.swift: -------------------------------------------------------------------------------- 1 | struct swift_lib { 2 | var text = "Hello, World!" 3 | } 4 | 5 | public struct Toy { 6 | public var name = "Unknown" 7 | public var age = 1 8 | public var price = 1.0 9 | 10 | public init(name: String, age:Int, price:Double) { 11 | self.name = name 12 | self.age = age 13 | self.price = price 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Chapter08/swift-lib/Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import swift_libTests 3 | 4 | XCTMain([ 5 | testCase(swift_libTests.allTests), 6 | ]) 7 | -------------------------------------------------------------------------------- /Chapter08/swift-lib/Tests/swift-libTests/swift_libTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import swift_lib 3 | 4 | class swift_libTests: XCTestCase { 5 | func testExample() { 6 | // This is an example of a functional test case. 7 | // Use XCTAssert and related functions to verify your tests produce the correct 8 | // results. 9 | XCTAssertEqual(swift_lib().text, "Hello, World!") 10 | } 11 | 12 | func testToyDefaultValues() { 13 | let toy = Toy() 14 | XCTAssertEqual(toy.name, "Unknown") 15 | XCTAssertEqual(toy.age, 1) 16 | XCTAssertEqual(toy.price, 1.0) 17 | } 18 | 19 | func testToy() { 20 | let toy = Toy(name: "Rex", age: 2, price:99) 21 | XCTAssertEqual(toy.name, "Rex") 22 | XCTAssertEqual(toy.age, 2) 23 | XCTAssertEqual(toy.price, 99.0) 24 | } 25 | //update this for Linux 26 | static var allTests = [ 27 | ("testExample", testExample), 28 | ("testToyDefaultValues", testToyDefaultValues), 29 | ("testToy", testToy), 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /Chapter09/WeatherApp/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | target 'WeatherApp' do 5 | # Comment the next line if you're not using Swift and don't want to use dynamic frameworks 6 | use_frameworks! 7 | 8 | # Pods for WeatherApp 9 | pod 'Alamofire', '~> 4.5' 10 | pod 'Toast-Swift', '~> 3.0.1' 11 | 12 | end 13 | -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp.xcodeproj/project.xcworkspace/xcuserdata/emil.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter09/WeatherApp/WeatherApp.xcodeproj/project.xcworkspace/xcuserdata/emil.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp.xcodeproj/xcuserdata/emil.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | WeatherApp.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 202272221F5DD195000F04C8 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp.xcworkspace/xcuserdata/emil.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter09/WeatherApp/WeatherApp.xcworkspace/xcuserdata/emil.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp.xcworkspace/xcuserdata/emil.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "size" : "1024x1024", 46 | "scale" : "1x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/cloudy.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "cloudy.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/cloudy.imageset/cloudy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter09/WeatherApp/WeatherApp/Assets.xcassets/cloudy.imageset/cloudy.png -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/hail.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "hail.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/hail.imageset/hail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter09/WeatherApp/WeatherApp/Assets.xcassets/hail.imageset/hail.png -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/heavy_rain.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "heavy_rain.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/heavy_rain.imageset/heavy_rain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter09/WeatherApp/WeatherApp/Assets.xcassets/heavy_rain.imageset/heavy_rain.png -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/partly_cloudy.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "partly_cloudy.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/partly_cloudy.imageset/partly_cloudy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter09/WeatherApp/WeatherApp/Assets.xcassets/partly_cloudy.imageset/partly_cloudy.png -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/rain.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "rain.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/rain.imageset/rain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter09/WeatherApp/WeatherApp/Assets.xcassets/rain.imageset/rain.png -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/rainy_weather.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "rainy_weather.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/rainy_weather.imageset/rainy_weather.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter09/WeatherApp/WeatherApp/Assets.xcassets/rainy_weather.imageset/rainy_weather.png -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/show_storm.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "show_storm.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/show_storm.imageset/show_storm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter09/WeatherApp/WeatherApp/Assets.xcassets/show_storm.imageset/show_storm.png -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/snow.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "snow.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/snow.imageset/snow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter09/WeatherApp/WeatherApp/Assets.xcassets/snow.imageset/snow.png -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/snowflake.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "snowflake.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/snowflake.imageset/snowflake.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter09/WeatherApp/WeatherApp/Assets.xcassets/snowflake.imageset/snowflake.png -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/storm.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "storm.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/storm.imageset/storm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter09/WeatherApp/WeatherApp/Assets.xcassets/storm.imageset/storm.png -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/sunny.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "sunny.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/sunny.imageset/sunny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter09/WeatherApp/WeatherApp/Assets.xcassets/sunny.imageset/sunny.png -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/sunrise.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "sunrise.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/sunrise.imageset/sunrise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter09/WeatherApp/WeatherApp/Assets.xcassets/sunrise.imageset/sunrise.png -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/sunset.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "sunset.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/sunset.imageset/sunset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter09/WeatherApp/WeatherApp/Assets.xcassets/sunset.imageset/sunset.png -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/windy.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "windy.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Assets.xcassets/windy.imageset/windy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter09/WeatherApp/WeatherApp/Assets.xcassets/windy.imageset/windy.png -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/DailyForecastViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DailyForecastViewCell.swift 3 | // WeatherApp 4 | // 5 | // Created by Emil Atanasov on 9/17/17. 6 | // Copyright © 2017 Appose Studio Inc. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import UIKit 12 | 13 | class DailyForecastViewCell: UITableViewCell { 14 | 15 | @IBOutlet weak var day: UILabel! 16 | 17 | @IBOutlet weak var icon: UIImageView! 18 | 19 | @IBOutlet weak var temperature: UILabel! 20 | } 21 | -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/FavoriteViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FavoriteViewCell.swift 3 | // WeatherApp 4 | // 5 | // Created by Emil Atanasov on 9/25/17. 6 | // Copyright © 2017 Appose Studio Inc. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | class FavoriteViewCell: UITableViewCell { 13 | 14 | @IBOutlet weak var time: UILabel! 15 | 16 | @IBOutlet weak var city: UILabel! 17 | 18 | @IBOutlet weak var temperature: UILabel! 19 | } 20 | 21 | class StaticViewCell: UITableViewCell { 22 | 23 | @IBOutlet weak var title: UILabel! 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/PlacesViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PlacesViewCell.swift 3 | // WeatherApp 4 | // 5 | // Created by Emil Atanasov on 10/9/17. 6 | // Copyright © 2017 Appose Studio Inc. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | class PlacesViewCell: UITableViewCell { 13 | 14 | @IBOutlet weak var city: UILabel! 15 | } 16 | -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/WeatherViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WeatherViewCell.swift 3 | // WeatherApp 4 | // 5 | // Created by Emil Atanasov on 9/17/17. 6 | // Copyright © 2017 Appose Studio Inc. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | class WeatherViewCell: UICollectionViewCell { 13 | @IBOutlet weak var time: UILabel! 14 | 15 | @IBOutlet weak var icon: UIImageView! 16 | 17 | @IBOutlet weak var temperature: UILabel! 18 | } 19 | -------------------------------------------------------------------------------- /Chapter09/WeatherApp/WeatherApp/ZoomInSegue.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ZoomInSegue.swift 3 | // WeatherApp 4 | // 5 | // Created by Emil Atanasov on 10/30/17. 6 | // Copyright © 2017 Appose Studio Inc. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | class ZoomInSegue : UIStoryboardSegue { 13 | 14 | override func perform() { 15 | zoomIn() 16 | } 17 | 18 | func zoomIn() { 19 | let superView = self.source.view.superview 20 | let center = self.source.view.center 21 | 22 | self.destination.view.transform = CGAffineTransform.init(scaleX: 0.05, y: 0.05).rotated(by: 90 * .pi / 180) 23 | self.destination.view.center = center 24 | 25 | superView?.addSubview(self.destination.view) 26 | 27 | UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseIn, animations: { 28 | self.destination.view.transform = CGAffineTransform.identity 29 | }, completion: { success in 30 | self.source.present(self.destination, animated: false, completion: nil) 31 | }) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Chapter10/InstagramLikeApp/InstagramLikeApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Chapter10/InstagramLikeApp/InstagramLikeApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter10/InstagramLikeApp/InstagramLikeApp.xcodeproj/project.xcworkspace/xcuserdata/emil.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/InstagramLikeApp/InstagramLikeApp.xcodeproj/project.xcworkspace/xcuserdata/emil.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Chapter10/InstagramLikeApp/InstagramLikeApp.xcodeproj/xcuserdata/emil.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | InstagramLikeApp.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Chapter10/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Chapter10/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/favorites.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "favorites@x2.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter10/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/favorites.imageset/favorites@x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/favorites.imageset/favorites@x2.png -------------------------------------------------------------------------------- /Chapter10/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/first.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "first.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Chapter10/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/first.imageset/first.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/first.imageset/first.pdf -------------------------------------------------------------------------------- /Chapter10/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/home.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "home@x2.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter10/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/home.imageset/home@x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/home.imageset/home@x2.png -------------------------------------------------------------------------------- /Chapter10/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/photo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "photo@x2.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter10/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/photo.imageset/photo@x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/photo.imageset/photo@x2.png -------------------------------------------------------------------------------- /Chapter10/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/photo_verybig.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "photo_verybig.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "photo_verybig@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Chapter10/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/photo_verybig.imageset/photo_verybig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/photo_verybig.imageset/photo_verybig.png -------------------------------------------------------------------------------- /Chapter10/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/photo_verybig.imageset/photo_verybig@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/photo_verybig.imageset/photo_verybig@2x.png -------------------------------------------------------------------------------- /Chapter10/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/search.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "search@x2.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter10/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/search.imageset/search@x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/search.imageset/search@x2.png -------------------------------------------------------------------------------- /Chapter10/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/second.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "second.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Chapter10/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/second.imageset/second.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/second.imageset/second.pdf -------------------------------------------------------------------------------- /Chapter10/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/user.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "user@x2.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter10/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/user.imageset/user@x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/user.imageset/user@x2.png -------------------------------------------------------------------------------- /Chapter10/InstagramLikeApp/InstagramLikeApp/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 | -------------------------------------------------------------------------------- /Chapter10/InstagramLikeApp/InstagramLikeApp/FirstViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FirstViewController.swift 3 | // InstagramLikeApp 4 | // 5 | // Created by Emil Atanasov on 10.02.18. 6 | // Copyright © 2018 ApposeStudio Inc. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import FirebaseAuthUI 11 | 12 | class FirstViewController: UIViewController { 13 | 14 | @IBAction func onLogout(_ sender: Any) { 15 | let authUI = FUIAuth.defaultAuthUI() 16 | do { 17 | try authUI?.signOut() 18 | let nc = NotificationCenter.default 19 | nc.post(name: Notification.Name(rawValue: "userSignedOut"), 20 | object: nil, 21 | userInfo: nil) 22 | //remove the active user 23 | DataManager.shared.user = nil 24 | DataManager.shared.userUID = nil 25 | } catch let error { 26 | print("Error: \(error)") 27 | } 28 | } 29 | override func viewDidLoad() { 30 | super.viewDidLoad() 31 | // Do any additional setup after loading the view, typically from a nib. 32 | } 33 | 34 | override func didReceiveMemoryWarning() { 35 | super.didReceiveMemoryWarning() 36 | // Dispose of any resources that can be recreated. 37 | } 38 | 39 | 40 | } 41 | 42 | -------------------------------------------------------------------------------- /Chapter10/InstagramLikeApp/InstagramLikeApp/GoogleService-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AD_UNIT_ID_FOR_BANNER_TEST 6 | ca-app-pub-3940256099942544/2934735716 7 | AD_UNIT_ID_FOR_INTERSTITIAL_TEST 8 | ca-app-pub-3940256099942544/4411468910 9 | CLIENT_ID 10 | 5093388547-d41i5lehe7kn1tbuk52q30ojtt15ga2l.apps.googleusercontent.com 11 | REVERSED_CLIENT_ID 12 | com.googleusercontent.apps.5093388547-d41i5lehe7kn1tbuk52q30ojtt15ga2l 13 | API_KEY 14 | Please insert Google API Key 15 | GCM_SENDER_ID 16 | 5093388547 17 | PLIST_VERSION 18 | 1 19 | BUNDLE_ID 20 | com.packtpublishing.swift4.InstagramLikeApp 21 | PROJECT_ID 22 | instagramlike-app 23 | STORAGE_BUCKET 24 | instagramlike-app.appspot.com 25 | IS_ADS_ENABLED 26 | 27 | IS_ANALYTICS_ENABLED 28 | 29 | IS_APPINVITE_ENABLED 30 | 31 | IS_GCM_ENABLED 32 | 33 | IS_SIGNIN_ENABLED 34 | 35 | GOOGLE_APP_ID 36 | 1:5093388547:ios:e5b83cdcd340db0a 37 | DATABASE_URL 38 | https://instagramlike-app.firebaseio.com 39 | 40 | 41 | -------------------------------------------------------------------------------- /Chapter10/InstagramLikeApp/InstagramLikeApp/SecondViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SecondViewController.swift 3 | // InstagramLikeApp 4 | // 5 | // Created by Emil Atanasov on 10.02.18. 6 | // Copyright © 2018 ApposeStudio Inc. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SecondViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | // Do any additional setup after loading the view, typically from a nib. 16 | } 17 | 18 | override func didReceiveMemoryWarning() { 19 | super.didReceiveMemoryWarning() 20 | // Dispose of any resources that can be recreated. 21 | } 22 | 23 | 24 | } 25 | 26 | -------------------------------------------------------------------------------- /Chapter10/InstagramLikeApp/InstagramLikeApp/SignInViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SigInViewController.swift 3 | // InstagramLikeApp 4 | // 5 | // Created by Emil Atanasov on 11.02.18. 6 | // Copyright © 2018 ApposeStudio Inc. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import FirebaseAuthUI 11 | 12 | class SignInViewController: UIViewController { 13 | 14 | override func viewDidLoad() { 15 | super.viewDidLoad() 16 | 17 | // Do any additional setup after loading the view. 18 | } 19 | 20 | override func didReceiveMemoryWarning() { 21 | super.didReceiveMemoryWarning() 22 | // Dispose of any resources that can be recreated. 23 | } 24 | 25 | @IBAction func signInWithEmail(_ sender: Any) { 26 | let authUI = FUIAuth.defaultAuthUI() 27 | if let authViewController = authUI?.authViewController() { 28 | present(authViewController, animated: true, completion: nil) 29 | } 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /Chapter10/InstagramLikeApp/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | target 'InstagramLikeApp' do 5 | # Comment the next line if you're not using Swift and don't want to use dynamic frameworks 6 | use_frameworks! 7 | 8 | # Pods for InstagramLikeApp 9 | 10 | pod 'Firebase/Core' 11 | pod 'FirebaseUI/Auth', '~> 4.0' 12 | # database & storage 13 | pod 'Firebase/Database' 14 | pod 'Firebase/Storage' 15 | # Instragram-like photo browser 16 | pod 'YPImagePicker' 17 | #customisable tabbar 18 | pod 'ESTabBarController-swift' 19 | 20 | #nice horizontal list 21 | #pod 'ASHorizontalScrollView', '~> 1.5.1' 22 | # add progress 23 | # https://github.com/mrackwitz/MRProgress 24 | 25 | end 26 | -------------------------------------------------------------------------------- /Chapter10/icon-set/comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/icon-set/comment.png -------------------------------------------------------------------------------- /Chapter10/icon-set/comment@x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/icon-set/comment@x2.png -------------------------------------------------------------------------------- /Chapter10/icon-set/create_post.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/icon-set/create_post.png -------------------------------------------------------------------------------- /Chapter10/icon-set/create_post@2x.org.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/icon-set/create_post@2x.org.png -------------------------------------------------------------------------------- /Chapter10/icon-set/create_post@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/icon-set/create_post@2x.png -------------------------------------------------------------------------------- /Chapter10/icon-set/favorite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/icon-set/favorite.png -------------------------------------------------------------------------------- /Chapter10/icon-set/favorites.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/icon-set/favorites.png -------------------------------------------------------------------------------- /Chapter10/icon-set/favorites@x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/icon-set/favorites@x2.png -------------------------------------------------------------------------------- /Chapter10/icon-set/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/icon-set/home.png -------------------------------------------------------------------------------- /Chapter10/icon-set/home@x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/icon-set/home@x2.png -------------------------------------------------------------------------------- /Chapter10/icon-set/org/comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/icon-set/org/comment.png -------------------------------------------------------------------------------- /Chapter10/icon-set/org/favorites.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/icon-set/org/favorites.png -------------------------------------------------------------------------------- /Chapter10/icon-set/org/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/icon-set/org/home.png -------------------------------------------------------------------------------- /Chapter10/icon-set/org/photo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/icon-set/org/photo.png -------------------------------------------------------------------------------- /Chapter10/icon-set/org/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/icon-set/org/search.png -------------------------------------------------------------------------------- /Chapter10/icon-set/org/send.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/icon-set/org/send.png -------------------------------------------------------------------------------- /Chapter10/icon-set/org/user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/icon-set/org/user.png -------------------------------------------------------------------------------- /Chapter10/icon-set/photo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/icon-set/photo.png -------------------------------------------------------------------------------- /Chapter10/icon-set/photo@x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/icon-set/photo@x2.png -------------------------------------------------------------------------------- /Chapter10/icon-set/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/icon-set/search.png -------------------------------------------------------------------------------- /Chapter10/icon-set/search@x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/icon-set/search@x2.png -------------------------------------------------------------------------------- /Chapter10/icon-set/send.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/icon-set/send.png -------------------------------------------------------------------------------- /Chapter10/icon-set/send@x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/icon-set/send@x2.png -------------------------------------------------------------------------------- /Chapter10/icon-set/user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/icon-set/user.png -------------------------------------------------------------------------------- /Chapter10/icon-set/user@x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter10/icon-set/user@x2.png -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp.xcodeproj/project.xcworkspace/xcuserdata/emil.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter11/InstagramLikeApp/InstagramLikeApp.xcodeproj/project.xcworkspace/xcuserdata/emil.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp.xcodeproj/xcuserdata/emil.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | InstagramLikeApp.xcscheme 8 | 9 | orderHint 10 | 10 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 20677C21202F84CC00079CA7 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/comment.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "comment@x2.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/comment.imageset/comment@x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/comment.imageset/comment@x2.png -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/create_post.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "create_post.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "create_post@2x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/create_post.imageset/create_post.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/create_post.imageset/create_post.png -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/create_post.imageset/create_post@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/create_post.imageset/create_post@2x.png -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/favorites.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "favorites@x2.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/favorites.imageset/favorites@x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/favorites.imageset/favorites@x2.png -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/home.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "home@x2.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/home.imageset/home@x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/home.imageset/home@x2.png -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/loading.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "loading.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/loading.imageset/loading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/loading.imageset/loading.png -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/photo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "photo@x2.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/photo.imageset/photo@x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/photo.imageset/photo@x2.png -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/photo_verybig.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "photo_verybig.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "photo_verybig@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/photo_verybig.imageset/photo_verybig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/photo_verybig.imageset/photo_verybig.png -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/photo_verybig.imageset/photo_verybig@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/photo_verybig.imageset/photo_verybig@2x.png -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/search.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "search@x2.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/search.imageset/search@x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/search.imageset/search@x2.png -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/send.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "send@x2.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/send.imageset/send@x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/send.imageset/send@x2.png -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/user.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "user@x2.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/user.imageset/user@x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter11/InstagramLikeApp/InstagramLikeApp/Assets.xcassets/user.imageset/user@x2.png -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp/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 | -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp/FavoritesViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FavoritesViewController.swift 3 | // InstagramLikeApp 4 | // 5 | // Created by Emil Atanasov on 22.04.18. 6 | // Copyright © 2018 ApposeStudio Inc. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class FavoritesViewController: UIViewController { 12 | 13 | @IBOutlet weak var collectionView: UICollectionView! 14 | @IBOutlet weak var noItems: UIView! 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | showEmptyView() 18 | loadData() 19 | } 20 | 21 | func loadData() { 22 | //TODO: load all favorite posts 23 | } 24 | } 25 | 26 | 27 | protocol EmptyCollectionView { 28 | func showCollectionView() 29 | func showEmptyView() 30 | var collectionView: UICollectionView! { get } 31 | var emptyView: UIView? { get } 32 | } 33 | 34 | extension EmptyCollectionView { 35 | func showCollectionView() { 36 | self.emptyView?.isHidden = true 37 | self.collectionView.isHidden = false 38 | } 39 | 40 | func showEmptyView() { 41 | if self.emptyView != nil { 42 | self.emptyView?.isHidden = false 43 | self.collectionView.isHidden = true 44 | } 45 | } 46 | } 47 | 48 | 49 | extension FavoritesViewController: EmptyCollectionView { 50 | var emptyView: UIView? { 51 | return noItems 52 | } 53 | } 54 | 55 | -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp/FirstViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FirstViewController.swift 3 | // InstagramLikeApp 4 | // 5 | // Created by Emil Atanasov on 10.02.18. 6 | // Copyright © 2018 ApposeStudio Inc. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class FirstViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | // Do any additional setup after loading the view, typically from a nib. 16 | } 17 | 18 | override func didReceiveMemoryWarning() { 19 | super.didReceiveMemoryWarning() 20 | // Dispose of any resources that can be recreated. 21 | } 22 | 23 | 24 | } 25 | 26 | -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp/GoogleService-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AD_UNIT_ID_FOR_BANNER_TEST 6 | ca-app-pub-3940256099942544/2934735716 7 | AD_UNIT_ID_FOR_INTERSTITIAL_TEST 8 | ca-app-pub-3940256099942544/4411468910 9 | CLIENT_ID 10 | 5093388547-d41i5lehe7kn1tbuk52q30ojtt15ga2l.apps.googleusercontent.com 11 | REVERSED_CLIENT_ID 12 | com.googleusercontent.apps.5093388547-d41i5lehe7kn1tbuk52q30ojtt15ga2l 13 | API_KEY 14 | AIzaSyA78EIw_9ZyFg2G4jByXFnrINVHfpn-784 15 | GCM_SENDER_ID 16 | 5093388547 17 | PLIST_VERSION 18 | 1 19 | BUNDLE_ID 20 | com.packtpublishing.swift4.InstagramLikeApp 21 | PROJECT_ID 22 | instagramlike-app 23 | STORAGE_BUCKET 24 | instagramlike-app.appspot.com 25 | IS_ADS_ENABLED 26 | 27 | IS_ANALYTICS_ENABLED 28 | 29 | IS_APPINVITE_ENABLED 30 | 31 | IS_GCM_ENABLED 32 | 33 | IS_SIGNIN_ENABLED 34 | 35 | GOOGLE_APP_ID 36 | 1:5093388547:ios:e5b83cdcd340db0a 37 | DATABASE_URL 38 | https://instagramlike-app.firebaseio.com 39 | 40 | -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp/PhotoViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoViewCell.swift 3 | // InstagramLikeApp 4 | // 5 | // Created by Emil Atanasov on 19.04.18. 6 | // Copyright © 2018 ApposeStudio Inc. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class PhotoViewCell: UICollectionViewCell { 12 | @IBOutlet weak var image: UIImageView! 13 | } 14 | -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/InstagramLikeApp/SignInViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SigInViewController.swift 3 | // InstagramLikeApp 4 | // 5 | // Created by Emil Atanasov on 11.02.18. 6 | // Copyright © 2018 ApposeStudio Inc. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import FirebaseAuthUI 11 | 12 | class SignInViewController: UIViewController { 13 | 14 | override func viewDidLoad() { 15 | super.viewDidLoad() 16 | 17 | // Do any additional setup after loading the view. 18 | } 19 | 20 | override func didReceiveMemoryWarning() { 21 | super.didReceiveMemoryWarning() 22 | // Dispose of any resources that can be recreated. 23 | } 24 | 25 | @IBAction func signInWithEmail(_ sender: Any) { 26 | let authUI = FUIAuth.defaultAuthUI() 27 | if let authViewController = authUI?.authViewController() { 28 | present(authViewController, animated: true, completion: nil) 29 | } 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /Chapter11/InstagramLikeApp/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | target 'InstagramLikeApp' do 5 | # Comment the next line if you're not using Swift and don't want to use dynamic frameworks 6 | use_frameworks! 7 | 8 | # Pods for InstagramLikeApp 9 | 10 | pod 'Firebase/Core' 11 | pod 'FirebaseUI/Auth', '~> 4.0' 12 | # database & storage 13 | pod 'Firebase/Database' 14 | pod 'Firebase/Storage' 15 | # storage UI 16 | pod 'FirebaseUI/Storage' 17 | # Instragram-like photo browser 18 | pod 'YPImagePicker' 19 | #customisable tabbar 20 | pod 'ESTabBarController-swift' 21 | 22 | #nice horizontal list 23 | #pod 'ASHorizontalScrollView', '~> 1.5.1' 24 | # add progress 25 | # https://github.com/mrackwitz/MRProgress 26 | 27 | end 28 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | # build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | 22 | # Bundler 23 | .bundle 24 | 25 | # Carthage 26 | # We recommend against adding the Pods directory to your .gitignore. However 27 | # you should judge for yourself, the pros and cons are mentioned at: 28 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 29 | 30 | # Note: if you ignore the Pods directory, make sure to uncomment 31 | # `pod install` in .travis.yml 32 | 33 | Pods/ 34 | 35 | 36 | *.lock 37 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/.swift-version: -------------------------------------------------------------------------------- 1 | 4.0 2 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/.swiftlint.yml: -------------------------------------------------------------------------------- 1 | disabled_rules: 2 | - trailing_whitespace 3 | - variable_name 4 | - type_body_length 5 | - function_body_length 6 | - file_length 7 | - cyclomatic_complexity 8 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Cartfile: -------------------------------------------------------------------------------- 1 | github "freshOS/Stevia" "4.2.0" 2 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Cartfile.resolved: -------------------------------------------------------------------------------- 1 | github "freshOS/Stevia" "4.2.0" 2 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Images/filters.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter12/YPImagePicker_source_with_contribution/Images/filters.PNG -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Images/library.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter12/YPImagePicker_source_with_contribution/Images/library.PNG -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Images/photo.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter12/YPImagePicker_source_with_contribution/Images/photo.PNG -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Images/video.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter12/YPImagePicker_source_with_contribution/Images/video.PNG -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Images/visual.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter12/YPImagePicker_source_with_contribution/Images/visual.jpg -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 ytakzk 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Resources/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Resources/Assets.xcassets/yp_arrow.imageset/Arrow.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter12/YPImagePicker_source_with_contribution/Resources/Assets.xcassets/yp_arrow.imageset/Arrow.pdf -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Resources/Assets.xcassets/yp_arrow.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Arrow.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Resources/Assets.xcassets/yp_iconCapture.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "iconCapture2.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Resources/Assets.xcassets/yp_iconCapture.imageset/iconCapture2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter12/YPImagePicker_source_with_contribution/Resources/Assets.xcassets/yp_iconCapture.imageset/iconCapture2.pdf -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Resources/Assets.xcassets/yp_iconCrop.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "yp_iconCrop.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Resources/Assets.xcassets/yp_iconCrop.imageset/yp_iconCrop.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter12/YPImagePicker_source_with_contribution/Resources/Assets.xcassets/yp_iconCrop.imageset/yp_iconCrop.pdf -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Resources/Assets.xcassets/yp_iconFlash_auto.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "yp_iconFlash_auto.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Resources/Assets.xcassets/yp_iconFlash_auto.imageset/yp_iconFlash_auto.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter12/YPImagePicker_source_with_contribution/Resources/Assets.xcassets/yp_iconFlash_auto.imageset/yp_iconFlash_auto.pdf -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Resources/Assets.xcassets/yp_iconFlash_off.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "yp_icon_flash_off.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Resources/Assets.xcassets/yp_iconFlash_off.imageset/yp_icon_flash_off.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter12/YPImagePicker_source_with_contribution/Resources/Assets.xcassets/yp_iconFlash_off.imageset/yp_icon_flash_off.pdf -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Resources/Assets.xcassets/yp_iconFlash_on.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "yp_iconFlash.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Resources/Assets.xcassets/yp_iconFlash_on.imageset/yp_iconFlash.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter12/YPImagePicker_source_with_contribution/Resources/Assets.xcassets/yp_iconFlash_on.imageset/yp_iconFlash.pdf -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Resources/Assets.xcassets/yp_iconLoop.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "yp_iconLoop.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Resources/Assets.xcassets/yp_iconLoop.imageset/yp_iconLoop.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter12/YPImagePicker_source_with_contribution/Resources/Assets.xcassets/yp_iconLoop.imageset/yp_iconLoop.pdf -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Resources/Assets.xcassets/yp_iconVideoCapture.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "iconCapture Copy.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Resources/Assets.xcassets/yp_iconVideoCapture.imageset/iconCapture Copy.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter12/YPImagePicker_source_with_contribution/Resources/Assets.xcassets/yp_iconVideoCapture.imageset/iconCapture Copy.pdf -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Resources/Assets.xcassets/yp_iconVideoCaptureRecording.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "iconCapture Copy 2.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Resources/Assets.xcassets/yp_iconVideoCaptureRecording.imageset/iconCapture Copy 2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Learn-Swift-by-Building-Applications/dad5bebd845975205c6c4fcef60b31ef8d14d048/Chapter12/YPImagePicker_source_with_contribution/Resources/Assets.xcassets/yp_iconVideoCaptureRecording.imageset/iconCapture Copy 2.pdf -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Resources/ar.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localizable.strings 3 | YPImagePicker 4 | 5 | Created by Sacha Durand Saint Omer on 02/11/16. 6 | Copyright © 2016 Yummypets. All rights reserved. 7 | */ 8 | 9 | "YPImagePickerLibrary" = "المكتبة"; 10 | "YPImagePickerPhoto" = "صورة"; 11 | "YPImagePickerVideo" = "فيديو"; 12 | "YPImagePickerNext" = "التالي"; 13 | "YPImagePickerFilter" = "فلتر"; 14 | "YPImagePickerVideoTooLongTitle" = "مدة الفيديو"; 15 | "YPImagePickerVideoTooLongDetail" = "ثانية %@ اختار فيديو بمدة اقل من "; 16 | "YPImagePickerPermissionDeniedPopupTitle" = "الطلب مرفوض"; 17 | "YPImagePickerPermissionDeniedPopupMessage" = "يرجى السماح بالوصول"; 18 | "YPImagePickerPermissionDeniedPopupCancel" = "إلغاء"; 19 | "YPImagePickerPermissionDeniedPopupGrantPermission" = "السماح بالوصول"; 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Resources/en.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localizable.strings 3 | YPImagePicker 4 | 5 | Created by Sacha Durand Saint Omer on 02/11/16. 6 | Copyright © 2016 Yummypets. All rights reserved. 7 | */ 8 | 9 | "YPImagePickerLibrary" = "Library"; 10 | "YPImagePickerPhoto" = "Photo"; 11 | "YPImagePickerVideo" = "Video"; 12 | "YPImagePickerNext" = "Next"; 13 | "YPImagePickerFilter" = "Filter"; 14 | "YPImagePickerVideoTooLongTitle" = "Video duration"; 15 | "YPImagePickerVideoTooLongDetail" = "Pick a video less than %@ seconds long."; 16 | "YPImagePickerPermissionDeniedPopupTitle" = "Permission denied"; 17 | "YPImagePickerPermissionDeniedPopupMessage" = "Please allow access"; 18 | "YPImagePickerPermissionDeniedPopupCancel" = "Cancel"; 19 | "YPImagePickerPermissionDeniedPopupGrantPermission" = "Grant Permission"; 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Resources/es.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localizable.strings 3 | YPImagePicker 4 | 5 | Created by Sacha Durand Saint Omer on 02/11/16. 6 | Copyright © 2016 Yummypets. All rights reserved. 7 | */ 8 | 9 | "YPImagePickerLibrary" = "Biblioteca"; 10 | "YPImagePickerPhoto" = "Foto"; 11 | "YPImagePickerVideo" = "Vídeo"; 12 | "YPImagePickerNext" = "Siguiente"; 13 | "YPImagePickerFilter" = "Filtro"; 14 | "YPImagePickerVideoTooLongTitle" = "Demasiado largo"; 15 | "YPImagePickerVideoTooLongDetail" = "Elige un vídeo que dure menos de %@ segundos."; 16 | "YPImagePickerPermissionDeniedPopupTitle" = "Permiso denegado"; 17 | "YPImagePickerPermissionDeniedPopupMessage" = "Por favor, permite el acceso"; 18 | "YPImagePickerPermissionDeniedPopupCancel" = "Cancelar"; 19 | "YPImagePickerPermissionDeniedPopupGrantPermission" = "Permitir"; 20 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Resources/fr.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localizable.strings 3 | YPImagePicker 4 | 5 | Created by Sacha Durand Saint Omer on 02/11/16. 6 | Copyright © 2016 Yummypets. All rights reserved. 7 | */ 8 | 9 | "YPImagePickerLibrary" = "Bibliothèque"; 10 | "YPImagePickerPhoto" = "Photo"; 11 | "YPImagePickerVideo" = "Vidéo"; 12 | "YPImagePickerNext" = "Suivant"; 13 | "YPImagePickerFilter" = "Filtrer"; 14 | "YPImagePickerVideoTooLongTitle" = "Durée de votre vidéo"; 15 | "YPImagePickerVideoTooLongDetail" = "La durée d'une vidéo ne doit pas dépasser %@ secondes."; 16 | "YPImagePickerPermissionDeniedPopupTitle" = "Permission refusée"; 17 | "YPImagePickerPermissionDeniedPopupMessage" = "Vous devez authorizer l'accès"; 18 | "YPImagePickerPermissionDeniedPopupCancel" = "Annuler"; 19 | "YPImagePickerPermissionDeniedPopupGrantPermission" = "Donner la permission"; 20 | 21 | 22 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Resources/nl.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localizable.strings 3 | YPImagePicker 4 | 5 | Created by Sacha Durand Saint Omer on 02/11/16. 6 | Copyright © 2016 Yummypets. All rights reserved. 7 | */ 8 | 9 | "YPImagePickerLibrary" = "Bibliotheek"; 10 | "YPImagePickerPhoto" = "Foto"; 11 | "YPImagePickerVideo" = "Video"; 12 | "YPImagePickerNext" = "Volgende"; 13 | "YPImagePickerFilter" = "Filter"; 14 | "YPImagePickerVideoTooLongTitle" = "Video lengte"; 15 | "YPImagePickerVideoTooLongDetail" = "Selecteer een video korter dan %@ seconden."; 16 | "YPImagePickerPermissionDeniedPopupTitle" = "Toestemming geweigerd"; 17 | "YPImagePickerPermissionDeniedPopupMessage" = "Verleen alstublieft toestemming"; 18 | "YPImagePickerPermissionDeniedPopupCancel" = "Annuleer"; 19 | "YPImagePickerPermissionDeniedPopupGrantPermission" = "Verleen toestemming"; 20 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Resources/pt-BR.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localizable.strings 3 | YPImagePicker 4 | 5 | Created by Sacha Durand Saint Omer on 02/11/16. 6 | Copyright © 2016 Yummypets. All rights reserved. 7 | */ 8 | 9 | "YPImagePickerLibrary" = "Biblioteca"; 10 | "YPImagePickerPhoto" = "Foto"; 11 | "YPImagePickerVideo" = "Vídeo"; 12 | "YPImagePickerNext" = "Avançar"; 13 | "YPImagePickerFilter" = "Filtro"; 14 | "YPImagePickerVideoTooLongTitle" = "Duração do vídeo"; 15 | "YPImagePickerVideoTooLongDetail" = "Escolha um vídeo menor que %@ segundos."; 16 | "YPImagePickerPermissionDeniedPopupTitle" = "Permissão negada"; 17 | "YPImagePickerPermissionDeniedPopupMessage" = "Por favor, permita o acesso"; 18 | "YPImagePickerPermissionDeniedPopupCancel" = "Cancelar"; 19 | "YPImagePickerPermissionDeniedPopupGrantPermission" = "Permitir"; 20 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Resources/ru.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localizable.strings 3 | YPImagePicker 4 | 5 | Created by Sacha Durand Saint Omer on 02/11/16. 6 | Copyright © 2016 Yummypets. All rights reserved. 7 | */ 8 | 9 | "YPImagePickerLibrary" = "Библиотека"; 10 | "YPImagePickerPhoto" = "Фото"; 11 | "YPImagePickerVideo" = "Видео"; 12 | "YPImagePickerNext" = "Дальше"; 13 | "YPImagePickerFilter" = "Фильтр"; 14 | "YPImagePickerVideoTooLongTitle" = "Видео слишком длинное"; 15 | "YPImagePickerVideoTooLongDetail" = "Выберите видео короче %@ секунд."; 16 | "YPImagePickerPermissionDeniedPopupTitle" = "Не хватает полномочий"; 17 | "YPImagePickerPermissionDeniedPopupMessage" = "Пожалуйста, разрешите доступ"; 18 | "YPImagePickerPermissionDeniedPopupCancel" = "Отмена"; 19 | "YPImagePickerPermissionDeniedPopupGrantPermission" = "Настроить разрешения"; 20 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Resources/tr.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localizable.strings 3 | YPImagePicker 4 | 5 | Created by Sacha Durand Saint Omer on 02/11/16. 6 | Copyright © 2016 Yummypets. All rights reserved. 7 | */ 8 | 9 | "YPImagePickerLibrary" = "Kütüphane"; 10 | "YPImagePickerPhoto" = "Fotoğraf"; 11 | "YPImagePickerVideo" = "Video"; 12 | "YPImagePickerNext" = "İleri"; 13 | "YPImagePickerFilter" = "Filtrele"; 14 | "YPImagePickerVideoTooLongTitle" = "Video uzunluğu"; 15 | "YPImagePickerVideoTooLongDetail" = "%@ saniyeden daha kısa bir video seç."; 16 | "YPImagePickerPermissionDeniedPopupTitle" = "Erişim izni reddedildi"; 17 | "YPImagePickerPermissionDeniedPopupMessage" = "Lütfen erişime izin ver"; 18 | "YPImagePickerPermissionDeniedPopupCancel" = "İptal"; 19 | "YPImagePickerPermissionDeniedPopupGrantPermission" = "Erişime İzin Ver"; 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Source/BottomPager/YPBottomPagerView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // YPBottomPagerView.swift 3 | // YPImagePicker 4 | // 5 | // Created by Sacha DSO on 24/01/2018. 6 | // Copyright © 2016 Yummypets. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Stevia 11 | 12 | final class YPBottomPagerView: UIView { 13 | 14 | var header = YPPagerMenu() 15 | var scrollView = UIScrollView() 16 | 17 | convenience init() { 18 | self.init(frame: .zero) 19 | backgroundColor = UIColor(red: 239/255, green: 238/255, blue: 237/255, alpha: 1) 20 | 21 | sv( 22 | scrollView, 23 | header 24 | ) 25 | 26 | layout( 27 | 0, 28 | |scrollView|, 29 | 0, 30 | |header| ~ 50 31 | ) 32 | 33 | if #available(iOS 11.0, *) { 34 | header.Bottom == safeAreaLayoutGuide.Bottom 35 | } else { 36 | header.bottom(0) 37 | } 38 | 39 | clipsToBounds = false 40 | scrollView.clipsToBounds = false 41 | scrollView.isPagingEnabled = true 42 | scrollView.showsHorizontalScrollIndicator = false 43 | scrollView.scrollsToTop = false 44 | scrollView.bounces = false 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Source/BottomPager/YPMenuItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // YPMenuItem.swift 3 | // YPImagePicker 4 | // 5 | // Created by Sacha DSO on 24/01/2018. 6 | // Copyright © 2016 Yummypets. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Stevia 11 | 12 | final class YPMenuItem: UIView { 13 | 14 | var text = UILabel() 15 | var button = UIButton() 16 | 17 | convenience init() { 18 | self.init(frame: .zero) 19 | backgroundColor = .clear 20 | 21 | sv( 22 | text, 23 | button 24 | ) 25 | 26 | text.centerInContainer() 27 | button.fillContainer() 28 | 29 | text.style { l in 30 | l.textAlignment = .center 31 | l.font = UIFont.systemFont(ofSize: 17, weight: UIFont.Weight.medium) 32 | l.textColor = self.unselectedColor() 33 | } 34 | } 35 | 36 | func selectedColor() -> UIColor { 37 | return UIColor(r: 38, g: 38, b: 38) 38 | } 39 | 40 | func unselectedColor() -> UIColor { 41 | return UIColor(r: 153, g: 153, b: 153) 42 | } 43 | 44 | func select() { 45 | text.textColor = selectedColor() 46 | } 47 | 48 | func unselect() { 49 | text.textColor = unselectedColor() 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Source/BottomPager/YPPagerMenu.swift: -------------------------------------------------------------------------------- 1 | // 2 | // YPPagerMenu.swift 3 | // YPImagePicker 4 | // 5 | // Created by Sacha DSO on 24/01/2018. 6 | // Copyright © 2016 Yummypets. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Stevia 11 | 12 | final class YPPagerMenu: UIView { 13 | 14 | var didSetConstraints = false 15 | var menuItems = [YPMenuItem]() 16 | 17 | convenience init() { 18 | self.init(frame: .zero) 19 | backgroundColor = UIColor(r: 247, g: 247, b: 247) 20 | } 21 | 22 | var separators = [UIView]() 23 | 24 | func setUpMenuItemsConstraints() { 25 | let menuItemWidth: CGFloat = UIScreen.main.bounds.width / CGFloat(menuItems.count) 26 | var previousMenuItem: YPMenuItem? 27 | for m in menuItems { 28 | 29 | sv( 30 | m 31 | ) 32 | 33 | m.fillVertically().width(menuItemWidth) 34 | if let pm = previousMenuItem { 35 | pm-0-m 36 | } else { 37 | |m 38 | } 39 | 40 | previousMenuItem = m 41 | } 42 | } 43 | 44 | override func updateConstraints() { 45 | super.updateConstraints() 46 | if !didSetConstraints { 47 | setUpMenuItemsConstraints() 48 | } 49 | didSetConstraints = true 50 | } 51 | 52 | func refreshMenuItems() { 53 | didSetConstraints = false 54 | updateConstraints() 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Source/Camera/YPPhotoCapture.swift: -------------------------------------------------------------------------------- 1 | // 2 | // YPPhotoCapture.swift 3 | // YPImagePicker 4 | // 5 | // Created by Sacha DSO on 08/03/2018. 6 | // Copyright © 2018 Yummypets. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import AVFoundation 11 | import UIKit 12 | 13 | protocol YPPhotoCapture: class { 14 | 15 | // Public api 16 | func setup(with previewView: UIView) 17 | func tryToStartCamera() 18 | func stopCamera() 19 | func focus(on point: CGPoint) 20 | func tryToggleFlash() 21 | var hasFlash: Bool { get } 22 | var currentFlashMode: YPFlashMode { get } 23 | func flipCamera() 24 | func shoot(completion: @escaping (Data) -> Void) 25 | var videoLayer: AVCaptureVideoPreviewLayer! { get set } 26 | var device: AVCaptureDevice? { get } 27 | 28 | 29 | // Used by Default extension 30 | var previewView: UIView! { get set } 31 | func startCamera() 32 | var isPreviewSetup: Bool { get set } 33 | var sessionQueue: DispatchQueue { get } 34 | var session: AVCaptureSession { get } 35 | var output: AVCaptureOutput { get } 36 | var deviceInput: AVCaptureDeviceInput? { get set } 37 | func configure() 38 | } 39 | 40 | func newPhotoCapture() -> YPPhotoCapture { 41 | if #available(iOS 10.0, *) { 42 | return PostiOS10PhotoCapture() 43 | } else { 44 | return PreiOS10PhotoCapture() 45 | } 46 | } 47 | 48 | enum YPFlashMode { 49 | case off 50 | case on 51 | case auto 52 | } 53 | 54 | extension YPFlashMode { 55 | func flashImage() -> UIImage { 56 | switch self { 57 | case .on: return flashOnImage! 58 | case .off: return flashOffImage! 59 | case .auto: return flashAutoImage! 60 | } 61 | } 62 | } 63 | 64 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Source/Configuration/YPFilterDescriptor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // YPFilterDescriptor.swift 3 | // YPImagePicker 4 | // 5 | // Created by Emil Atanasov on 14.04.18. 6 | // Copyright © 2018 Yummypets. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public class YPFilterDescriptor { 12 | let name:String 13 | let filterName:String 14 | 15 | public init(name: String, filterName: String ) { 16 | self.name = name 17 | self.filterName = filterName 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Source/Configuration/YPLibraryImageSize.swift: -------------------------------------------------------------------------------- 1 | // 2 | // YPLibraryImageSize.swift 3 | // YPImagePicker 4 | // 5 | // Created by Sacha DSO on 24/01/2018. 6 | // Copyright © 2016 Yummypets. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import AVFoundation 11 | 12 | public enum YPLibraryImageSize { 13 | case original 14 | case cappedTo(size: CGFloat) 15 | } 16 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Source/Configuration/YPPickerScreen.swift: -------------------------------------------------------------------------------- 1 | // 2 | // YPPickerScreen.swift 3 | // YPImagePicker 4 | // 5 | // Created by Sacha DSO on 24/01/2018. 6 | // Copyright © 2016 Yummypets. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public enum YPPickerScreen { 12 | case library 13 | case photo 14 | case video 15 | } 16 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Source/Configuration/YPWordings.swift: -------------------------------------------------------------------------------- 1 | // 2 | // YPWordings.swift 3 | // YPImagePicker 4 | // 5 | // Created by Sacha DSO on 12/03/2018. 6 | // Copyright © 2018 Yummypets. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public struct YPWordings { 12 | 13 | public struct PermissionPopup { 14 | public var title = ypLocalized("YPImagePickerPermissionDeniedPopupTitle") 15 | public var message = ypLocalized("YPImagePickerPermissionDeniedPopupMessage") 16 | public var cancel = ypLocalized("YPImagePickerPermissionDeniedPopupCancel") 17 | public var grantPermission = ypLocalized("YPImagePickerPermissionDeniedPopupGrantPermission") 18 | } 19 | 20 | public var libraryTitle = ypLocalized("YPImagePickerLibrary") 21 | public var cameraTitle = ypLocalized("YPImagePickerPhoto") 22 | public var videoTitle = ypLocalized("YPImagePickerVideo") 23 | public var next = ypLocalized("YPImagePickerNext") 24 | public var filter = ypLocalized("YPImagePickerFilter") 25 | public var videoTooLongTitle = ypLocalized("YPImagePickerVideoTooLongDetail") 26 | public var videoTooLongDetail = ypLocalized("YPImagePickerNext") 27 | public var permissionPopup = PermissionPopup() 28 | } 29 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Source/Filters/YPFilter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // YPFilter.swift 3 | // photoTaking 4 | // 5 | // Created by Sacha Durand Saint Omer on 21/10/16. 6 | // Copyright © 2016 octopepper. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import CoreImage 11 | 12 | var _filterSharedContext: CIContext! 13 | 14 | struct YPFilter { 15 | 16 | var name = "" 17 | 18 | init(_ name: String) { 19 | self.name = name 20 | } 21 | 22 | func filter(_ image: UIImage) -> UIImage { 23 | if name == "" { 24 | return image 25 | } 26 | let context = filterSharedContext() 27 | let ciImage = CIImage(image: image) 28 | if let filter = CIFilter(name: name) { 29 | filter.setValue(ciImage, forKey: kCIInputImageKey) 30 | if let outputImage = filter.outputImage, 31 | let cgImg = context.createCGImage(outputImage, from: outputImage.extent) { 32 | return UIImage(cgImage: cgImg, scale: image.scale, orientation: image.imageOrientation) 33 | } else { 34 | return UIImage() 35 | } 36 | } 37 | return UIImage() 38 | } 39 | 40 | func filterSharedContext() -> CIContext { 41 | if _filterSharedContext == nil { 42 | if let context = EAGLContext(api: .openGLES2) { 43 | _filterSharedContext = CIContext(eaglContext: context) 44 | } 45 | return _filterSharedContext 46 | } else { 47 | return _filterSharedContext 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Source/Filters/YPFilterPreview.swift: -------------------------------------------------------------------------------- 1 | // 2 | // YPFilterPreview.swift 3 | // photoTaking 4 | // 5 | // Created by Sacha Durand Saint Omer on 21/10/16. 6 | // Copyright © 2016 octopepper. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class YPFilterPreview { 12 | 13 | let name: String 14 | var image: UIImage? 15 | 16 | init(_ name: String) { 17 | self.name = name 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Source/Filters/YPFiltersView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // YPFiltersView.swift 3 | // photoTaking 4 | // 5 | // Created by Sacha Durand Saint Omer on 21/10/16. 6 | // Copyright © 2016 octopepper. All rights reserved. 7 | // 8 | 9 | import Stevia 10 | 11 | class YPFiltersView: UIView { 12 | 13 | let imageView = UIImageView() 14 | var collectionView: UICollectionView! 15 | 16 | convenience init() { 17 | self.init(frame: CGRect.zero) 18 | collectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout()) 19 | 20 | sv( 21 | imageView, 22 | collectionView 23 | ) 24 | 25 | let isIphone4 = UIScreen.main.bounds.height == 480 26 | let sideMargin: CGFloat = isIphone4 ? 20 : 0 27 | 28 | |-sideMargin-imageView.top(0)-sideMargin-| 29 | |collectionView.bottom(42).height(160)| 30 | 31 | imageView.heightEqualsWidth() 32 | 33 | backgroundColor = UIColor(r: 247, g: 247, b: 247) 34 | imageView.contentMode = .scaleAspectFit 35 | imageView.clipsToBounds = true 36 | collectionView.backgroundColor = .clear 37 | collectionView.showsHorizontalScrollIndicator = false 38 | } 39 | 40 | func layout() -> UICollectionViewFlowLayout { 41 | let layout = UICollectionViewFlowLayout() 42 | layout.scrollDirection = .horizontal 43 | layout.minimumLineSpacing = 4 44 | layout.sectionInset = UIEdgeInsets(top: 0, left: 18, bottom: 0, right: 18) 45 | layout.itemSize = CGSize(width: 100, height: 120) 46 | return layout 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Source/Helpers/IndexSet+IndexPath.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IndexSet+IndexPath.swift 3 | // YPImagePicker 4 | // 5 | // Created by Sacha DSO on 26/01/2018. 6 | // Copyright © 2018 Yummypets. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | internal extension IndexSet { 12 | 13 | func aapl_indexPathsFromIndexesWithSection(_ section: Int) -> [IndexPath] { 14 | var indexPaths: [IndexPath] = [] 15 | indexPaths.reserveCapacity(count) 16 | (self as NSIndexSet).enumerate({idx, _ in 17 | indexPaths.append(IndexPath(item: idx, section: section)) 18 | }) 19 | return indexPaths 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Source/Helpers/PHFetchResult + IndexPath.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PHFetchResult + IndexPath.swift 3 | // YPImagePicker 4 | // 5 | // Created by Sacha DSO on 26/01/2018. 6 | // Copyright © 2018 Yummypets. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Photos 11 | 12 | extension PHFetchResult where ObjectType == PHAsset { 13 | 14 | func assetsAtIndexPaths(_ indexPaths: [IndexPath]) -> [PHAsset] { 15 | if indexPaths.count == 0 { return [] } 16 | var assets: [PHAsset] = [] 17 | assets.reserveCapacity(indexPaths.count) 18 | for indexPath in indexPaths { 19 | let asset = self[indexPath.item] 20 | assets.append(asset) 21 | } 22 | return assets 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Source/Helpers/UICollectionView+IndexPath.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UICollectionView+IndexPath.swift 3 | // YPImagePicker 4 | // 5 | // Created by Sacha DSO on 26/01/2018. 6 | // Copyright © 2018 Yummypets. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | internal extension UICollectionView { 12 | 13 | func aapl_indexPathsForElementsInRect(_ rect: CGRect) -> [IndexPath] { 14 | let allLayoutAttributes = collectionViewLayout.layoutAttributesForElements(in: rect) 15 | if (allLayoutAttributes?.count ?? 0) == 0 {return []} 16 | var indexPaths: [IndexPath] = [] 17 | indexPaths.reserveCapacity(allLayoutAttributes!.count) 18 | for layoutAttributes in allLayoutAttributes! { 19 | let indexPath = layoutAttributes.indexPath 20 | indexPaths.append(indexPath) 21 | } 22 | return indexPaths 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Source/Helpers/YPAlerts.swift: -------------------------------------------------------------------------------- 1 | // 2 | // YPAlerts.swift 3 | // YPImagePicker 4 | // 5 | // Created by Sacha DSO on 26/01/2018. 6 | // Copyright © 2018 Yummypets. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | struct YPAlerts { 12 | 13 | static func videoTooLongAlert(with config: YPImagePickerConfiguration ) -> UIAlertController { 14 | let str = config.wordings.videoTooLongDetail 15 | let msg = String(format: str, "\(config.videoFromLibraryTimeLimit)") 16 | let alert = UIAlertController(title: config.wordings.videoTooLongTitle, 17 | message: msg, 18 | preferredStyle: .alert) 19 | alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: nil)) 20 | return alert 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Source/Helpers/YPDragDirection.swift: -------------------------------------------------------------------------------- 1 | // 2 | // YPDragDirection.swift 3 | // YPImagePicker 4 | // 5 | // Created by Sacha DSO on 26/01/2018. 6 | // Copyright © 2018 Yummypets. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | enum YPDragDirection { 12 | case scroll 13 | case stop 14 | case up 15 | case down 16 | } 17 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Source/Helpers/YPPermissionDeniedPopup.swift: -------------------------------------------------------------------------------- 1 | // 2 | // YPPermissionDeniedPopup.swift 3 | // YPImagePicker 4 | // 5 | // Created by Sacha DSO on 12/03/2018. 6 | // Copyright © 2018 Yummypets. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class YPPermissionDeniedPopup { 12 | 13 | private let configuration: YPImagePickerConfiguration! 14 | public required init(configuration: YPImagePickerConfiguration) { 15 | self.configuration = configuration 16 | } 17 | 18 | func popup(cancelBlock: @escaping () -> Void) -> UIAlertController { 19 | let alert = UIAlertController(title: 20 | configuration.wordings.permissionPopup.title, 21 | message: configuration.wordings.permissionPopup.message, 22 | preferredStyle: .alert) 23 | alert.addAction( 24 | UIAlertAction(title: configuration.wordings.permissionPopup.cancel, 25 | style: UIAlertActionStyle.cancel, 26 | handler: { _ in 27 | cancelBlock() 28 | })) 29 | alert.addAction( 30 | UIAlertAction(title: configuration.wordings.permissionPopup.grantPermission, 31 | style: .default, 32 | handler: { _ in 33 | if #available(iOS 10.0, *) { 34 | UIApplication.shared.open(URL(string: UIApplicationOpenSettingsURLString)!) 35 | } else { 36 | UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!) 37 | } 38 | })) 39 | return alert 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Source/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 2.8.1 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | 24 | 25 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Source/Library/YPAlbum.swift: -------------------------------------------------------------------------------- 1 | // 2 | // YPAlbum.swift 3 | // YPImagePicker 4 | // 5 | // Created by Sacha Durand Saint Omer on 20/07/2017. 6 | // Copyright © 2017 Yummypets. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Photos 11 | 12 | struct YPAlbum { 13 | var thumbnail: UIImage? 14 | var title: String = "" 15 | var numberOfPhotos: Int = 0 16 | var collection: PHAssetCollection? 17 | } 18 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Source/Library/YPAlbumCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // YPAlbumCell.swift 3 | // YPImagePicker 4 | // 5 | // Created by Sacha Durand Saint Omer on 20/07/2017. 6 | // Copyright © 2017 Yummypets. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Stevia 11 | 12 | class YPAlbumCell: UITableViewCell { 13 | 14 | let thumbnail = UIImageView() 15 | let title = UILabel() 16 | let numberOfPhotos = UILabel() 17 | 18 | required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } 19 | 20 | override init(style: UITableViewCellStyle, reuseIdentifier: String?) { 21 | super.init(style: style, reuseIdentifier: reuseIdentifier) 22 | 23 | let stackView = UIStackView() 24 | stackView.axis = .vertical 25 | stackView.addArrangedSubview(title) 26 | stackView.addArrangedSubview(numberOfPhotos) 27 | 28 | sv( 29 | thumbnail, 30 | stackView 31 | ) 32 | 33 | layout( 34 | 6, 35 | |-10-thumbnail.size(78), 36 | 6 37 | ) 38 | 39 | align(horizontally: thumbnail-10-stackView) 40 | 41 | thumbnail.contentMode = .scaleAspectFill 42 | thumbnail.clipsToBounds = true 43 | 44 | title.font = UIFont.systemFont(ofSize: 16, weight: UIFont.Weight.regular) 45 | numberOfPhotos.font = UIFont.systemFont(ofSize: 12, weight: UIFont.Weight.regular) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Source/Library/YPAlbumView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // YPAlbumView.swift 3 | // YPImagePicker 4 | // 5 | // Created by Sacha Durand Saint Omer on 20/07/2017. 6 | // Copyright © 2017 Yummypets. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Stevia 11 | 12 | class YPAlbumView: UIView { 13 | 14 | let tableView = UITableView() 15 | let spinner = UIActivityIndicatorView(activityIndicatorStyle: .gray) 16 | 17 | convenience init() { 18 | self.init(frame: .zero) 19 | 20 | sv( 21 | tableView, 22 | spinner 23 | ) 24 | // TableView needs to be the first subview for it to automatically adjust its content inset with the NavBar 25 | 26 | spinner.centerInContainer() 27 | tableView.fillContainer() 28 | 29 | backgroundColor = .white 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Source/Library/YPGridView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // YPGridView.swift 3 | // YPImgePicker 4 | // 5 | // Created by Sacha Durand Saint Omer on 15/11/2016. 6 | // Copyright © 2016 Yummypets. All rights reserved. 7 | // 8 | 9 | import Stevia 10 | 11 | class YPGridView: UIView { 12 | 13 | let line1 = UIView() 14 | let line2 = UIView() 15 | let line3 = UIView() 16 | let line4 = UIView() 17 | 18 | convenience init() { 19 | self.init(frame: .zero) 20 | isUserInteractionEnabled = false 21 | sv( 22 | line1, 23 | line2, 24 | line3, 25 | line4 26 | ) 27 | 28 | let stroke: CGFloat = 0.5 29 | line1.top(0).width(stroke).bottom(0) 30 | line1.Right == 33 % Right 31 | 32 | line2.top(0).width(stroke).bottom(0) 33 | line2.Right == 66 % Right 34 | 35 | line3.left(0).height(stroke).right(0) 36 | line3.Bottom == 33 % Bottom 37 | 38 | line4.left(0).height(stroke).right(0) 39 | line4.Bottom == 66 % Bottom 40 | 41 | let color = UIColor.white.withAlphaComponent(0.6) 42 | line1.backgroundColor = color 43 | line2.backgroundColor = color 44 | line3.backgroundColor = color 45 | line4.backgroundColor = color 46 | 47 | applyShadow(to: line1) 48 | applyShadow(to: line2) 49 | applyShadow(to: line3) 50 | applyShadow(to: line4) 51 | } 52 | 53 | func applyShadow(to view: UIView) { 54 | view.layer.shadowColor = UIColor.black.cgColor 55 | view.layer.shadowOpacity = 1 56 | view.layer.shadowRadius = 2 57 | view.layer.shadowOffset = CGSize(width: 0, height: 0) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Source/Library/YPLibraryViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // YPLibraryViewCell.swift 3 | // YPImgePicker 4 | // 5 | // Created by Sacha Durand Saint Omer on 2015/11/14. 6 | // Copyright © 2015 Yummypets. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Stevia 11 | 12 | class YPLibraryViewCell: UICollectionViewCell { 13 | 14 | var representedAssetIdentifier: String! 15 | let imageView = UIImageView() 16 | let durationLabel = UILabel() 17 | let selectionOverlay = UIView() 18 | 19 | required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } 20 | override init(frame: CGRect) { 21 | super.init(frame: frame) 22 | 23 | sv( 24 | imageView, 25 | durationLabel, 26 | selectionOverlay 27 | ) 28 | 29 | imageView.fillContainer() 30 | selectionOverlay.fillContainer() 31 | layout( 32 | durationLabel-5-|, 33 | 5 34 | ) 35 | 36 | imageView.contentMode = .scaleAspectFill 37 | imageView.clipsToBounds = true 38 | durationLabel.textColor = .white 39 | durationLabel.font = .systemFont(ofSize: 12) 40 | durationLabel.isHidden = true 41 | selectionOverlay.backgroundColor = .black 42 | selectionOverlay.alpha = 0 43 | backgroundColor = UIColor(r: 247, g: 247, b: 247) 44 | } 45 | 46 | override var isSelected: Bool { 47 | didSet { isHighlighted = isSelected } 48 | } 49 | 50 | override var isHighlighted: Bool { 51 | didSet { 52 | selectionOverlay.alpha = isHighlighted ? 0.5 : 0 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Source/Library/YPLibraryViewDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // YPLibraryViewDelegate.swift 3 | // YPImagePicker 4 | // 5 | // Created by Sacha DSO on 26/01/2018. 6 | // Copyright © 2016 Yummypets. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | @objc 12 | public protocol YPLibraryViewDelegate: class { 13 | func libraryViewCameraRollUnauthorized() 14 | func libraryViewStartedLoadingImage() 15 | func libraryViewFinishedLoadingImage() 16 | } 17 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/Source/YPImagePickerHeader.h: -------------------------------------------------------------------------------- 1 | // 2 | // YPImgePicker.h 3 | // YPImgePicker 4 | // 5 | // Created by Sacha Durand Saint Omer on 2016/03/26. 6 | // Copyright © 2016 Yummypets. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for YPImagePicker. 12 | FOUNDATION_EXPORT double YPImagePickerVersionNumber; 13 | 14 | //! Project version string for YPImagePicker. 15 | FOUNDATION_EXPORT const unsigned char YPImagePickerVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/YPImagePicker.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'YPImagePicker' 3 | s.version = "2.8.1" 4 | s.summary = "Instagram-like image picker & filters for iOS" 5 | s.homepage = "https://github.com/Yummypets/YPImagePicker" 6 | s.license = { :type => "MIT", :file => "LICENSE" } 7 | s.author = 'S4cha' 8 | s.platform = :ios 9 | s.source = { :git => "https://github.com/Yummypets/YPImagePicker.git", 10 | :tag => s.version.to_s } 11 | s.social_media_url = 'https://twitter.com/sachadso' 12 | s.requires_arc = true 13 | s.ios.deployment_target = "9.0" 14 | s.source_files = 'Source/**/*.swift' 15 | s.dependency 'SteviaLayout', '~> 4.2.0' 16 | s.resources = ['Resources/*', 'Source/**/*.xib'] 17 | s.description = "Instagram-like image picker & filters for iOS supporting videos and albums" 18 | end 19 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/YPImagePicker.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Chapter12/YPImagePicker_source_with_contribution/YPImagePicker.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ### Download a free PDF 5 | 6 | If you have already purchased a print or Kindle version of this book, you can get a DRM-free PDF version at no cost.
Simply click on the link to claim your free PDF.
7 |

https://packt.link/free-ebook/9781786463920

--------------------------------------------------------------------------------