├── Codable
├── Codable.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcuserdata
│ │ │ └── ahmedmasoud.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── ahmedmasoud.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
├── Codable.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
│ └── xcuserdata
│ │ └── ahmedmasoud.xcuserdatad
│ │ ├── UserInterfaceState.xcuserstate
│ │ └── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
├── Codable
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ ├── Info.plist
│ ├── Model
│ │ ├── CompanyModel.swift
│ │ ├── PostModel.swift
│ │ └── UserModel.swift
│ ├── SceneDelegate.swift
│ └── ViewController.swift
├── Podfile
├── Podfile.lock
└── Pods
│ ├── Alamofire
│ ├── LICENSE
│ ├── README.md
│ └── Source
│ │ ├── AFError.swift
│ │ ├── Alamofire.swift
│ │ ├── AlamofireExtended.swift
│ │ ├── CachedResponseHandler.swift
│ │ ├── DispatchQueue+Alamofire.swift
│ │ ├── EventMonitor.swift
│ │ ├── HTTPHeaders.swift
│ │ ├── HTTPMethod.swift
│ │ ├── MultipartFormData.swift
│ │ ├── MultipartUpload.swift
│ │ ├── NetworkReachabilityManager.swift
│ │ ├── Notifications.swift
│ │ ├── OperationQueue+Alamofire.swift
│ │ ├── ParameterEncoder.swift
│ │ ├── ParameterEncoding.swift
│ │ ├── Protector.swift
│ │ ├── RedirectHandler.swift
│ │ ├── Request.swift
│ │ ├── RequestInterceptor.swift
│ │ ├── RequestTaskMap.swift
│ │ ├── Response.swift
│ │ ├── ResponseSerialization.swift
│ │ ├── Result+Alamofire.swift
│ │ ├── RetryPolicy.swift
│ │ ├── ServerTrustEvaluation.swift
│ │ ├── Session.swift
│ │ ├── SessionDelegate.swift
│ │ ├── URLConvertible+URLRequestConvertible.swift
│ │ ├── URLEncodedFormEncoder.swift
│ │ ├── URLRequest+Alamofire.swift
│ │ ├── URLSessionConfiguration+Alamofire.swift
│ │ └── Validation.swift
│ ├── Manifest.lock
│ ├── Pods.xcodeproj
│ ├── project.pbxproj
│ └── xcuserdata
│ │ └── ahmedmasoud.xcuserdatad
│ │ └── xcschemes
│ │ ├── Alamofire.xcscheme
│ │ ├── Pods-Codable.xcscheme
│ │ └── xcschememanagement.plist
│ └── Target Support Files
│ ├── Alamofire
│ ├── Alamofire-Info.plist
│ ├── Alamofire-dummy.m
│ ├── Alamofire-prefix.pch
│ ├── Alamofire-umbrella.h
│ ├── Alamofire.modulemap
│ └── Alamofire.xcconfig
│ └── Pods-Codable
│ ├── Pods-Codable-Info.plist
│ ├── Pods-Codable-acknowledgements.markdown
│ ├── Pods-Codable-acknowledgements.plist
│ ├── Pods-Codable-dummy.m
│ ├── Pods-Codable-frameworks-Debug-input-files.xcfilelist
│ ├── Pods-Codable-frameworks-Debug-output-files.xcfilelist
│ ├── Pods-Codable-frameworks-Release-input-files.xcfilelist
│ ├── Pods-Codable-frameworks-Release-output-files.xcfilelist
│ ├── Pods-Codable-frameworks.sh
│ ├── Pods-Codable-umbrella.h
│ ├── Pods-Codable.debug.xcconfig
│ ├── Pods-Codable.modulemap
│ └── Pods-Codable.release.xcconfig
├── CustomTransitions
├── CustomTransitions.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcuserdata
│ │ │ └── ahmedmasoud.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── ahmedmasoud.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
└── CustomTransitions
│ ├── Animator
│ └── StretchAnimator.swift
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── Contents.json
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── Info.plist
│ ├── SceneDelegate.swift
│ └── Views
│ ├── DetailVC.swift
│ └── ViewController.swift
├── DispatchGroups
└── DispatchGroups.playground
│ ├── Contents.swift
│ ├── contents.xcplayground
│ └── playground.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcshareddata
│ └── IDEWorkspaceChecks.plist
│ └── xcuserdata
│ └── ahmedmasoud.xcuserdatad
│ └── UserInterfaceState.xcuserstate
├── FacebookStoryAnimation
├── FacebookStoryAnnimation.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcuserdata
│ │ │ └── ahmedmasoud.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── ahmedmasoud.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
└── FacebookStoryAnnimation
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── Contents.json
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── Info.plist
│ ├── SceneDelegate.swift
│ └── ViewController.swift
├── LocalizationManager
├── LocalizationManager.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcuserdata
│ │ │ └── ahmedmasoud.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── ahmedmasoud.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
└── LocalizationManager
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Contents.json
│ └── arrow.imageset
│ │ ├── Contents.json
│ │ └── arrow.png
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── Info.plist
│ ├── LocalizationManager.swift
│ ├── ViewController.swift
│ ├── ar.lproj
│ └── Localizable.strings
│ └── en.lproj
│ └── localizable.strings
├── LoginAnimation
├── LoginAnimation.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcuserdata
│ │ │ └── ahmedmasoud.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── ahmedmasoud.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
└── LoginAnimation
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Contents.json
│ └── logo.imageset
│ │ ├── Contents.json
│ │ └── icon-4399622_960_720.png
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── ButtonsVC.swift
│ ├── Info.plist
│ ├── SceneDelegate.swift
│ └── ViewController.swift
├── NetworkLayer
├── NetworkLayer.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcuserdata
│ │ │ └── ahmedmasoud.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ ├── ahmedmasoud.xcuserdatad
│ │ └── xcschemes
│ │ │ └── xcschememanagement.plist
│ │ └── fatema.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
├── NetworkLayer.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
│ └── xcuserdata
│ │ ├── ahmedmasoud.xcuserdatad
│ │ ├── UserInterfaceState.xcuserstate
│ │ └── xcdebugger
│ │ │ └── Breakpoints_v2.xcbkptlist
│ │ └── fatema.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
├── NetworkLayer
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ ├── Constants.swift
│ ├── Info.plist
│ ├── Models
│ │ └── UserModel.swift
│ ├── Networkinng
│ │ ├── Base
│ │ │ ├── BaseAPI.swift
│ │ │ ├── BaseResponse.swift
│ │ │ └── TargetType.swift
│ │ └── Users
│ │ │ ├── UsersAPI.swift
│ │ │ └── UsersNetworking.swift
│ ├── SceneDelegate.swift
│ └── ViewController.swift
├── Podfile
├── Podfile.lock
└── Pods
│ ├── Alamofire
│ ├── LICENSE
│ ├── README.md
│ └── Source
│ │ ├── AFError.swift
│ │ ├── Alamofire.swift
│ │ ├── AlamofireExtended.swift
│ │ ├── CachedResponseHandler.swift
│ │ ├── DispatchQueue+Alamofire.swift
│ │ ├── EventMonitor.swift
│ │ ├── HTTPHeaders.swift
│ │ ├── HTTPMethod.swift
│ │ ├── MultipartFormData.swift
│ │ ├── MultipartUpload.swift
│ │ ├── NetworkReachabilityManager.swift
│ │ ├── Notifications.swift
│ │ ├── OperationQueue+Alamofire.swift
│ │ ├── ParameterEncoder.swift
│ │ ├── ParameterEncoding.swift
│ │ ├── Protector.swift
│ │ ├── RedirectHandler.swift
│ │ ├── Request.swift
│ │ ├── RequestInterceptor.swift
│ │ ├── RequestTaskMap.swift
│ │ ├── Response.swift
│ │ ├── ResponseSerialization.swift
│ │ ├── Result+Alamofire.swift
│ │ ├── RetryPolicy.swift
│ │ ├── ServerTrustEvaluation.swift
│ │ ├── Session.swift
│ │ ├── SessionDelegate.swift
│ │ ├── URLConvertible+URLRequestConvertible.swift
│ │ ├── URLEncodedFormEncoder.swift
│ │ ├── URLRequest+Alamofire.swift
│ │ ├── URLSessionConfiguration+Alamofire.swift
│ │ └── Validation.swift
│ ├── Manifest.lock
│ ├── Pods.xcodeproj
│ ├── project.pbxproj
│ └── xcuserdata
│ │ ├── ahmedmasoud.xcuserdatad
│ │ └── xcschemes
│ │ │ ├── Alamofire.xcscheme
│ │ │ ├── Pods-NetworkLayer.xcscheme
│ │ │ └── xcschememanagement.plist
│ │ └── fatema.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
│ └── Target Support Files
│ ├── Alamofire
│ ├── Alamofire-Info.plist
│ ├── Alamofire-dummy.m
│ ├── Alamofire-prefix.pch
│ ├── Alamofire-umbrella.h
│ ├── Alamofire.modulemap
│ └── Alamofire.xcconfig
│ └── Pods-NetworkLayer
│ ├── Pods-NetworkLayer-Info.plist
│ ├── Pods-NetworkLayer-acknowledgements.markdown
│ ├── Pods-NetworkLayer-acknowledgements.plist
│ ├── Pods-NetworkLayer-dummy.m
│ ├── Pods-NetworkLayer-frameworks-Debug-input-files.xcfilelist
│ ├── Pods-NetworkLayer-frameworks-Debug-output-files.xcfilelist
│ ├── Pods-NetworkLayer-frameworks-Release-input-files.xcfilelist
│ ├── Pods-NetworkLayer-frameworks-Release-output-files.xcfilelist
│ ├── Pods-NetworkLayer-frameworks.sh
│ ├── Pods-NetworkLayer-umbrella.h
│ ├── Pods-NetworkLayer.debug.xcconfig
│ ├── Pods-NetworkLayer.modulemap
│ └── Pods-NetworkLayer.release.xcconfig
├── README.md
├── StretchyTableHeader
├── StretchyTableHeader.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcuserdata
│ │ │ └── ahmedmasoud.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── ahmedmasoud.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
└── StretchyTableHeader
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Contents.json
│ └── header.imageset
│ │ ├── Contents.json
│ │ └── header.png
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── Info.plist
│ ├── SceneDelegate.swift
│ └── ViewController.swift
└── ToastManager
├── ToastManager.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
│ └── xcuserdata
│ │ └── ahmedmasoud.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
└── xcuserdata
│ └── ahmedmasoud.xcuserdatad
│ └── xcschemes
│ └── xcschememanagement.plist
└── ToastManager
├── AppDelegate.swift
├── Assets.xcassets
├── AppIcon.appiconset
│ └── Contents.json
└── Contents.json
├── Base.lproj
├── LaunchScreen.storyboard
└── Main.storyboard
├── Info.plist
├── Managers
├── KeyboardStateManager.swift
└── ToastManager.swift
├── SceneDelegate.swift
└── Views
├── ToastView
├── ToastView.swift
└── ToastView.xib
└── ViewController.swift
/Codable/Codable.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Codable/Codable.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Codable/Codable.xcodeproj/project.xcworkspace/xcuserdata/ahmedmasoud.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Masoud/Tutorials/5bbaf498957c7d8d6ba545cea930bceb515889ec/Codable/Codable.xcodeproj/project.xcworkspace/xcuserdata/ahmedmasoud.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/Codable/Codable.xcodeproj/xcuserdata/ahmedmasoud.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | Codable.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 2
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Codable/Codable.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Codable/Codable.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Codable/Codable.xcworkspace/xcuserdata/ahmedmasoud.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Masoud/Tutorials/5bbaf498957c7d8d6ba545cea930bceb515889ec/Codable/Codable.xcworkspace/xcuserdata/ahmedmasoud.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/Codable/Codable.xcworkspace/xcuserdata/ahmedmasoud.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/Codable/Codable/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // Codable
4 | //
5 | // Created by Ahmed masoud on 3/30/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
30 | // Called when the user discards a scene session.
31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/Codable/Codable/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" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/Codable/Codable/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Codable/Codable/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 |
--------------------------------------------------------------------------------
/Codable/Codable/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 |
--------------------------------------------------------------------------------
/Codable/Codable/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | $(PRODUCT_MODULE_NAME).SceneDelegate
36 | UISceneStoryboardFile
37 | Main
38 |
39 |
40 |
41 |
42 | UILaunchStoryboardName
43 | LaunchScreen
44 | UIMainStoryboardFile
45 | Main
46 | UIRequiredDeviceCapabilities
47 |
48 | armv7
49 |
50 | UISupportedInterfaceOrientations
51 |
52 | UIInterfaceOrientationPortrait
53 | UIInterfaceOrientationLandscapeLeft
54 | UIInterfaceOrientationLandscapeRight
55 |
56 | UISupportedInterfaceOrientations~ipad
57 |
58 | UIInterfaceOrientationPortrait
59 | UIInterfaceOrientationPortraitUpsideDown
60 | UIInterfaceOrientationLandscapeLeft
61 | UIInterfaceOrientationLandscapeRight
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/Codable/Codable/Model/CompanyModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CompanyModel.swift
3 | // Codable
4 | //
5 | // Created by Ahmed masoud on 3/30/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class CompanyModel: Decodable {
12 | var name: String?
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/Codable/Codable/Model/PostModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PostModel.swift
3 | // Codable
4 | //
5 | // Created by Ahmed masoud on 3/30/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class PostModel: Decodable {
12 | var title: String?
13 | var body: String?
14 | }
15 |
--------------------------------------------------------------------------------
/Codable/Codable/Model/UserModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UserModel.swift
3 | // Codable
4 | //
5 | // Created by Ahmed masoud on 3/30/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class UserModel: Decodable {
12 | //MARK:- Properties
13 | var id: Int?
14 | var name: String?
15 | var email: String?
16 | var userName: String?
17 | var company: CompanyModel?
18 |
19 | enum CodingKeys: String, CodingKey {
20 | case id
21 | case name
22 | case email
23 | case userName = "username"
24 | case company
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Codable/Codable/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // Codable
4 | //
5 | // Created by Ahmed masoud on 3/30/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
12 |
13 | var window: UIWindow?
14 |
15 |
16 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
17 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
18 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
19 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
20 | guard let _ = (scene as? UIWindowScene) else { return }
21 | }
22 |
23 | func sceneDidDisconnect(_ scene: UIScene) {
24 | // Called as the scene is being released by the system.
25 | // This occurs shortly after the scene enters the background, or when its session is discarded.
26 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
27 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
28 | }
29 |
30 | func sceneDidBecomeActive(_ scene: UIScene) {
31 | // Called when the scene has moved from an inactive state to an active state.
32 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
33 | }
34 |
35 | func sceneWillResignActive(_ scene: UIScene) {
36 | // Called when the scene will move from an active state to an inactive state.
37 | // This may occur due to temporary interruptions (ex. an incoming phone call).
38 | }
39 |
40 | func sceneWillEnterForeground(_ scene: UIScene) {
41 | // Called as the scene transitions from the background to the foreground.
42 | // Use this method to undo the changes made on entering the background.
43 | }
44 |
45 | func sceneDidEnterBackground(_ scene: UIScene) {
46 | // Called as the scene transitions from the foreground to the background.
47 | // Use this method to save data, release shared resources, and store enough scene-specific state information
48 | // to restore the scene back to its current state.
49 | }
50 |
51 |
52 | }
53 |
54 |
--------------------------------------------------------------------------------
/Codable/Codable/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // Codable
4 | //
5 | // Created by Ahmed masoud on 3/30/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import Alamofire
11 |
12 | class ViewController: UIViewController {
13 |
14 | override func viewDidLoad() {
15 | super.viewDidLoad()
16 |
17 | fetchData(url: "https://jsonplaceholder.typicode.com/users", responseClass: [UserModel].self) { (response) in
18 | switch response {
19 | case .success(let users):
20 | guard let users = users else { return }
21 | for user in users {
22 | print("name -> \(user.name)")
23 | }
24 | case .failure(_):
25 | print("ERROR")
26 | }
27 | }
28 |
29 | }
30 |
31 | func fetchData(url: String, responseClass: T.Type , completion:@escaping (Result) -> Void) {
32 | AF.request(url, method: .get, parameters: [:], headers: [:]).responseJSON { (response) in
33 | guard let statusCode = response.response?.statusCode else { return }
34 | if statusCode == 200 { // Success
35 | guard let jsonResponse = try? response.result.get() else { return }
36 | guard let theJSONData = try? JSONSerialization.data(withJSONObject: jsonResponse, options: []) else { return }
37 | guard let responseObj = try? JSONDecoder().decode(T.self, from: theJSONData) else { return }
38 | completion(.success(responseObj))
39 | }
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Codable/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment the next line to define a global platform for your project
2 | # platform :ios, '9.0'
3 |
4 | target 'Codable' do
5 | # Comment the next line if you don't want to use dynamic frameworks
6 | use_frameworks!
7 |
8 | # Pods for Codable
9 | pod 'Alamofire'
10 | end
11 |
--------------------------------------------------------------------------------
/Codable/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - Alamofire (5.0.2)
3 |
4 | DEPENDENCIES:
5 | - Alamofire
6 |
7 | SPEC REPOS:
8 | https://github.com/cocoapods/specs.git:
9 | - Alamofire
10 |
11 | SPEC CHECKSUMS:
12 | Alamofire: 3ba7a4db18b4f62c4a1c0e1cb39d7f3d52e10ada
13 |
14 | PODFILE CHECKSUM: dfbe2768ec522903afa51e515607c7b55f473ff4
15 |
16 | COCOAPODS: 1.7.5
17 |
--------------------------------------------------------------------------------
/Codable/Pods/Alamofire/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2014-2020 Alamofire Software Foundation (http://alamofire.org/)
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/Codable/Pods/Alamofire/Source/Alamofire.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Alamofire.swift
3 | //
4 | // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/)
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 | //
24 |
25 | /// Reference to `Session.default` for quick bootstrapping and examples.
26 | public let AF = Session.default
27 |
28 | /// Current Alamofire version. Necessary since SPM doesn't use dynamic libraries. Plus this will be more accurate.
29 | let version = "5.0.2"
30 |
--------------------------------------------------------------------------------
/Codable/Pods/Alamofire/Source/AlamofireExtended.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AlamofireExtended.swift
3 | //
4 | // Copyright (c) 2019 Alamofire Software Foundation (http://alamofire.org/)
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 | //
24 |
25 | /// Type that acts as a generic extension point for all `AlamofireExtended` types.
26 | public struct AlamofireExtension {
27 | /// Stores the type or meta-type of any extended type.
28 | public private(set) var type: ExtendedType
29 |
30 | /// Create an instance from the provided value.
31 | ///
32 | /// - Parameter type: Instance being extended.
33 | public init(_ type: ExtendedType) {
34 | self.type = type
35 | }
36 | }
37 |
38 | /// Protocol describing the `af` extension points for Alamofire extended types.
39 | public protocol AlamofireExtended {
40 | /// Type being extended.
41 | associatedtype ExtendedType
42 |
43 | /// Static Alamofire extension point.
44 | static var af: AlamofireExtension.Type { get set }
45 | /// Instance Alamofire extension point.
46 | var af: AlamofireExtension { get set }
47 | }
48 |
49 | public extension AlamofireExtended {
50 | /// Static Alamofire extension point.
51 | static var af: AlamofireExtension.Type {
52 | get { return AlamofireExtension.self }
53 | set {}
54 | }
55 |
56 | /// Instance Alamofire extension point.
57 | var af: AlamofireExtension {
58 | get { return AlamofireExtension(self) }
59 | set {}
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/Codable/Pods/Alamofire/Source/DispatchQueue+Alamofire.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DispatchQueue+Alamofire.swift
3 | //
4 | // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/)
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 | //
24 |
25 | import Dispatch
26 | import Foundation
27 |
28 | extension DispatchQueue {
29 | /// Execute the provided closure after a `TimeInterval`.
30 | ///
31 | /// - Parameters:
32 | /// - delay: `TimeInterval` to delay execution.
33 | /// - closure: Closure to execute.
34 | func after(_ delay: TimeInterval, execute closure: @escaping () -> Void) {
35 | asyncAfter(deadline: .now() + delay, execute: closure)
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Codable/Pods/Alamofire/Source/HTTPMethod.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HTTPMethod.swift
3 | //
4 | // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/)
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 | //
24 |
25 | /// Type representing HTTP methods. Raw `String` value is stored and compared case-sensitively, so
26 | /// `HTTPMethod.get != HTTPMethod(rawValue: "get")`.
27 | ///
28 | /// See https://tools.ietf.org/html/rfc7231#section-4.3
29 | public struct HTTPMethod: RawRepresentable, Equatable, Hashable {
30 | /// `CONNECT` method.
31 | public static let connect = HTTPMethod(rawValue: "CONNECT")
32 | /// `DELETE` method.
33 | public static let delete = HTTPMethod(rawValue: "DELETE")
34 | /// `GET` method.
35 | public static let get = HTTPMethod(rawValue: "GET")
36 | /// `HEAD` method.
37 | public static let head = HTTPMethod(rawValue: "HEAD")
38 | /// `OPTIONS` method.
39 | public static let options = HTTPMethod(rawValue: "OPTIONS")
40 | /// `PATCH` method.
41 | public static let patch = HTTPMethod(rawValue: "PATCH")
42 | /// `POST` method.
43 | public static let post = HTTPMethod(rawValue: "POST")
44 | /// `PUT` method.
45 | public static let put = HTTPMethod(rawValue: "PUT")
46 | /// `TRACE` method.
47 | public static let trace = HTTPMethod(rawValue: "TRACE")
48 |
49 | public let rawValue: String
50 |
51 | public init(rawValue: String) {
52 | self.rawValue = rawValue
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/Codable/Pods/Alamofire/Source/OperationQueue+Alamofire.swift:
--------------------------------------------------------------------------------
1 | //
2 | // OperationQueue+Alamofire.swift
3 | //
4 | // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/)
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 | //
24 |
25 | import Foundation
26 |
27 | extension OperationQueue {
28 | /// Creates an instance using the provided parameters.
29 | ///
30 | /// - Parameters:
31 | /// - qualityOfService: `QualityOfService` to be applied to the queue. `.default` by default.
32 | /// - maxConcurrentOperationCount: Maximum concurrent operations.
33 | /// `OperationQueue.defaultMaxConcurrentOperationCount` by default.
34 | /// - underlyingQueue: Underlying `DispatchQueue`. `nil` by default.
35 | /// - name: Name for the queue. `nil` by default.
36 | /// - startSuspended: Whether the queue starts suspended. `false` by default.
37 | convenience init(qualityOfService: QualityOfService = .default,
38 | maxConcurrentOperationCount: Int = OperationQueue.defaultMaxConcurrentOperationCount,
39 | underlyingQueue: DispatchQueue? = nil,
40 | name: String? = nil,
41 | startSuspended: Bool = false) {
42 | self.init()
43 | self.qualityOfService = qualityOfService
44 | self.maxConcurrentOperationCount = maxConcurrentOperationCount
45 | self.underlyingQueue = underlyingQueue
46 | self.name = name
47 | isSuspended = startSuspended
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Codable/Pods/Alamofire/Source/URLRequest+Alamofire.swift:
--------------------------------------------------------------------------------
1 | //
2 | // URLRequest+Alamofire.swift
3 | //
4 | // Copyright (c) 2019 Alamofire Software Foundation (http://alamofire.org/)
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 | //
24 |
25 | import Foundation
26 |
27 | public extension URLRequest {
28 | /// Returns the `httpMethod` as Alamofire's `HTTPMethod` type.
29 | var method: HTTPMethod? {
30 | get { return httpMethod.flatMap(HTTPMethod.init) }
31 | set { httpMethod = newValue?.rawValue }
32 | }
33 |
34 | func validate() throws {
35 | if method == .get, let bodyData = httpBody {
36 | throw AFError.urlRequestValidationFailed(reason: .bodyDataInGETRequest(bodyData))
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Codable/Pods/Alamofire/Source/URLSessionConfiguration+Alamofire.swift:
--------------------------------------------------------------------------------
1 | //
2 | // URLSessionConfiguration+Alamofire.swift
3 | //
4 | // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/)
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 | //
24 |
25 | import Foundation
26 |
27 | extension URLSessionConfiguration: AlamofireExtended {}
28 | extension AlamofireExtension where ExtendedType: URLSessionConfiguration {
29 | /// Alamofire's default configuration. Same as `URLSessionConfiguration.default` but adds Alamofire default
30 | /// `Accept-Language`, `Accept-Encoding`, and `User-Agent` headers.
31 | public static var `default`: URLSessionConfiguration {
32 | let configuration = URLSessionConfiguration.default
33 | configuration.headers = .default
34 |
35 | return configuration
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Codable/Pods/Manifest.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - Alamofire (5.0.2)
3 |
4 | DEPENDENCIES:
5 | - Alamofire
6 |
7 | SPEC REPOS:
8 | https://github.com/cocoapods/specs.git:
9 | - Alamofire
10 |
11 | SPEC CHECKSUMS:
12 | Alamofire: 3ba7a4db18b4f62c4a1c0e1cb39d7f3d52e10ada
13 |
14 | PODFILE CHECKSUM: dfbe2768ec522903afa51e515607c7b55f473ff4
15 |
16 | COCOAPODS: 1.7.5
17 |
--------------------------------------------------------------------------------
/Codable/Pods/Pods.xcodeproj/xcuserdata/ahmedmasoud.xcuserdatad/xcschemes/Alamofire.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
45 |
46 |
52 |
53 |
55 |
56 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/Codable/Pods/Pods.xcodeproj/xcuserdata/ahmedmasoud.xcuserdatad/xcschemes/Pods-Codable.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
50 |
51 |
53 |
54 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/Codable/Pods/Pods.xcodeproj/xcuserdata/ahmedmasoud.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | Alamofire.xcscheme
8 |
9 | isShown
10 |
11 | orderHint
12 | 0
13 |
14 | Pods-Codable.xcscheme
15 |
16 | isShown
17 |
18 | orderHint
19 | 1
20 |
21 |
22 | SuppressBuildableAutocreation
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Codable/Pods/Target Support Files/Alamofire/Alamofire-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 | 5.0.2
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Codable/Pods/Target Support Files/Alamofire/Alamofire-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Alamofire : NSObject
3 | @end
4 | @implementation PodsDummy_Alamofire
5 | @end
6 |
--------------------------------------------------------------------------------
/Codable/Pods/Target Support Files/Alamofire/Alamofire-prefix.pch:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
--------------------------------------------------------------------------------
/Codable/Pods/Target Support Files/Alamofire/Alamofire-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
14 | FOUNDATION_EXPORT double AlamofireVersionNumber;
15 | FOUNDATION_EXPORT const unsigned char AlamofireVersionString[];
16 |
17 |
--------------------------------------------------------------------------------
/Codable/Pods/Target Support Files/Alamofire/Alamofire.modulemap:
--------------------------------------------------------------------------------
1 | framework module Alamofire {
2 | umbrella header "Alamofire-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/Codable/Pods/Target Support Files/Alamofire/Alamofire.xcconfig:
--------------------------------------------------------------------------------
1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Alamofire
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | OTHER_LDFLAGS = $(inherited) -framework "CFNetwork"
4 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
5 | PODS_BUILD_DIR = ${BUILD_DIR}
6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
7 | PODS_ROOT = ${SRCROOT}
8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/Alamofire
9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
10 | SKIP_INSTALL = YES
11 |
--------------------------------------------------------------------------------
/Codable/Pods/Target Support Files/Pods-Codable/Pods-Codable-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 | 1.0.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Codable/Pods/Target Support Files/Pods-Codable/Pods-Codable-acknowledgements.markdown:
--------------------------------------------------------------------------------
1 | # Acknowledgements
2 | This application makes use of the following third party libraries:
3 |
4 | ## Alamofire
5 |
6 | Copyright (c) 2014-2020 Alamofire Software Foundation (http://alamofire.org/)
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining a copy
9 | of this software and associated documentation files (the "Software"), to deal
10 | in the Software without restriction, including without limitation the rights
11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | copies of the Software, and to permit persons to whom the Software is
13 | furnished to do so, subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be included in
16 | all copies or substantial portions of the Software.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 | THE SOFTWARE.
25 |
26 | Generated by CocoaPods - https://cocoapods.org
27 |
--------------------------------------------------------------------------------
/Codable/Pods/Target Support Files/Pods-Codable/Pods-Codable-acknowledgements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreferenceSpecifiers
6 |
7 |
8 | FooterText
9 | This application makes use of the following third party libraries:
10 | Title
11 | Acknowledgements
12 | Type
13 | PSGroupSpecifier
14 |
15 |
16 | FooterText
17 | Copyright (c) 2014-2020 Alamofire Software Foundation (http://alamofire.org/)
18 |
19 | Permission is hereby granted, free of charge, to any person obtaining a copy
20 | of this software and associated documentation files (the "Software"), to deal
21 | in the Software without restriction, including without limitation the rights
22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
23 | copies of the Software, and to permit persons to whom the Software is
24 | furnished to do so, subject to the following conditions:
25 |
26 | The above copyright notice and this permission notice shall be included in
27 | all copies or substantial portions of the Software.
28 |
29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
35 | THE SOFTWARE.
36 |
37 | License
38 | MIT
39 | Title
40 | Alamofire
41 | Type
42 | PSGroupSpecifier
43 |
44 |
45 | FooterText
46 | Generated by CocoaPods - https://cocoapods.org
47 | Title
48 |
49 | Type
50 | PSGroupSpecifier
51 |
52 |
53 | StringsTable
54 | Acknowledgements
55 | Title
56 | Acknowledgements
57 |
58 |
59 |
--------------------------------------------------------------------------------
/Codable/Pods/Target Support Files/Pods-Codable/Pods-Codable-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Pods_Codable : NSObject
3 | @end
4 | @implementation PodsDummy_Pods_Codable
5 | @end
6 |
--------------------------------------------------------------------------------
/Codable/Pods/Target Support Files/Pods-Codable/Pods-Codable-frameworks-Debug-input-files.xcfilelist:
--------------------------------------------------------------------------------
1 | ${PODS_ROOT}/Target Support Files/Pods-Codable/Pods-Codable-frameworks.sh
2 | ${BUILT_PRODUCTS_DIR}/Alamofire/Alamofire.framework
--------------------------------------------------------------------------------
/Codable/Pods/Target Support Files/Pods-Codable/Pods-Codable-frameworks-Debug-output-files.xcfilelist:
--------------------------------------------------------------------------------
1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Alamofire.framework
--------------------------------------------------------------------------------
/Codable/Pods/Target Support Files/Pods-Codable/Pods-Codable-frameworks-Release-input-files.xcfilelist:
--------------------------------------------------------------------------------
1 | ${PODS_ROOT}/Target Support Files/Pods-Codable/Pods-Codable-frameworks.sh
2 | ${BUILT_PRODUCTS_DIR}/Alamofire/Alamofire.framework
--------------------------------------------------------------------------------
/Codable/Pods/Target Support Files/Pods-Codable/Pods-Codable-frameworks-Release-output-files.xcfilelist:
--------------------------------------------------------------------------------
1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Alamofire.framework
--------------------------------------------------------------------------------
/Codable/Pods/Target Support Files/Pods-Codable/Pods-Codable-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
14 | FOUNDATION_EXPORT double Pods_CodableVersionNumber;
15 | FOUNDATION_EXPORT const unsigned char Pods_CodableVersionString[];
16 |
17 |
--------------------------------------------------------------------------------
/Codable/Pods/Target Support Files/Pods-Codable/Pods-Codable.debug.xcconfig:
--------------------------------------------------------------------------------
1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire"
3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire/Alamofire.framework/Headers"
5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
6 | OTHER_LDFLAGS = $(inherited) -framework "Alamofire" -framework "CFNetwork"
7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
8 | PODS_BUILD_DIR = ${BUILD_DIR}
9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
11 | PODS_ROOT = ${SRCROOT}/Pods
12 |
--------------------------------------------------------------------------------
/Codable/Pods/Target Support Files/Pods-Codable/Pods-Codable.modulemap:
--------------------------------------------------------------------------------
1 | framework module Pods_Codable {
2 | umbrella header "Pods-Codable-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/Codable/Pods/Target Support Files/Pods-Codable/Pods-Codable.release.xcconfig:
--------------------------------------------------------------------------------
1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire"
3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire/Alamofire.framework/Headers"
5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
6 | OTHER_LDFLAGS = $(inherited) -framework "Alamofire" -framework "CFNetwork"
7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
8 | PODS_BUILD_DIR = ${BUILD_DIR}
9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
11 | PODS_ROOT = ${SRCROOT}/Pods
12 |
--------------------------------------------------------------------------------
/CustomTransitions/CustomTransitions.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/CustomTransitions/CustomTransitions.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/CustomTransitions/CustomTransitions.xcodeproj/project.xcworkspace/xcuserdata/ahmedmasoud.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Masoud/Tutorials/5bbaf498957c7d8d6ba545cea930bceb515889ec/CustomTransitions/CustomTransitions.xcodeproj/project.xcworkspace/xcuserdata/ahmedmasoud.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/CustomTransitions/CustomTransitions.xcodeproj/xcuserdata/ahmedmasoud.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | CustomTransitions.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/CustomTransitions/CustomTransitions/Animator/StretchAnimator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // StretchAnimator.swift
3 | // CustomTransitions
4 | //
5 | // Created by Ahmed masoud on 3/27/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class StretchAnimator: NSObject {
12 | //MARK:- Properties
13 | private let duration = 0.8
14 | var presenting = true
15 | var originFrame = CGRect.zero
16 | }
17 |
18 | // MARK:- Transition Animation Delegate conformance
19 | extension StretchAnimator: UIViewControllerAnimatedTransitioning {
20 |
21 | func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
22 | return duration
23 | }
24 |
25 | func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
26 | let containerView = transitionContext.containerView
27 | let toView = transitionContext.view(forKey: .to)!
28 | let detailView = presenting ? toView : transitionContext.view(forKey: .from)!
29 | let initialFrame = presenting ? originFrame : detailView.frame
30 | let finalFrame = presenting ? detailView.frame : originFrame
31 |
32 | let xScaleFactor = presenting ?
33 | initialFrame.width / finalFrame.width :
34 | finalFrame.width / initialFrame.width
35 |
36 | let yScaleFactor = presenting ?
37 | initialFrame.height / finalFrame.height :
38 | finalFrame.height / initialFrame.height
39 |
40 | let scaleTransform = CGAffineTransform(scaleX: xScaleFactor, y: yScaleFactor)
41 |
42 | if presenting {
43 | detailView.transform = scaleTransform
44 | detailView.center = CGPoint(
45 | x: initialFrame.midX,
46 | y: initialFrame.midY)
47 | detailView.clipsToBounds = true
48 | }
49 |
50 | containerView.addSubview(toView)
51 | containerView.bringSubviewToFront(detailView)
52 |
53 | UIView.animate(
54 | withDuration: duration,
55 | delay:0.0,
56 | animations: { [weak self] in
57 | guard let self = self else { return }
58 | detailView.transform = self.presenting ? .identity : scaleTransform
59 | detailView.center = CGPoint(x: finalFrame.midX, y: finalFrame.midY)
60 | }, completion: { _ in
61 | transitionContext.completeTransition(true)
62 | })
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/CustomTransitions/CustomTransitions/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // CustomTransitions
4 | //
5 | // Created by Ahmed masoud on 3/27/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | @available(iOS 13.0, *)
24 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
25 | // Called when a new scene session is being created.
26 | // Use this method to select a configuration to create the new scene with.
27 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
28 | }
29 |
30 | @available(iOS 13.0, *)
31 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
32 | // Called when the user discards a scene session.
33 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
34 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
35 | }
36 |
37 |
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/CustomTransitions/CustomTransitions/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" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/CustomTransitions/CustomTransitions/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/CustomTransitions/CustomTransitions/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 |
--------------------------------------------------------------------------------
/CustomTransitions/CustomTransitions/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | $(PRODUCT_MODULE_NAME).SceneDelegate
36 | UISceneStoryboardFile
37 | Main
38 |
39 |
40 |
41 |
42 | UILaunchStoryboardName
43 | LaunchScreen
44 | UIMainStoryboardFile
45 | Main
46 | UIRequiredDeviceCapabilities
47 |
48 | armv7
49 |
50 | UISupportedInterfaceOrientations
51 |
52 | UIInterfaceOrientationPortrait
53 |
54 | UISupportedInterfaceOrientations~ipad
55 |
56 | UIInterfaceOrientationPortrait
57 | UIInterfaceOrientationPortraitUpsideDown
58 | UIInterfaceOrientationLandscapeLeft
59 | UIInterfaceOrientationLandscapeRight
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/CustomTransitions/CustomTransitions/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // CustomTransitions
4 | //
5 | // Created by Ahmed masoud on 3/27/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @available(iOS 13.0, *)
12 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
18 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
19 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
20 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
21 | guard let _ = (scene as? UIWindowScene) else { return }
22 | }
23 |
24 | func sceneDidDisconnect(_ scene: UIScene) {
25 | // Called as the scene is being released by the system.
26 | // This occurs shortly after the scene enters the background, or when its session is discarded.
27 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
28 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
29 | }
30 |
31 | func sceneDidBecomeActive(_ scene: UIScene) {
32 | // Called when the scene has moved from an inactive state to an active state.
33 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
34 | }
35 |
36 | func sceneWillResignActive(_ scene: UIScene) {
37 | // Called when the scene will move from an active state to an inactive state.
38 | // This may occur due to temporary interruptions (ex. an incoming phone call).
39 | }
40 |
41 | func sceneWillEnterForeground(_ scene: UIScene) {
42 | // Called as the scene transitions from the background to the foreground.
43 | // Use this method to undo the changes made on entering the background.
44 | }
45 |
46 | func sceneDidEnterBackground(_ scene: UIScene) {
47 | // Called as the scene transitions from the foreground to the background.
48 | // Use this method to save data, release shared resources, and store enough scene-specific state information
49 | // to restore the scene back to its current state.
50 | }
51 |
52 |
53 | }
54 |
55 |
--------------------------------------------------------------------------------
/CustomTransitions/CustomTransitions/Views/DetailVC.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DetailVC.swift
3 | // CustomTransitions
4 | //
5 | // Created by Ahmed masoud on 3/27/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | class DetailVC: UIViewController {
13 |
14 | override func viewDidLoad() {
15 | super.viewDidLoad()
16 | }
17 |
18 | class func create() -> DetailVC {
19 | let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "\(DetailVC.self)") as! DetailVC
20 | vc.modalPresentationStyle = .fullScreen
21 | return vc
22 | }
23 | @IBAction func dismissVC(_ sender: Any) {
24 | self.dismiss(animated: true, completion: nil)
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/CustomTransitions/CustomTransitions/Views/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // CustomTransitions
4 | //
5 | // Created by Ahmed masoud on 3/27/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController {
12 |
13 | //MARK:- Properties
14 | let transition = StretchAnimator()
15 | @IBOutlet weak var searchContainerView: UIView!
16 |
17 | //MARK:- LifeCycle
18 | override func viewDidLoad() {
19 | super.viewDidLoad()
20 | // Do any additional setup after loading the view.
21 | }
22 |
23 | //MARK:- Methods
24 | @IBAction func openDetailVC(_ sender: Any) {
25 | let vc = DetailVC.create()
26 | vc.transitioningDelegate = self
27 | self.present(vc, animated: true, completion: nil)
28 | }
29 |
30 | }
31 |
32 | //MARK:- Transition Delegate Conformance
33 | extension ViewController: UIViewControllerTransitioningDelegate {
34 | func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
35 | transition.originFrame = searchContainerView.frame
36 | transition.presenting = true
37 | return transition
38 | }
39 |
40 | func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
41 | transition.presenting = false
42 | return transition
43 | }
44 | }
45 |
46 |
--------------------------------------------------------------------------------
/DispatchGroups/DispatchGroups.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 |
3 |
4 |
5 | func heavyDuty(identifier: String, _ completion: @escaping ()->()) {
6 | var i = 0
7 | while i < 5000 {
8 | print("\(identifier) ======> \(i)")
9 | i+=1
10 | }
11 | completion()
12 | }
13 |
14 |
15 | let queue1 = DispatchQueue(label: "queue 1")
16 | let queue2 = DispatchQueue(label: "queue 2")
17 | let dispatchGroup = DispatchGroup()
18 |
19 | dispatchGroup.enter()
20 | queue1.async {
21 | heavyDuty(identifier: "call 1") {
22 | dispatchGroup.leave()
23 | }
24 | }
25 | dispatchGroup.enter()
26 | queue2.async {
27 | heavyDuty(identifier: "call 2") {
28 | dispatchGroup.leave()
29 | }
30 | }
31 |
32 | dispatchGroup.notify(queue: .main) {
33 | print("Done")
34 | }
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/DispatchGroups/DispatchGroups.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/DispatchGroups/DispatchGroups.playground/playground.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/DispatchGroups/DispatchGroups.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/DispatchGroups/DispatchGroups.playground/playground.xcworkspace/xcuserdata/ahmedmasoud.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Masoud/Tutorials/5bbaf498957c7d8d6ba545cea930bceb515889ec/DispatchGroups/DispatchGroups.playground/playground.xcworkspace/xcuserdata/ahmedmasoud.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/FacebookStoryAnimation/FacebookStoryAnnimation.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/FacebookStoryAnimation/FacebookStoryAnnimation.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/FacebookStoryAnimation/FacebookStoryAnnimation.xcodeproj/project.xcworkspace/xcuserdata/ahmedmasoud.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Masoud/Tutorials/5bbaf498957c7d8d6ba545cea930bceb515889ec/FacebookStoryAnimation/FacebookStoryAnnimation.xcodeproj/project.xcworkspace/xcuserdata/ahmedmasoud.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/FacebookStoryAnimation/FacebookStoryAnnimation.xcodeproj/xcuserdata/ahmedmasoud.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/FacebookStoryAnimation/FacebookStoryAnnimation.xcodeproj/xcuserdata/ahmedmasoud.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | FacebookStoryAnnimation.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/FacebookStoryAnimation/FacebookStoryAnnimation/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // FacebookStoryAnnimation
4 | //
5 | // Created by Ahmed masoud on 5/5/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
30 | // Called when the user discards a scene session.
31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/FacebookStoryAnimation/FacebookStoryAnnimation/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "scale" : "2x",
6 | "size" : "20x20"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "scale" : "3x",
11 | "size" : "20x20"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "scale" : "2x",
16 | "size" : "29x29"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "scale" : "3x",
21 | "size" : "29x29"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "scale" : "2x",
26 | "size" : "40x40"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "scale" : "3x",
31 | "size" : "40x40"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "scale" : "2x",
36 | "size" : "60x60"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "scale" : "3x",
41 | "size" : "60x60"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "scale" : "1x",
46 | "size" : "20x20"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "scale" : "2x",
51 | "size" : "20x20"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "scale" : "1x",
56 | "size" : "29x29"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "scale" : "2x",
61 | "size" : "29x29"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "scale" : "1x",
66 | "size" : "40x40"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "scale" : "2x",
71 | "size" : "40x40"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "scale" : "1x",
76 | "size" : "76x76"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "scale" : "2x",
81 | "size" : "76x76"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "scale" : "2x",
86 | "size" : "83.5x83.5"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "scale" : "1x",
91 | "size" : "1024x1024"
92 | }
93 | ],
94 | "info" : {
95 | "author" : "xcode",
96 | "version" : 1
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/FacebookStoryAnimation/FacebookStoryAnnimation/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/FacebookStoryAnimation/FacebookStoryAnnimation/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 |
--------------------------------------------------------------------------------
/FacebookStoryAnimation/FacebookStoryAnnimation/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | $(PRODUCT_MODULE_NAME).SceneDelegate
36 | UISceneStoryboardFile
37 | Main
38 |
39 |
40 |
41 |
42 | UILaunchStoryboardName
43 | LaunchScreen
44 | UIMainStoryboardFile
45 | Main
46 | UIRequiredDeviceCapabilities
47 |
48 | armv7
49 |
50 | UISupportedInterfaceOrientations
51 |
52 | UIInterfaceOrientationPortrait
53 | UIInterfaceOrientationLandscapeLeft
54 | UIInterfaceOrientationLandscapeRight
55 |
56 | UISupportedInterfaceOrientations~ipad
57 |
58 | UIInterfaceOrientationPortrait
59 | UIInterfaceOrientationPortraitUpsideDown
60 | UIInterfaceOrientationLandscapeLeft
61 | UIInterfaceOrientationLandscapeRight
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/FacebookStoryAnimation/FacebookStoryAnnimation/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // FacebookStoryAnnimation
4 | //
5 | // Created by Ahmed masoud on 5/5/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
12 |
13 | var window: UIWindow?
14 |
15 |
16 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
17 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
18 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
19 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
20 | guard let _ = (scene as? UIWindowScene) else { return }
21 | }
22 |
23 | func sceneDidDisconnect(_ scene: UIScene) {
24 | // Called as the scene is being released by the system.
25 | // This occurs shortly after the scene enters the background, or when its session is discarded.
26 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
27 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
28 | }
29 |
30 | func sceneDidBecomeActive(_ scene: UIScene) {
31 | // Called when the scene has moved from an inactive state to an active state.
32 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
33 | }
34 |
35 | func sceneWillResignActive(_ scene: UIScene) {
36 | // Called when the scene will move from an active state to an inactive state.
37 | // This may occur due to temporary interruptions (ex. an incoming phone call).
38 | }
39 |
40 | func sceneWillEnterForeground(_ scene: UIScene) {
41 | // Called as the scene transitions from the background to the foreground.
42 | // Use this method to undo the changes made on entering the background.
43 | }
44 |
45 | func sceneDidEnterBackground(_ scene: UIScene) {
46 | // Called as the scene transitions from the foreground to the background.
47 | // Use this method to save data, release shared resources, and store enough scene-specific state information
48 | // to restore the scene back to its current state.
49 | }
50 |
51 |
52 | }
53 |
54 |
--------------------------------------------------------------------------------
/LocalizationManager/LocalizationManager.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/LocalizationManager/LocalizationManager.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/LocalizationManager/LocalizationManager.xcodeproj/project.xcworkspace/xcuserdata/ahmedmasoud.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Masoud/Tutorials/5bbaf498957c7d8d6ba545cea930bceb515889ec/LocalizationManager/LocalizationManager.xcodeproj/project.xcworkspace/xcuserdata/ahmedmasoud.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/LocalizationManager/LocalizationManager.xcodeproj/xcuserdata/ahmedmasoud.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | LocalizationManager.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/LocalizationManager/LocalizationManager/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // LocalizationManager
4 | //
5 | // Created by Ahmed masoud on 8/10/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | LocalizationManager.shared.delegate = self
18 | LocalizationManager.shared.setAppInnitLanguage()
19 | return true
20 | }
21 |
22 |
23 | }
24 |
25 | extension AppDelegate: LocalizationDelegate {
26 | func resetApp() {
27 | guard let window = window else { return }
28 | let storyboard = UIStoryboard(name: "Main", bundle: nil)
29 | let vc = storyboard.instantiateViewController(identifier: "ViewController")
30 | window.rootViewController = vc
31 | let options: UIView.AnimationOptions = .transitionCrossDissolve
32 | let duration: TimeInterval = 0.3
33 | UIView.transition(with: window, duration: duration, options: options, animations: nil, completion: nil)
34 | }
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/LocalizationManager/LocalizationManager/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "scale" : "2x",
6 | "size" : "20x20"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "scale" : "3x",
11 | "size" : "20x20"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "scale" : "2x",
16 | "size" : "29x29"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "scale" : "3x",
21 | "size" : "29x29"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "scale" : "2x",
26 | "size" : "40x40"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "scale" : "3x",
31 | "size" : "40x40"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "scale" : "2x",
36 | "size" : "60x60"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "scale" : "3x",
41 | "size" : "60x60"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "scale" : "1x",
46 | "size" : "20x20"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "scale" : "2x",
51 | "size" : "20x20"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "scale" : "1x",
56 | "size" : "29x29"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "scale" : "2x",
61 | "size" : "29x29"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "scale" : "1x",
66 | "size" : "40x40"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "scale" : "2x",
71 | "size" : "40x40"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "scale" : "1x",
76 | "size" : "76x76"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "scale" : "2x",
81 | "size" : "76x76"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "scale" : "2x",
86 | "size" : "83.5x83.5"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "scale" : "1x",
91 | "size" : "1024x1024"
92 | }
93 | ],
94 | "info" : {
95 | "author" : "xcode",
96 | "version" : 1
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/LocalizationManager/LocalizationManager/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/LocalizationManager/LocalizationManager/Assets.xcassets/arrow.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "arrow.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/LocalizationManager/LocalizationManager/Assets.xcassets/arrow.imageset/arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Masoud/Tutorials/5bbaf498957c7d8d6ba545cea930bceb515889ec/LocalizationManager/LocalizationManager/Assets.xcassets/arrow.imageset/arrow.png
--------------------------------------------------------------------------------
/LocalizationManager/LocalizationManager/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 |
--------------------------------------------------------------------------------
/LocalizationManager/LocalizationManager/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | 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 |
--------------------------------------------------------------------------------
/LocalizationManager/LocalizationManager/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // LocalizationManager
4 | //
5 | // Created by Ahmed masoud on 8/10/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController {
12 |
13 | @IBOutlet weak var myLabel: UILabel!
14 | @IBOutlet weak var myImage: UIImageView!
15 |
16 | override func viewDidLoad() {
17 | super.viewDidLoad()
18 | myLabel.text = "Language Check".localized
19 | }
20 |
21 | override func viewDidLayoutSubviews() {
22 | super.viewDidLayoutSubviews()
23 | let image = UIImage(named: "arrow")?.imageFlippedForRightToLeftLayoutDirection()
24 | myImage.image = image
25 | }
26 |
27 | @IBAction func switchLanguage(_ sender: Any) {
28 | if LocalizationManager.shared.getLanguage() == .Arabic {
29 | LocalizationManager.shared.setLanguage(language: .English)
30 | } else {
31 | LocalizationManager.shared.setLanguage(language: .Arabic)
32 | }
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/LocalizationManager/LocalizationManager/ar.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 | LocalizationManager
4 |
5 | Created by Ahmed masoud on 8/10/20.
6 | Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | */
8 | "Language Check"="اختبار اللغه";
9 |
--------------------------------------------------------------------------------
/LocalizationManager/LocalizationManager/en.lproj/localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 | LocalizationManager
4 |
5 | Created by Ahmed masoud on 8/10/20.
6 | Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | */
8 | "Language Check" = "Language Check";
9 |
--------------------------------------------------------------------------------
/LoginAnimation/LoginAnimation.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/LoginAnimation/LoginAnimation.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/LoginAnimation/LoginAnimation.xcodeproj/project.xcworkspace/xcuserdata/ahmedmasoud.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Masoud/Tutorials/5bbaf498957c7d8d6ba545cea930bceb515889ec/LoginAnimation/LoginAnimation.xcodeproj/project.xcworkspace/xcuserdata/ahmedmasoud.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/LoginAnimation/LoginAnimation.xcodeproj/xcuserdata/ahmedmasoud.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/LoginAnimation/LoginAnimation.xcodeproj/xcuserdata/ahmedmasoud.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | LoginAnimation.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/LoginAnimation/LoginAnimation/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // LoginAnimation
4 | //
5 | // Created by Ahmed masoud on 4/11/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
30 | // Called when the user discards a scene session.
31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/LoginAnimation/LoginAnimation/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" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/LoginAnimation/LoginAnimation/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/LoginAnimation/LoginAnimation/Assets.xcassets/logo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "icon-4399622_960_720.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 | }
--------------------------------------------------------------------------------
/LoginAnimation/LoginAnimation/Assets.xcassets/logo.imageset/icon-4399622_960_720.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Masoud/Tutorials/5bbaf498957c7d8d6ba545cea930bceb515889ec/LoginAnimation/LoginAnimation/Assets.xcassets/logo.imageset/icon-4399622_960_720.png
--------------------------------------------------------------------------------
/LoginAnimation/LoginAnimation/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 |
--------------------------------------------------------------------------------
/LoginAnimation/LoginAnimation/ButtonsVC.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ButtonsVC.swift
3 | // LoginAnimation
4 | //
5 | // Created by Ahmed masoud on 4/12/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ButtonsVC: UIViewController {
12 |
13 | @IBOutlet weak var circleView: UIView!
14 |
15 | override func viewDidLoad() {
16 | super.viewDidLoad()
17 | circleView.layer.borderWidth = 2
18 | circleView.layer.borderColor = UIColor.red.cgColor
19 | circleView.backgroundColor = .red
20 | circleView.layer.cornerRadius = 30
21 | }
22 |
23 | @IBAction func tapACtion(_ sender: UIButton) {
24 | UIView.animate(withDuration: 0.5) {
25 | self.circleView.center.x = sender.center.x
26 | }
27 | }
28 |
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/LoginAnimation/LoginAnimation/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | $(PRODUCT_MODULE_NAME).SceneDelegate
36 | UISceneStoryboardFile
37 | Main
38 |
39 |
40 |
41 |
42 | UILaunchStoryboardName
43 | LaunchScreen
44 | UIMainStoryboardFile
45 | Main
46 | UIRequiredDeviceCapabilities
47 |
48 | armv7
49 |
50 | UISupportedInterfaceOrientations
51 |
52 | UIInterfaceOrientationPortrait
53 | UIInterfaceOrientationLandscapeLeft
54 | UIInterfaceOrientationLandscapeRight
55 |
56 | UISupportedInterfaceOrientations~ipad
57 |
58 | UIInterfaceOrientationPortrait
59 | UIInterfaceOrientationPortraitUpsideDown
60 | UIInterfaceOrientationLandscapeLeft
61 | UIInterfaceOrientationLandscapeRight
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/LoginAnimation/LoginAnimation/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // LoginAnimation
4 | //
5 | // Created by Ahmed masoud on 4/11/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
12 |
13 | var window: UIWindow?
14 |
15 |
16 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
17 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
18 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
19 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
20 | guard let _ = (scene as? UIWindowScene) else { return }
21 | }
22 |
23 | func sceneDidDisconnect(_ scene: UIScene) {
24 | // Called as the scene is being released by the system.
25 | // This occurs shortly after the scene enters the background, or when its session is discarded.
26 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
27 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
28 | }
29 |
30 | func sceneDidBecomeActive(_ scene: UIScene) {
31 | // Called when the scene has moved from an inactive state to an active state.
32 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
33 | }
34 |
35 | func sceneWillResignActive(_ scene: UIScene) {
36 | // Called when the scene will move from an active state to an inactive state.
37 | // This may occur due to temporary interruptions (ex. an incoming phone call).
38 | }
39 |
40 | func sceneWillEnterForeground(_ scene: UIScene) {
41 | // Called as the scene transitions from the background to the foreground.
42 | // Use this method to undo the changes made on entering the background.
43 | }
44 |
45 | func sceneDidEnterBackground(_ scene: UIScene) {
46 | // Called as the scene transitions from the foreground to the background.
47 | // Use this method to save data, release shared resources, and store enough scene-specific state information
48 | // to restore the scene back to its current state.
49 | }
50 |
51 |
52 | }
53 |
54 |
--------------------------------------------------------------------------------
/LoginAnimation/LoginAnimation/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // LoginAnimation
4 | //
5 | // Created by Ahmed masoud on 4/11/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController {
12 |
13 | @IBOutlet weak var imageView: UIImageView!
14 | @IBOutlet weak var userNameTextField: UITextField!
15 | @IBOutlet weak var passwordTextField: UITextField!
16 | @IBOutlet weak var loginButton: UIButton!
17 | @IBOutlet weak var loginButtonTopConstraint: NSLayoutConstraint!
18 | @IBOutlet weak var loadingSpinner: UIActivityIndicatorView!
19 |
20 | override func viewDidLoad() {
21 | super.viewDidLoad()
22 | loadingSpinner.isHidden = true
23 | hideViews()
24 | }
25 |
26 | override func viewDidAppear(_ animated: Bool) {
27 | super.viewDidAppear(animated)
28 | animateViews()
29 | }
30 |
31 |
32 | @IBAction func loginAction(_ sender: Any) {
33 | animateLogin()
34 | }
35 |
36 |
37 | func hideViews() {
38 | let scaleDownTransform = CGAffineTransform(scaleX: 0, y: 0)
39 | imageView.transform = scaleDownTransform
40 | let scaleLeftTransform = CGAffineTransform(translationX: -UIScreen.main.bounds.width, y: 0)
41 | userNameTextField.transform = scaleLeftTransform
42 | let scaleRightTransform = CGAffineTransform(translationX: UIScreen.main.bounds.width, y: 0)
43 | passwordTextField.transform = scaleRightTransform
44 |
45 | }
46 |
47 | func animateViews() {
48 | DispatchQueue.main.async {
49 | UIView.animate(withDuration: 0.2) {
50 | self.imageView.transform = .identity // CGAffineTransform(scaleX: 1, y: 1)
51 | self.userNameTextField.transform = .identity
52 | self.passwordTextField.transform = .identity
53 | }
54 | }
55 | }
56 |
57 | func animateLogin() {
58 | self.loginButtonTopConstraint.constant = 100
59 | UIView.animate(withDuration: 0.2, animations: {
60 | self.view.layoutIfNeeded()
61 | }) { (_) in
62 | self.loadingSpinner.isHidden = false
63 | self.loadingSpinner.startAnimating()
64 | }
65 | }
66 | }
67 |
68 |
--------------------------------------------------------------------------------
/NetworkLayer/NetworkLayer.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/NetworkLayer/NetworkLayer.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/NetworkLayer/NetworkLayer.xcodeproj/project.xcworkspace/xcuserdata/ahmedmasoud.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Masoud/Tutorials/5bbaf498957c7d8d6ba545cea930bceb515889ec/NetworkLayer/NetworkLayer.xcodeproj/project.xcworkspace/xcuserdata/ahmedmasoud.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/NetworkLayer/NetworkLayer.xcodeproj/xcuserdata/ahmedmasoud.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | NetworkLayer.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 2
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/NetworkLayer/NetworkLayer.xcodeproj/xcuserdata/fatema.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | NetworkLayer.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/NetworkLayer/NetworkLayer.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/NetworkLayer/NetworkLayer.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/NetworkLayer/NetworkLayer.xcworkspace/xcuserdata/ahmedmasoud.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Masoud/Tutorials/5bbaf498957c7d8d6ba545cea930bceb515889ec/NetworkLayer/NetworkLayer.xcworkspace/xcuserdata/ahmedmasoud.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/NetworkLayer/NetworkLayer.xcworkspace/xcuserdata/ahmedmasoud.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/NetworkLayer/NetworkLayer.xcworkspace/xcuserdata/fatema.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Masoud/Tutorials/5bbaf498957c7d8d6ba545cea930bceb515889ec/NetworkLayer/NetworkLayer.xcworkspace/xcuserdata/fatema.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/NetworkLayer/NetworkLayer/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // NetworkLayer
4 | //
5 | // Created by Ahmed masoud on 3/30/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
30 | // Called when the user discards a scene session.
31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/NetworkLayer/NetworkLayer/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" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/NetworkLayer/NetworkLayer/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/NetworkLayer/NetworkLayer/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 |
--------------------------------------------------------------------------------
/NetworkLayer/NetworkLayer/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 |
--------------------------------------------------------------------------------
/NetworkLayer/NetworkLayer/Constants.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Constants.swift
3 | // NetworkLayer
4 | //
5 | // Created by Ahmed masoud on 6/19/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | struct ErrorMessage {
13 | static let genericError = "Something went wrong please try again later"
14 | }
15 |
--------------------------------------------------------------------------------
/NetworkLayer/NetworkLayer/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSAppTransportSecurity
6 |
7 | NSAllowsArbitraryLoads
8 |
9 |
10 | CFBundleDevelopmentRegion
11 | $(DEVELOPMENT_LANGUAGE)
12 | CFBundleExecutable
13 | $(EXECUTABLE_NAME)
14 | CFBundleIdentifier
15 | $(PRODUCT_BUNDLE_IDENTIFIER)
16 | CFBundleInfoDictionaryVersion
17 | 6.0
18 | CFBundleName
19 | $(PRODUCT_NAME)
20 | CFBundlePackageType
21 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
22 | CFBundleShortVersionString
23 | 1.0
24 | CFBundleVersion
25 | 1
26 | LSRequiresIPhoneOS
27 |
28 | UIApplicationSceneManifest
29 |
30 | UIApplicationSupportsMultipleScenes
31 |
32 | UISceneConfigurations
33 |
34 | UIWindowSceneSessionRoleApplication
35 |
36 |
37 | UISceneConfigurationName
38 | Default Configuration
39 | UISceneDelegateClassName
40 | $(PRODUCT_MODULE_NAME).SceneDelegate
41 | UISceneStoryboardFile
42 | Main
43 |
44 |
45 |
46 |
47 | UILaunchStoryboardName
48 | LaunchScreen
49 | UIMainStoryboardFile
50 | Main
51 | UIRequiredDeviceCapabilities
52 |
53 | armv7
54 |
55 | UISupportedInterfaceOrientations
56 |
57 | UIInterfaceOrientationPortrait
58 | UIInterfaceOrientationLandscapeLeft
59 | UIInterfaceOrientationLandscapeRight
60 |
61 | UISupportedInterfaceOrientations~ipad
62 |
63 | UIInterfaceOrientationPortrait
64 | UIInterfaceOrientationPortraitUpsideDown
65 | UIInterfaceOrientationLandscapeLeft
66 | UIInterfaceOrientationLandscapeRight
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/NetworkLayer/NetworkLayer/Models/UserModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UserModel.swift
3 | // NetworkLayer
4 | //
5 | // Created by Ahmed masoud on 5/21/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class UserModel: Codable {
12 | var name: String?
13 | var salary: String?
14 |
15 | enum CodingKeys: String, CodingKey {
16 | case name = "employee_name"
17 | case salary = "employee_salary"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/NetworkLayer/NetworkLayer/Networkinng/Base/BaseAPI.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BaseAPI.swift
3 | // NetworkLayer
4 | //
5 | // Created by Ahmed masoud on 5/21/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Alamofire
11 |
12 | class BaseAPI {
13 |
14 | func fetchData(target: T, responseClass: M.Type, completion:@escaping (Result) -> Void) {
15 | let method = Alamofire.HTTPMethod(rawValue: target.method.rawValue)
16 | let headers = Alamofire.HTTPHeaders(target.headers ?? [:])
17 | let params = buildParams(task: target.task)
18 | AF.request(target.baseURL + target.path, method: method, parameters: params.0, encoding: params.1, headers: headers).responseJSON { (response) in
19 | guard let statusCode = response.response?.statusCode else {
20 | // ADD Custom Error
21 | let error = NSError(domain: target.baseURL, code: 0, userInfo: [NSLocalizedDescriptionKey: ErrorMessage.genericError])
22 | completion(.failure(error))
23 | return
24 | }
25 | if statusCode == 200 { // 200 reflect success response
26 | // Successful request
27 | guard let jsonResponse = try? response.result.get() else {
28 | // ADD Custom Error
29 | let error = NSError(domain: target.baseURL, code: 0, userInfo: [NSLocalizedDescriptionKey: ErrorMessage.genericError])
30 | completion(.failure(error))
31 | return
32 | }
33 | guard let theJSONData = try? JSONSerialization.data(withJSONObject: jsonResponse, options: []) else {
34 | // ADD Custom Error
35 | let error = NSError(domain: target.baseURL, code: 0, userInfo: [NSLocalizedDescriptionKey: ErrorMessage.genericError])
36 | completion(.failure(error))
37 | return
38 | }
39 | guard let responseObj = try? JSONDecoder().decode(M.self, from: theJSONData) else {
40 | // ADD Custom Error
41 | let error = NSError(domain: target.baseURL, code: 0, userInfo: [NSLocalizedDescriptionKey: ErrorMessage.genericError])
42 | completion(.failure(error))
43 | return
44 | }
45 | completion(.success(responseObj))
46 | } else {
47 | // ADD custom error base on status code 404 / 401 /
48 | // Error Parsing for the error message from the BE
49 | let message = "Error Message Parsed From BE"
50 | let error = NSError(domain: target.baseURL, code: statusCode, userInfo: [NSLocalizedDescriptionKey: message])
51 | completion(.failure(error))
52 | }
53 | }
54 | }
55 |
56 |
57 | private func buildParams(task: Task) -> ([String:Any], ParameterEncoding) {
58 | switch task {
59 | case .requestPlain:
60 | return ([:], URLEncoding.default)
61 | case .requestParameters(parameters: let parameters, encoding: let encoding):
62 | return (parameters, encoding)
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/NetworkLayer/NetworkLayer/Networkinng/Base/BaseResponse.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BaseResponse.swift
3 | // NetworkLayer
4 | //
5 | // Created by Ahmed masoud on 6/29/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | class BaseResponse: Codable {
13 | var status: String?
14 | var data: T?
15 |
16 | enum CodingKeys: String, CodingKey {
17 | case status = "status"
18 | case data = "data"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/NetworkLayer/NetworkLayer/Networkinng/Base/TargetType.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TargetType.swift
3 | // NetworkLayer
4 | //
5 | // Created by Ahmed masoud on 5/21/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Alamofire
11 |
12 | enum HTTPMethod: String {
13 | case get = "GET"
14 | case post = "POST"
15 | case put = "PUT"
16 | case delete = "DELETE"
17 | }
18 |
19 | enum Task {
20 |
21 | /// A request with no additional data.
22 | case requestPlain
23 |
24 | /// A requests body set with encoded parameters.
25 | case requestParameters(parameters: [String: Any], encoding: ParameterEncoding)
26 | }
27 |
28 | protocol TargetType {
29 |
30 | /// The target's base `URL`.
31 | var baseURL: String { get }
32 |
33 | /// The path to be appended to `baseURL` to form the full `URL`.
34 | var path: String { get }
35 |
36 | /// The HTTP method used in the request.
37 | var method: HTTPMethod { get }
38 |
39 | /// The type of HTTP task to be performed.
40 | var task: Task { get }
41 |
42 | /// The headers to be used in the request.
43 | var headers: [String: String]? { get }
44 | }
45 |
--------------------------------------------------------------------------------
/NetworkLayer/NetworkLayer/Networkinng/Users/UsersAPI.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UsersAPI.swift
3 | // NetworkLayer
4 | //
5 | // Created by Ahmed masoud on 5/21/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | protocol UsersAPIProtocol {
12 | func getUsers(completion: @escaping (Result?, NSError>) -> Void)
13 | }
14 |
15 |
16 | class UsersAPI: BaseAPI, UsersAPIProtocol {
17 |
18 | //MARK:- Requests
19 |
20 | func getUsers(completion: @escaping (Result?, NSError>) -> Void) {
21 | self.fetchData(target: .getUsers, responseClass: BaseResponse<[UserModel]>.self) { (result) in
22 | completion(result)
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/NetworkLayer/NetworkLayer/Networkinng/Users/UsersNetworking.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UsersNetworking.swift
3 | // NetworkLayer
4 | //
5 | // Created by Ahmed masoud on 5/21/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Alamofire
11 |
12 | enum UsersNetworking {
13 | case getUsers
14 | case createUser(name: String, job: String)
15 | }
16 |
17 | extension UsersNetworking: TargetType {
18 | var baseURL: String {
19 | switch self {
20 | case .getUsers:
21 | return "http://dummy.restapiexample.com/api/v1"
22 | default:
23 | return "https://reqres.in/api"
24 | }
25 | }
26 |
27 | var path: String {
28 | switch self {
29 | case .getUsers:
30 | return "/employees"
31 | case .createUser:
32 | return "/users"
33 | }
34 | }
35 |
36 | var method: HTTPMethod {
37 | switch self {
38 | case .getUsers:
39 | return .get
40 | case .createUser:
41 | return .post
42 | }
43 | }
44 |
45 | var task: Task {
46 | switch self {
47 | case .getUsers:
48 | return .requestPlain
49 | case .createUser(let name, let job):
50 | return .requestParameters(parameters: ["name": name, "job": job], encoding: JSONEncoding.default)
51 | }
52 | }
53 |
54 | var headers: [String : String]? {
55 | switch self {
56 | default:
57 | return [:]
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/NetworkLayer/NetworkLayer/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // NetworkLayer
4 | //
5 | // Created by Ahmed masoud on 3/30/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
12 |
13 | var window: UIWindow?
14 |
15 |
16 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
17 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
18 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
19 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
20 | guard let _ = (scene as? UIWindowScene) else { return }
21 | }
22 |
23 | func sceneDidDisconnect(_ scene: UIScene) {
24 | // Called as the scene is being released by the system.
25 | // This occurs shortly after the scene enters the background, or when its session is discarded.
26 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
27 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
28 | }
29 |
30 | func sceneDidBecomeActive(_ scene: UIScene) {
31 | // Called when the scene has moved from an inactive state to an active state.
32 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
33 | }
34 |
35 | func sceneWillResignActive(_ scene: UIScene) {
36 | // Called when the scene will move from an active state to an inactive state.
37 | // This may occur due to temporary interruptions (ex. an incoming phone call).
38 | }
39 |
40 | func sceneWillEnterForeground(_ scene: UIScene) {
41 | // Called as the scene transitions from the background to the foreground.
42 | // Use this method to undo the changes made on entering the background.
43 | }
44 |
45 | func sceneDidEnterBackground(_ scene: UIScene) {
46 | // Called as the scene transitions from the foreground to the background.
47 | // Use this method to save data, release shared resources, and store enough scene-specific state information
48 | // to restore the scene back to its current state.
49 | }
50 |
51 |
52 | }
53 |
54 |
--------------------------------------------------------------------------------
/NetworkLayer/NetworkLayer/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // NetworkLayer
4 | //
5 | // Created by Ahmed masoud on 3/30/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 | let api: UsersAPIProtocol = UsersAPI()
16 | api.getUsers { (result) in
17 | switch result {
18 | case .success(let response):
19 | let users = response?.data
20 | for user in users ?? [] {
21 | print("\(user.name ?? "") => \(user.salary ?? "")")
22 | }
23 | case .failure(let error):
24 | print(error.userInfo[NSLocalizedDescriptionKey] as? String ?? "")
25 | }
26 | }
27 | }
28 |
29 |
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/NetworkLayer/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment the next line to define a global platform for your project
2 | # platform :ios, '9.0'
3 |
4 | target 'NetworkLayer' do
5 | # Comment the next line if you don't want to use dynamic frameworks
6 | use_frameworks!
7 |
8 | # Pods for NetworkLayer
9 | pod 'Alamofire'
10 | end
11 |
--------------------------------------------------------------------------------
/NetworkLayer/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - Alamofire (5.0.2)
3 |
4 | DEPENDENCIES:
5 | - Alamofire
6 |
7 | SPEC REPOS:
8 | https://github.com/cocoapods/specs.git:
9 | - Alamofire
10 |
11 | SPEC CHECKSUMS:
12 | Alamofire: 3ba7a4db18b4f62c4a1c0e1cb39d7f3d52e10ada
13 |
14 | PODFILE CHECKSUM: c259b15ca909ebe147df21b3c1eee974fe39c59b
15 |
16 | COCOAPODS: 1.7.5
17 |
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Alamofire/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2014-2020 Alamofire Software Foundation (http://alamofire.org/)
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Alamofire/Source/Alamofire.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Alamofire.swift
3 | //
4 | // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/)
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 | //
24 |
25 | /// Reference to `Session.default` for quick bootstrapping and examples.
26 | public let AF = Session.default
27 |
28 | /// Current Alamofire version. Necessary since SPM doesn't use dynamic libraries. Plus this will be more accurate.
29 | let version = "5.0.2"
30 |
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Alamofire/Source/AlamofireExtended.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AlamofireExtended.swift
3 | //
4 | // Copyright (c) 2019 Alamofire Software Foundation (http://alamofire.org/)
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 | //
24 |
25 | /// Type that acts as a generic extension point for all `AlamofireExtended` types.
26 | public struct AlamofireExtension {
27 | /// Stores the type or meta-type of any extended type.
28 | public private(set) var type: ExtendedType
29 |
30 | /// Create an instance from the provided value.
31 | ///
32 | /// - Parameter type: Instance being extended.
33 | public init(_ type: ExtendedType) {
34 | self.type = type
35 | }
36 | }
37 |
38 | /// Protocol describing the `af` extension points for Alamofire extended types.
39 | public protocol AlamofireExtended {
40 | /// Type being extended.
41 | associatedtype ExtendedType
42 |
43 | /// Static Alamofire extension point.
44 | static var af: AlamofireExtension.Type { get set }
45 | /// Instance Alamofire extension point.
46 | var af: AlamofireExtension { get set }
47 | }
48 |
49 | public extension AlamofireExtended {
50 | /// Static Alamofire extension point.
51 | static var af: AlamofireExtension.Type {
52 | get { return AlamofireExtension.self }
53 | set {}
54 | }
55 |
56 | /// Instance Alamofire extension point.
57 | var af: AlamofireExtension {
58 | get { return AlamofireExtension(self) }
59 | set {}
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Alamofire/Source/DispatchQueue+Alamofire.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DispatchQueue+Alamofire.swift
3 | //
4 | // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/)
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 | //
24 |
25 | import Dispatch
26 | import Foundation
27 |
28 | extension DispatchQueue {
29 | /// Execute the provided closure after a `TimeInterval`.
30 | ///
31 | /// - Parameters:
32 | /// - delay: `TimeInterval` to delay execution.
33 | /// - closure: Closure to execute.
34 | func after(_ delay: TimeInterval, execute closure: @escaping () -> Void) {
35 | asyncAfter(deadline: .now() + delay, execute: closure)
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Alamofire/Source/HTTPMethod.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HTTPMethod.swift
3 | //
4 | // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/)
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 | //
24 |
25 | /// Type representing HTTP methods. Raw `String` value is stored and compared case-sensitively, so
26 | /// `HTTPMethod.get != HTTPMethod(rawValue: "get")`.
27 | ///
28 | /// See https://tools.ietf.org/html/rfc7231#section-4.3
29 | public struct HTTPMethod: RawRepresentable, Equatable, Hashable {
30 | /// `CONNECT` method.
31 | public static let connect = HTTPMethod(rawValue: "CONNECT")
32 | /// `DELETE` method.
33 | public static let delete = HTTPMethod(rawValue: "DELETE")
34 | /// `GET` method.
35 | public static let get = HTTPMethod(rawValue: "GET")
36 | /// `HEAD` method.
37 | public static let head = HTTPMethod(rawValue: "HEAD")
38 | /// `OPTIONS` method.
39 | public static let options = HTTPMethod(rawValue: "OPTIONS")
40 | /// `PATCH` method.
41 | public static let patch = HTTPMethod(rawValue: "PATCH")
42 | /// `POST` method.
43 | public static let post = HTTPMethod(rawValue: "POST")
44 | /// `PUT` method.
45 | public static let put = HTTPMethod(rawValue: "PUT")
46 | /// `TRACE` method.
47 | public static let trace = HTTPMethod(rawValue: "TRACE")
48 |
49 | public let rawValue: String
50 |
51 | public init(rawValue: String) {
52 | self.rawValue = rawValue
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Alamofire/Source/OperationQueue+Alamofire.swift:
--------------------------------------------------------------------------------
1 | //
2 | // OperationQueue+Alamofire.swift
3 | //
4 | // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/)
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 | //
24 |
25 | import Foundation
26 |
27 | extension OperationQueue {
28 | /// Creates an instance using the provided parameters.
29 | ///
30 | /// - Parameters:
31 | /// - qualityOfService: `QualityOfService` to be applied to the queue. `.default` by default.
32 | /// - maxConcurrentOperationCount: Maximum concurrent operations.
33 | /// `OperationQueue.defaultMaxConcurrentOperationCount` by default.
34 | /// - underlyingQueue: Underlying `DispatchQueue`. `nil` by default.
35 | /// - name: Name for the queue. `nil` by default.
36 | /// - startSuspended: Whether the queue starts suspended. `false` by default.
37 | convenience init(qualityOfService: QualityOfService = .default,
38 | maxConcurrentOperationCount: Int = OperationQueue.defaultMaxConcurrentOperationCount,
39 | underlyingQueue: DispatchQueue? = nil,
40 | name: String? = nil,
41 | startSuspended: Bool = false) {
42 | self.init()
43 | self.qualityOfService = qualityOfService
44 | self.maxConcurrentOperationCount = maxConcurrentOperationCount
45 | self.underlyingQueue = underlyingQueue
46 | self.name = name
47 | isSuspended = startSuspended
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Alamofire/Source/URLRequest+Alamofire.swift:
--------------------------------------------------------------------------------
1 | //
2 | // URLRequest+Alamofire.swift
3 | //
4 | // Copyright (c) 2019 Alamofire Software Foundation (http://alamofire.org/)
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 | //
24 |
25 | import Foundation
26 |
27 | public extension URLRequest {
28 | /// Returns the `httpMethod` as Alamofire's `HTTPMethod` type.
29 | var method: HTTPMethod? {
30 | get { return httpMethod.flatMap(HTTPMethod.init) }
31 | set { httpMethod = newValue?.rawValue }
32 | }
33 |
34 | func validate() throws {
35 | if method == .get, let bodyData = httpBody {
36 | throw AFError.urlRequestValidationFailed(reason: .bodyDataInGETRequest(bodyData))
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Alamofire/Source/URLSessionConfiguration+Alamofire.swift:
--------------------------------------------------------------------------------
1 | //
2 | // URLSessionConfiguration+Alamofire.swift
3 | //
4 | // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/)
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 | //
24 |
25 | import Foundation
26 |
27 | extension URLSessionConfiguration: AlamofireExtended {}
28 | extension AlamofireExtension where ExtendedType: URLSessionConfiguration {
29 | /// Alamofire's default configuration. Same as `URLSessionConfiguration.default` but adds Alamofire default
30 | /// `Accept-Language`, `Accept-Encoding`, and `User-Agent` headers.
31 | public static var `default`: URLSessionConfiguration {
32 | let configuration = URLSessionConfiguration.default
33 | configuration.headers = .default
34 |
35 | return configuration
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Manifest.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - Alamofire (5.0.2)
3 |
4 | DEPENDENCIES:
5 | - Alamofire
6 |
7 | SPEC REPOS:
8 | https://github.com/cocoapods/specs.git:
9 | - Alamofire
10 |
11 | SPEC CHECKSUMS:
12 | Alamofire: 3ba7a4db18b4f62c4a1c0e1cb39d7f3d52e10ada
13 |
14 | PODFILE CHECKSUM: c259b15ca909ebe147df21b3c1eee974fe39c59b
15 |
16 | COCOAPODS: 1.7.5
17 |
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Pods.xcodeproj/xcuserdata/ahmedmasoud.xcuserdatad/xcschemes/Alamofire.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
45 |
46 |
52 |
53 |
55 |
56 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Pods.xcodeproj/xcuserdata/ahmedmasoud.xcuserdatad/xcschemes/Pods-NetworkLayer.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
50 |
51 |
53 |
54 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Pods.xcodeproj/xcuserdata/ahmedmasoud.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | Alamofire.xcscheme
8 |
9 | isShown
10 |
11 | orderHint
12 | 0
13 |
14 | Pods-NetworkLayer.xcscheme
15 |
16 | isShown
17 |
18 | orderHint
19 | 1
20 |
21 |
22 | SuppressBuildableAutocreation
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Pods.xcodeproj/xcuserdata/fatema.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | Alamofire.xcscheme
8 |
9 | orderHint
10 | 1
11 |
12 | Pods-NetworkLayer.xcscheme
13 |
14 | orderHint
15 | 2
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Target Support Files/Alamofire/Alamofire-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 | 5.0.2
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Target Support Files/Alamofire/Alamofire-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Alamofire : NSObject
3 | @end
4 | @implementation PodsDummy_Alamofire
5 | @end
6 |
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Target Support Files/Alamofire/Alamofire-prefix.pch:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Target Support Files/Alamofire/Alamofire-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
14 | FOUNDATION_EXPORT double AlamofireVersionNumber;
15 | FOUNDATION_EXPORT const unsigned char AlamofireVersionString[];
16 |
17 |
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Target Support Files/Alamofire/Alamofire.modulemap:
--------------------------------------------------------------------------------
1 | framework module Alamofire {
2 | umbrella header "Alamofire-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Target Support Files/Alamofire/Alamofire.xcconfig:
--------------------------------------------------------------------------------
1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Alamofire
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | OTHER_LDFLAGS = $(inherited) -framework "CFNetwork"
4 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
5 | PODS_BUILD_DIR = ${BUILD_DIR}
6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
7 | PODS_ROOT = ${SRCROOT}
8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/Alamofire
9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
10 | SKIP_INSTALL = YES
11 |
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Target Support Files/Pods-NetworkLayer/Pods-NetworkLayer-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 | 1.0.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Target Support Files/Pods-NetworkLayer/Pods-NetworkLayer-acknowledgements.markdown:
--------------------------------------------------------------------------------
1 | # Acknowledgements
2 | This application makes use of the following third party libraries:
3 |
4 | ## Alamofire
5 |
6 | Copyright (c) 2014-2020 Alamofire Software Foundation (http://alamofire.org/)
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining a copy
9 | of this software and associated documentation files (the "Software"), to deal
10 | in the Software without restriction, including without limitation the rights
11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | copies of the Software, and to permit persons to whom the Software is
13 | furnished to do so, subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be included in
16 | all copies or substantial portions of the Software.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 | THE SOFTWARE.
25 |
26 | Generated by CocoaPods - https://cocoapods.org
27 |
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Target Support Files/Pods-NetworkLayer/Pods-NetworkLayer-acknowledgements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreferenceSpecifiers
6 |
7 |
8 | FooterText
9 | This application makes use of the following third party libraries:
10 | Title
11 | Acknowledgements
12 | Type
13 | PSGroupSpecifier
14 |
15 |
16 | FooterText
17 | Copyright (c) 2014-2020 Alamofire Software Foundation (http://alamofire.org/)
18 |
19 | Permission is hereby granted, free of charge, to any person obtaining a copy
20 | of this software and associated documentation files (the "Software"), to deal
21 | in the Software without restriction, including without limitation the rights
22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
23 | copies of the Software, and to permit persons to whom the Software is
24 | furnished to do so, subject to the following conditions:
25 |
26 | The above copyright notice and this permission notice shall be included in
27 | all copies or substantial portions of the Software.
28 |
29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
35 | THE SOFTWARE.
36 |
37 | License
38 | MIT
39 | Title
40 | Alamofire
41 | Type
42 | PSGroupSpecifier
43 |
44 |
45 | FooterText
46 | Generated by CocoaPods - https://cocoapods.org
47 | Title
48 |
49 | Type
50 | PSGroupSpecifier
51 |
52 |
53 | StringsTable
54 | Acknowledgements
55 | Title
56 | Acknowledgements
57 |
58 |
59 |
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Target Support Files/Pods-NetworkLayer/Pods-NetworkLayer-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Pods_NetworkLayer : NSObject
3 | @end
4 | @implementation PodsDummy_Pods_NetworkLayer
5 | @end
6 |
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Target Support Files/Pods-NetworkLayer/Pods-NetworkLayer-frameworks-Debug-input-files.xcfilelist:
--------------------------------------------------------------------------------
1 | ${PODS_ROOT}/Target Support Files/Pods-NetworkLayer/Pods-NetworkLayer-frameworks.sh
2 | ${BUILT_PRODUCTS_DIR}/Alamofire/Alamofire.framework
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Target Support Files/Pods-NetworkLayer/Pods-NetworkLayer-frameworks-Debug-output-files.xcfilelist:
--------------------------------------------------------------------------------
1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Alamofire.framework
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Target Support Files/Pods-NetworkLayer/Pods-NetworkLayer-frameworks-Release-input-files.xcfilelist:
--------------------------------------------------------------------------------
1 | ${PODS_ROOT}/Target Support Files/Pods-NetworkLayer/Pods-NetworkLayer-frameworks.sh
2 | ${BUILT_PRODUCTS_DIR}/Alamofire/Alamofire.framework
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Target Support Files/Pods-NetworkLayer/Pods-NetworkLayer-frameworks-Release-output-files.xcfilelist:
--------------------------------------------------------------------------------
1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Alamofire.framework
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Target Support Files/Pods-NetworkLayer/Pods-NetworkLayer-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
14 | FOUNDATION_EXPORT double Pods_NetworkLayerVersionNumber;
15 | FOUNDATION_EXPORT const unsigned char Pods_NetworkLayerVersionString[];
16 |
17 |
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Target Support Files/Pods-NetworkLayer/Pods-NetworkLayer.debug.xcconfig:
--------------------------------------------------------------------------------
1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire"
3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire/Alamofire.framework/Headers"
5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
6 | OTHER_LDFLAGS = $(inherited) -framework "Alamofire" -framework "CFNetwork"
7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
8 | PODS_BUILD_DIR = ${BUILD_DIR}
9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
11 | PODS_ROOT = ${SRCROOT}/Pods
12 |
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Target Support Files/Pods-NetworkLayer/Pods-NetworkLayer.modulemap:
--------------------------------------------------------------------------------
1 | framework module Pods_NetworkLayer {
2 | umbrella header "Pods-NetworkLayer-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/NetworkLayer/Pods/Target Support Files/Pods-NetworkLayer/Pods-NetworkLayer.release.xcconfig:
--------------------------------------------------------------------------------
1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire"
3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire/Alamofire.framework/Headers"
5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
6 | OTHER_LDFLAGS = $(inherited) -framework "Alamofire" -framework "CFNetwork"
7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
8 | PODS_BUILD_DIR = ${BUILD_DIR}
9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
11 | PODS_ROOT = ${SRCROOT}/Pods
12 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Tutorials
2 | This repo will contain source codes for my tutorials on my youtube channel
3 | check it out: https://www.youtube.com/user/Iphone284
4 |
--------------------------------------------------------------------------------
/StretchyTableHeader/StretchyTableHeader.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/StretchyTableHeader/StretchyTableHeader.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/StretchyTableHeader/StretchyTableHeader.xcodeproj/project.xcworkspace/xcuserdata/ahmedmasoud.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Masoud/Tutorials/5bbaf498957c7d8d6ba545cea930bceb515889ec/StretchyTableHeader/StretchyTableHeader.xcodeproj/project.xcworkspace/xcuserdata/ahmedmasoud.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/StretchyTableHeader/StretchyTableHeader.xcodeproj/xcuserdata/ahmedmasoud.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | StretchyTableHeader.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/StretchyTableHeader/StretchyTableHeader/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // StretchyTableHeader
4 | //
5 | // Created by Ahmed masoud on 5/3/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
30 | // Called when the user discards a scene session.
31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/StretchyTableHeader/StretchyTableHeader/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "scale" : "2x",
6 | "size" : "20x20"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "scale" : "3x",
11 | "size" : "20x20"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "scale" : "2x",
16 | "size" : "29x29"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "scale" : "3x",
21 | "size" : "29x29"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "scale" : "2x",
26 | "size" : "40x40"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "scale" : "3x",
31 | "size" : "40x40"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "scale" : "2x",
36 | "size" : "60x60"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "scale" : "3x",
41 | "size" : "60x60"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "scale" : "1x",
46 | "size" : "20x20"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "scale" : "2x",
51 | "size" : "20x20"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "scale" : "1x",
56 | "size" : "29x29"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "scale" : "2x",
61 | "size" : "29x29"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "scale" : "1x",
66 | "size" : "40x40"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "scale" : "2x",
71 | "size" : "40x40"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "scale" : "1x",
76 | "size" : "76x76"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "scale" : "2x",
81 | "size" : "76x76"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "scale" : "2x",
86 | "size" : "83.5x83.5"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "scale" : "1x",
91 | "size" : "1024x1024"
92 | }
93 | ],
94 | "info" : {
95 | "author" : "xcode",
96 | "version" : 1
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/StretchyTableHeader/StretchyTableHeader/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/StretchyTableHeader/StretchyTableHeader/Assets.xcassets/header.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "header.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/StretchyTableHeader/StretchyTableHeader/Assets.xcassets/header.imageset/header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Masoud/Tutorials/5bbaf498957c7d8d6ba545cea930bceb515889ec/StretchyTableHeader/StretchyTableHeader/Assets.xcassets/header.imageset/header.png
--------------------------------------------------------------------------------
/StretchyTableHeader/StretchyTableHeader/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 |
--------------------------------------------------------------------------------
/StretchyTableHeader/StretchyTableHeader/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | $(PRODUCT_MODULE_NAME).SceneDelegate
36 | UISceneStoryboardFile
37 | Main
38 |
39 |
40 |
41 |
42 | UILaunchStoryboardName
43 | LaunchScreen
44 | UIMainStoryboardFile
45 | Main
46 | UIRequiredDeviceCapabilities
47 |
48 | armv7
49 |
50 | UISupportedInterfaceOrientations
51 |
52 | UIInterfaceOrientationPortrait
53 |
54 | UISupportedInterfaceOrientations~ipad
55 |
56 | UIInterfaceOrientationPortrait
57 | UIInterfaceOrientationPortraitUpsideDown
58 | UIInterfaceOrientationLandscapeLeft
59 | UIInterfaceOrientationLandscapeRight
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/StretchyTableHeader/StretchyTableHeader/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // StretchyTableHeader
4 | //
5 | // Created by Ahmed masoud on 5/3/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
12 |
13 | var window: UIWindow?
14 |
15 |
16 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
17 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
18 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
19 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
20 | guard let _ = (scene as? UIWindowScene) else { return }
21 | }
22 |
23 | func sceneDidDisconnect(_ scene: UIScene) {
24 | // Called as the scene is being released by the system.
25 | // This occurs shortly after the scene enters the background, or when its session is discarded.
26 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
27 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
28 | }
29 |
30 | func sceneDidBecomeActive(_ scene: UIScene) {
31 | // Called when the scene has moved from an inactive state to an active state.
32 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
33 | }
34 |
35 | func sceneWillResignActive(_ scene: UIScene) {
36 | // Called when the scene will move from an active state to an inactive state.
37 | // This may occur due to temporary interruptions (ex. an incoming phone call).
38 | }
39 |
40 | func sceneWillEnterForeground(_ scene: UIScene) {
41 | // Called as the scene transitions from the background to the foreground.
42 | // Use this method to undo the changes made on entering the background.
43 | }
44 |
45 | func sceneDidEnterBackground(_ scene: UIScene) {
46 | // Called as the scene transitions from the foreground to the background.
47 | // Use this method to save data, release shared resources, and store enough scene-specific state information
48 | // to restore the scene back to its current state.
49 | }
50 |
51 |
52 | }
53 |
54 |
--------------------------------------------------------------------------------
/StretchyTableHeader/StretchyTableHeader/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // StretchyTableHeader
4 | //
5 | // Created by Ahmed masoud on 5/3/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
12 |
13 | @IBOutlet weak var myTable: UITableView!
14 | var headerView: UIView!
15 | let headerHeight: CGFloat = 250
16 |
17 | override func viewDidLoad() {
18 | super.viewDidLoad()
19 | headerView = myTable.tableHeaderView
20 | myTable.tableHeaderView = nil
21 | myTable.addSubview(headerView)
22 | myTable.contentInset = UIEdgeInsets(top: headerHeight, left: 0, bottom: 0, right: 0)
23 | myTable.contentOffset = CGPoint(x: 0, y: -headerHeight)
24 | updateHeader()
25 | }
26 |
27 | func updateHeader() {
28 | print(myTable.contentOffset.y)
29 | if myTable.contentOffset.y < -headerHeight {
30 | headerView.frame.origin.y = myTable.contentOffset.y
31 | headerView.frame.size.height = -myTable.contentOffset.y
32 | }
33 | }
34 |
35 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
36 | return 20
37 | }
38 |
39 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
40 | let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath)
41 | cell.textLabel?.text = "[\(indexPath.section),\(indexPath.row)]"
42 | return cell
43 | }
44 |
45 | func scrollViewDidScroll(_ scrollView: UIScrollView) {
46 | updateHeader()
47 | }
48 | }
49 |
50 |
--------------------------------------------------------------------------------
/ToastManager/ToastManager.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ToastManager/ToastManager.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ToastManager/ToastManager.xcodeproj/project.xcworkspace/xcuserdata/ahmedmasoud.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Masoud/Tutorials/5bbaf498957c7d8d6ba545cea930bceb515889ec/ToastManager/ToastManager.xcodeproj/project.xcworkspace/xcuserdata/ahmedmasoud.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/ToastManager/ToastManager.xcodeproj/xcuserdata/ahmedmasoud.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | ToastManager.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/ToastManager/ToastManager/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // ToastManager
4 | //
5 | // Created by Ahmed masoud on 4/3/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | KeyboardStateManager.shared.start()
19 | return true
20 | }
21 |
22 | // MARK: UISceneSession Lifecycle
23 |
24 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
25 | // Called when a new scene session is being created.
26 | // Use this method to select a configuration to create the new scene with.
27 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
28 | }
29 |
30 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
31 | // Called when the user discards a scene session.
32 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
33 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
34 | }
35 |
36 |
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/ToastManager/ToastManager/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" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/ToastManager/ToastManager/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/ToastManager/ToastManager/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 |
--------------------------------------------------------------------------------
/ToastManager/ToastManager/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | $(PRODUCT_MODULE_NAME).SceneDelegate
36 | UISceneStoryboardFile
37 | Main
38 |
39 |
40 |
41 |
42 | UILaunchStoryboardName
43 | LaunchScreen
44 | UIMainStoryboardFile
45 | Main
46 | UIRequiredDeviceCapabilities
47 |
48 | armv7
49 |
50 | UISupportedInterfaceOrientations
51 |
52 | UIInterfaceOrientationPortrait
53 | UIInterfaceOrientationLandscapeLeft
54 | UIInterfaceOrientationLandscapeRight
55 |
56 | UISupportedInterfaceOrientations~ipad
57 |
58 | UIInterfaceOrientationPortrait
59 | UIInterfaceOrientationPortraitUpsideDown
60 | UIInterfaceOrientationLandscapeLeft
61 | UIInterfaceOrientationLandscapeRight
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/ToastManager/ToastManager/Managers/KeyboardStateManager.swift:
--------------------------------------------------------------------------------
1 | //
2 | // KeyboardStateManager.swift
3 | // ToastManager
4 | //
5 | // Created by Ahmed masoud on 4/3/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | class KeyboardStateManager {
13 |
14 | static let shared = KeyboardStateManager()
15 |
16 | var isVisible = false
17 | var keyboardOffset: CGFloat = 0
18 |
19 | func start() {
20 | NotificationCenter.default.addObserver(self, selector: #selector(handleShow),
21 | name: UIResponder.keyboardWillShowNotification, object: nil)
22 | NotificationCenter.default.addObserver(self, selector: #selector(handleHide),
23 | name: UIResponder.keyboardWillHideNotification, object: nil)
24 | }
25 |
26 | @objc func handleShow(_ notification: Notification) {
27 | isVisible = true
28 | if let keyboardFrame: NSValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
29 | let keyboardRectangle = keyboardFrame.cgRectValue
30 | keyboardOffset = keyboardRectangle.height
31 | }
32 | }
33 |
34 | @objc func handleHide()
35 | {
36 | isVisible = false
37 | }
38 |
39 | func stop() {
40 | NotificationCenter.default.removeObserver(self)
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/ToastManager/ToastManager/Managers/ToastManager.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ToastManager.swift
3 | // ToastManager
4 | //
5 | // Created by Ahmed masoud on 4/3/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | class ToastManager {
13 | //MARK: Properties
14 | static let shared = ToastManager()
15 | private var view: UIView = UIView()
16 | private var message: String = ""
17 | private var bottomAnchor: NSLayoutConstraint!
18 | private var errorHeaders: [ToastView?] = []
19 |
20 | //MARK: Methods
21 | private init() {}
22 |
23 | func showError(message: String, view: UIView) {
24 | let errorHeader: ToastView? = ToastView()
25 | errorHeaders.forEach({
26 | hideBanner(errorHeader: $0)
27 | })
28 | errorHeaders.append(errorHeader)
29 | self.view = view
30 | self.message = message
31 | createBannerWithInitialPosition(errorHeader: errorHeader)
32 | DispatchQueue.main.asyncAfter(deadline: .now() + 3) { [weak self] in
33 | self?.hideBanner(errorHeader: errorHeader)
34 | }
35 | }
36 |
37 | private func createBannerWithInitialPosition(errorHeader: ToastView?) {
38 | guard let errorHeader = errorHeader else { return }
39 | errorHeader.errorLabel.text = message
40 | errorHeader.layer.cornerRadius = 10
41 | errorHeader.layer.masksToBounds = true
42 | view.addSubview(errorHeader)
43 | let guide = view.safeAreaLayoutGuide
44 | errorHeader.translatesAutoresizingMaskIntoConstraints = false
45 | bottomAnchor = errorHeader.bottomAnchor.constraint(equalTo: guide.bottomAnchor, constant: 100)
46 | bottomAnchor.isActive = true
47 | errorHeader.trailingAnchor.constraint(lessThanOrEqualTo: guide.trailingAnchor, constant: -20).isActive = true
48 | errorHeader.leadingAnchor.constraint(greaterThanOrEqualTo: guide.leadingAnchor, constant: 20).isActive = true
49 | errorHeader.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
50 | errorHeader.heightAnchor.constraint(equalToConstant: errorHeader.viewHeight).isActive = true
51 | view.layoutIfNeeded()
52 | animateBannerPresentation()
53 | }
54 |
55 | private func animateBannerPresentation() {
56 | if KeyboardStateManager.shared.isVisible {
57 | bottomAnchor.constant = -KeyboardStateManager.shared.keyboardOffset
58 | } else {
59 | bottomAnchor.constant = -20
60 | }
61 | UIView.animate(withDuration: 0.5, delay: 0.3, options: [], animations: { [weak self] in self?.view.layoutIfNeeded() }, completion: nil)
62 | }
63 |
64 | private func hideBanner(errorHeader: ToastView?) {
65 | UIView.animate(withDuration: 0.5, animations: {
66 | errorHeader?.alpha = 0
67 | }) { _ in
68 | errorHeader?.removeFromSuperview()
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/ToastManager/ToastManager/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // ToastManager
4 | //
5 | // Created by Ahmed masoud on 4/3/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
12 |
13 | var window: UIWindow?
14 |
15 |
16 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
17 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
18 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
19 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
20 | guard let _ = (scene as? UIWindowScene) else { return }
21 | }
22 |
23 | func sceneDidDisconnect(_ scene: UIScene) {
24 | // Called as the scene is being released by the system.
25 | // This occurs shortly after the scene enters the background, or when its session is discarded.
26 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
27 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
28 | }
29 |
30 | func sceneDidBecomeActive(_ scene: UIScene) {
31 | // Called when the scene has moved from an inactive state to an active state.
32 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
33 | }
34 |
35 | func sceneWillResignActive(_ scene: UIScene) {
36 | // Called when the scene will move from an active state to an inactive state.
37 | // This may occur due to temporary interruptions (ex. an incoming phone call).
38 | }
39 |
40 | func sceneWillEnterForeground(_ scene: UIScene) {
41 | // Called as the scene transitions from the background to the foreground.
42 | // Use this method to undo the changes made on entering the background.
43 | }
44 |
45 | func sceneDidEnterBackground(_ scene: UIScene) {
46 | // Called as the scene transitions from the foreground to the background.
47 | // Use this method to save data, release shared resources, and store enough scene-specific state information
48 | // to restore the scene back to its current state.
49 | }
50 |
51 |
52 | }
53 |
54 |
--------------------------------------------------------------------------------
/ToastManager/ToastManager/Views/ToastView/ToastView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ToastView.swift
3 | // ToastManager
4 | //
5 | // Created by Ahmed masoud on 4/3/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ToastView: UIView {
12 |
13 | //MARK: Outlets
14 | @IBOutlet var contentView: UIView!
15 | @IBOutlet weak var imageView: UIImageView!
16 | @IBOutlet weak var errorLabel: UILabel!
17 |
18 | //MARK: Properties
19 | var viewHeight: CGFloat {
20 | let textString = (errorLabel.text ?? "") as NSString
21 | let textAttributes: [NSAttributedString.Key: Any] = [.font: errorLabel.font!]
22 | let estimatedTextHeight = textString.boundingRect(with: CGSize(width: 320, height: 2000), options: .usesLineFragmentOrigin, attributes: textAttributes, context: nil).height
23 | let height = estimatedTextHeight + 30
24 | return height
25 |
26 | }
27 | //MARK: Methods
28 | override init(frame: CGRect) {
29 | super.init(frame: frame)
30 | commonInit()
31 | }
32 |
33 | required init?(coder aDecoder: NSCoder) {
34 | super.init(coder: aDecoder)
35 | commonInit()
36 | }
37 |
38 | private func commonInit() {
39 | Bundle.main.loadNibNamed("ToastView", owner: self, options: nil)
40 | addSubview(contentView)
41 | contentView.frame = self.bounds
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/ToastManager/ToastManager/Views/ToastView/ToastView.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/ToastManager/ToastManager/Views/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // ToastManager
4 | //
5 | // Created by Ahmed masoud on 4/3/20.
6 | // Copyright © 2020 Ahmed Masoud. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 | // Do any additional setup after loading the view.
16 | }
17 |
18 | @IBAction func showToast(_ sender: Any) {
19 | ToastManager.shared.showError(message: "Hello", view: self.view)
20 | }
21 |
22 | }
23 |
24 |
--------------------------------------------------------------------------------