- Not Running: This is a simple state in which our app is not launched or no code is being executed and terminated by the system and the application is completely switched off.
- Inactive: This state is just a transitional state. Inactive state means our application is running in the background but is not able to receive events.
- Active: Active state is the main execution state, where our app is running in the background and is able to receive events.
- Background: This is the state where our App is running in the background and still is able to execute the code in the background.
- Suspended: This state means that our app running is in the background state and the system suspends this app and the application cannot execute any code.
2. sceneDidDisconnect(_:) the scene is sent to background
3. sceneDidBecomeActive(_:)
4. sceneWillResignActive(_:)
5. sceneWillEnterForeground(_:)
6. sceneDidEnterBackground(_:)
- Serial Queue (a work item starts to be executed once the previous one has finished execution)👍
- Concurrent Queue (work items are executed concurrently not necessarily simultaneously)
- It’s great and very limited use cases.
- We can’t obviously use complex queries to filter your results.
- It’s very slow.
- Each time we need something, we need to either serialize or deserialize it.
- it’s not thread-safe.
—> ABI stability
>>> Now Swift 5 is ABI Stable, Swift will be embeded within the iOS Operating System and it’s ABI will be compatible with every version of Swift. i.e Apple Music is using Swift 5.0, but Notes app is using Swift 5.2, and both are consuming Swift ABI embedded in the Operating System.
This means that if any changes occur in future Swift versions it will come with the OS on which developer is working on and gets automatically used by the app when it is running on that OS without the need to recompile and redeliver app.
—> Dependency Injection
It is injecting dependencies into an object instead of tasking the object
(https://cocoacasts.com/dependency-injection-in-swift)
example,
we define a UIViewController subclass that declares a property, requestManager, of type rquestManager?.
import UIKit
class ViewController: UIViewController {
var requestManager: RequestManager?
}
Note:- We can set the value of the requestManager property one of two ways.
Without Dependency Injection
The first option is to task the ViewController class with the instantiation of the RequestManager instance. We can make the property lazy or initialize the request manager in the view controller's initializer. That's not the point, though. The point is that the view controller is in charge of creating the RequestManager instance.
import UIKit
class ViewController: UIViewController {
lazy var requestManager: RequestManager? = RequestManager()
}
This means that the ViewController class not only knows about the behavior of the RequestManager class. It also knows about its instantiation. That's a subtle but important detail.
With Dependency Injection
But there's another option. We can inject the RequestManager instance into the ViewController instance. Even though the end result may appear identical, it definitely isn't. By injecting the request manager, the view controller doesn't know how to instantiate the request manager.
// Initialize View Controller
let viewController = ViewController()
// Configure View Controller
viewController.requestManager = RequestManager()
Many developers immediately discard this option because it's cumbersome and unnecessarily complex. But if you consider the benefits, dependency injection becomes more appealing.
Types
Most developers consider three forms or types of dependency injection:
- initializer injection
- property injection
- method injection
These types shouldn't be considered equal, though. Let me list the pros and cons of each type.
Initializer Injection
I personally prefer to pass dependencies during the initialization phase of an object because this has several key benefits. The most important benefit is that dependencies passed in during initialization can be made immutable. This is very easy to do in Swift by declaring the properties for the dependencies as constants. Take a look at this example.
class DataManager {
private let serializer: Serializer
init(serializer: Serializer) {
self.serializer = serializer
}
}
let serializer = RequestSerializer()
let dataManager = DataManager(serializer: serializer)
The only way to set the serializer property is by passing it as an argument during initialization. The init(serializer:) method is the designated initializer and guarantees that the DataManager instance is correctly configured. Another benefit is that the serializer property cannot be mutated.
Because we are required to pass the serializer as an argument during initialization, the designated initializer clearly shows what the dependencies of the DataManager class are.
Property Injection
Dependencies can also be injected by declaring an internal or public property on the class or structure that requires the dependency. This may seem convenient, but it adds a loophole in that the dependency can be modified or replaced. In other words, the dependency isn't immutable.
import UIKit
class ViewController: UIViewController {
var requestManager: RequestManager?
}
let viewController = ViewController()
viewController.requestManager = RequestManager()
Property injection is sometimes the only option you have. If you use storyboards, for example, you cannot implement a custom initializer and use initializer injection. Property injection is then your next best option.
Method Injection
Dependencies can also be injected whenever they are needed. This is easy to do by defining a method that accepts the dependency as a parameter. In this example, the serializer isn't a property on the DataManager class. Instead, the serializer is injected as an argument of the serializeRequest(_:with:) method.
class DataManager {
func serializeRequest(request: Request, with serializer: Serializer) -> NSData? {
...
}
}
Even though the DataManager class loses some control over the dependency, the serializer, this type of dependency injection introduces flexibility. Depending on the use case, we can choose what type of serializer to pass into serializeRequest(_:with:).
It's important to emphasize that each type of dependency injection has its use cases. While initializer injection is a great option in many scenarios, that doesn't make it best or preferred type. Consider the use case and then decide which type of dependency injection is the best fit.
//////////////////////////////////////////////////////////////
—> Singleton
Singletons are easy to understand. The singleton pattern guarantees that only one instance of a class is instantiated
class NetworkManager {
static let shared = NetworkManager()
// Static type property, which is guaranteed to be lazily initialized only once
}
NetworkManager.shared
/////////////////////////////////////////////////////////////
—> Generic
(https://learnappmaking.com/generics-swift-how-to/)
With generics you can write clear, flexible and reusable code. You avoid writing the same code twice,and avoid duplication, and it lets you write generic code in an expressive manner. its abstracted manner
Let’s take the original addition(a:b:) function, and turn it into a generic function. Like this:
func addition<T: Numeric>(a: T, b: T) -> T
{
return a + b
}
let a = addition(a: 42, b: 99)
print(a)
// Output: 141
let b = addition(a: 0.99, b: 0.33)
print(b)
// Output: 1.32
let c = addition(a: Double.pi, b: Double.pi)
/////////////////////////////////////////////////////////////
—> Access control/Access Specifier
(https://singhdivesh.medium.com/ios-and-macos-developer-traveler-9b9640476dc2)
==> Open and public comes to picture when we are talking about different target/module.
==> Internal, FilePrivate and private is used within Target/module
Open : This Access level is everywhere, can access within function, within class, within file, outside of target and even can override as well
Public : Same as open but can not override.
Internal : This is default access level. It can be access within module everywhere.
FilePrivate — This access level area is within file if multiple classes exits in the same file, that also can be accessible
private — access within body where you have written privat
/////////////////////////////////////////////////////////////
—> Higher-order function
(https://levelup.gitconnected.com/higher-order-functions-in-swift-35861620ad1)
A higher-order function is a function that takes one or more functions as arguments or returns a function as its result. It will speed up your software development skills.
swift higher-order functions — forEach, map, CompactMap, flatMap, filter, reduce, sort, and sorted.
let coins = [1, 5, 2, 10, 6]
ForEach
forEach will iterate through all elements in an array and will not return anything.
simple
for coin in coins {
print("\(coin)$", terminator: " ")
}
For Each
coins.forEach { print("\($0)$", terminator: " ") }
“forEach” works like “for in” but the basic difference is, you can’t use break and continue statement to exit from the closure for forEach.
Map
map will iterate through all elements in an array and will return an updated array.
let coins = [1, 5, 2, 10, 6]
simple
var coinsWithCurrency: [String] = []
for coin in coins {
coinsWithCurrency.append("\(coin)$")
}
print(coinsWithCurrency)
let coinsWithCurrencyUsingMap_shortSyntax = coins.map { "\($0)$" }
compactMap
compactMap will iterate through all elements in an array and will return an updated array only with the elements which satisfied the condition written inside the body of compactMap. Any element which resulting in a nil value will be excluded from the updated array.
let coins = ["1", "5", "$", "10", "6"]
simple
var validCoins: [Int] = []
for coin in coins {
if let coin = Int(coin) {
validCoins.append(coin)
}
}
print(validCoins)
let validCoinsUsingCompactMap_shortSyntax = coins.compactMap { Int($0) }
flatMap
flatMap converts 2D array to one dimensional array.
let arrayOfCoins = [[1, 5, 2, 10, 6],[2, 7, 4, 10, 15]]
let arrayOfCoin = arrayOfCoins.flatMap { (coins) in
coins
}
print(arrayOfCoin)
let arrayOfCoin_ShortSyntax = arrayOfCoins.flatMap { $0 }
print(arrayOfCoin_ShortSyntax)
filter
filter will iterate through all elements in an array and will return an updated array only with the elements which satisfied the condition written inside the body of filter.
let coins = [1, 5, 2, 10, 6, 2, 7, 4, 10, 15]
let coinsWithValueLessThanSix = coins.filter { (coin) -> Bool in
coin < 6
}
print(coinsWithValueLessThanSix)
let coinsWithValueLessThanSixShortSyntax = coins.filter { $0 < 6 }
print(coinsWithValueLessThanSixShortSyntax)
reduce
reduce will iterate through all elements in an array and returns an object with a combined value of all elements.
syntax -
reduce(initialResult, (currentResult, currentElement) -> Return finalResult)
let coins = [1, 5, 2, 10, 6, 2, 7, 4, 10, 15]
let sumOfCoins = coins.reduce(0) { (result, coin) -> Int in
result + coin
}
let sumOfCoinsShortSyntax = coins.reduce(0, { $0 + $1 })
outpost string “1521062741015”
sort(by:) and sorted(by:)
sort(by:) will sort all elements according to the condition written inside the body of the closure.
sorted(by:) will sort all elements according to the condition written inside the body of the closure and returns a new array.
var coins = [1, 5, 2, 10, 6, 2, 7, 4, 10, 15]
let sortCoins = coins.sorted { (a, b) -> Bool in
a > b
}
coins.sort { (a, b) -> Bool in
a > b
}
print(sortCoins)
print(coins)
->Beta Testing
It is invite users to test your apps and app clip experiences and collect valuable feedback before releasing your apps on the App Store.
Internal Tester
Add up to 100 members of your team who have been assigned the Account Holder, Admin, App Manager, Developer, or Marketing role to quickly test beta builds as you iterate on your app. Each member can test on up to 30 devices. Internal testers can access all of your beta builds available for testing
External tester
Invite up to 10,000 external testers using their email address or by enabling and sharing a public link, which creates an open invitation for anyone to test your app
->App Store Regarding
App name ,subtitle text limit = 30 character
What's New in This Version and Description text limit = 4000 characters
Promotional text limit = 170 characters
App size limit 4GB uncompressed
App clip Size 10 mb
Photo size
6.5” => 1242*2688 ==> XS_max , 11_pro_max
5.5” => 1242*2208 ==> 6+,6s+,7+,8+
Kewords = 100
-> NotificationCenterDelegate
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void)
No comments:
Post a Comment