Swift is fast, safe and expressive language to code with great full stack potential and community support. According to Apple, it’s 2.6 times faster than Objective C (As a Swift Developer I agree on this too 🙌). It’s 6th most loved language on StackOverflow.
ABI Background As a developer, I hope sometimes you also felt that Swift is not mature enough as every year major changes are being introduced. One of the key problems articulated by a lot of developers is “Lack of backward compatibility” and you have to choose one Swift version for your Xcode projects (Version lock). Resulting in with a new Swift release you have to make changes in your existing code.
What is ABI? ABI stands for Application Binary Interface. During runtime, Swift program interacts with other libraries through ABI (low-level set of protocols for memory representation, function calls, and access). So when I say ABI not stable it means that each binary is building its own version of Swift Dynamic Library inside it. Now the Swift 5 is ABI Stable which means if I build two apps, one using Swift 5.0 and another using Swift 5.2, both will use Swift ABI embedded in the iOS Operating System.
Why ABI Stability matters a lot?
Compatibility: which means new compilers can compile your old Swift code which means no more migration pain.
Bundle Size: It will reduce the build size because of no Swift standard Library in your Framework folder.
Binary framework and runtime compatibility which enables the framework distribution as a binary which will work across multiple Swift versions.
Conclusion: Swift is the future for Apple ecosystem and now it’s ABI stable which means, in other words, it is like write once and use everywhere.
When the user taps an on App icon, iOS creates an instance of UIApplication which runs on the main thread. This main thread processes all UI events such as touch, location updates etc.
After app launched successfully, it becomes available for the user to do interactions with it and every single interaction which known as an event is processed in a FIFO manner.
Now while events are being processed there may come some UI update requests which aren’t get fulfilled immediately. Instead, the system waits until the existing process finishes and the next redraw cycle comes. There is a periodic interval between the event processing and UI layout handling. The setLayoutNeeded() and layoutIfNeeded are two UIView’s methods here to ask the system for updating the view with new changes.
The setNeedsLayout() tells the system that you want the view and all it’s subviews to be redrawn in the update cycle.
Here is What Apple’s doc says on this, “Call this method on your application main thread when you want to adjust the layout of a view’s subviews. Note that it returns immediately (Async call) because it does not force an update, it waits for the next update cycle”.
Whereas layoutIfNeeded() is an async call which tells the system that you want the view and it’s subviews to be redrawn immediately without waiting for the next update cycle.
UIView have one more method named layoutSubviews() which you can use for your own implementation to set the frame of your view directly by overriding it. And since it’s default implementation uses the constraints you have given to determine it’s size and positions to get the frame, you should override it unless autoresizing and constraint behavior is not working for you as expected.
In short use setNeedsLayout(), if you are okay with the system to update it in the next upcoming update cycle and use layoutIfNeeded() if you want it to be updated immediately.
An enumeration defines a common type for a group of related values and enables you to work with those values in a type-safe way within your code. Or when a property can have its value only out of a defined set, enum is the solution which complimentary provides type-safety and auto-completion at compile time.
Enumerations can define initializers to provide an initial case value; can be extended to expand their functionality beyond their original implementation; can have functions and can conform to protocols to provide standard functionality.
Enums can have nested enums and associated values.
Enums can be recursive: A recursive enumeration is an enumeration that has another instance of the enumeration as the associated value for one or more of the enumeration cases. “Indirect” keyword is used to inform the compiler about recursion.
Each enum case’s rawValue depends upon the raw type taken and if no raw type is not taken than rawValue wouldn’t be available. Swift’s enums don’t bound to use only integer type as a raw type, you can use Strings, Characters or even Floats instead.
Properties of a constant instance of the struct are immutable because struct’s instance own the whole object and by declaring it as a constant means the whole object itself will be immutable.
Properties of a constant instance of the class are mutable as class’s instance owns the object’s reference thus by declaring it as a constant only means that the further reference assignment can’t be done.
Structs are blessed with default member-wise initializer but classes are not.
Structs are preferable when they are small and copyable.
With Structs, there is much less need to worry about memory leaks or multiple threads racing to access/modify a single instance of a variable.
Since struct instances are allocated on the stack, and class instances are allocated on the heap, structs can sometimes be drastically faster (but it still depends on how many values you’re storing and the size/structure.)
In a multi-threaded environment, for instance, with a database connection that’s opened in a different thread, structs are safer. They can be copied from one thread to another thread, without running the risk of a race condition or deadlock. Classes do not have this inherent safety unless they’re deliberately made thread-safe.
How to use Swift classes into Objective Code when you have multiple targets.
For using Swift classes in Objective-C Code when you have one target in your app. We generally need to andimport TargetName-Swift.h next to add support in your Swift file you need to inherit if from NSObject or use @objc flag.
What if you have multiple targets in your codebase? As you cannot import, TargetNameA-Swift.hTargetNameB-Swift.h etc. In that case, you can tell the compiler that not to create Swift module specific to target change it to project name because the project will be same and unique.
For achieving this select your every target, Build Settings and change the build configuration.
Objective-C Generated Interface Header Name —> replace$(SWIFT_MODULE_NAME)-Swift.h that is specific to the each target, with $(PROJECT_NAME)-Swift.h
Later import PROJECT_NAME-Swift.h in your Objective C code to make use of your Swift code.