How to perform throttling in Swift, Debounce.

What is Throttling all about, it’s a process responsible for regulating the rate at which application processing is conducted (doesn’t matter statically or dynamically). Wikipedia

A very common use in iOS, when you have a search bar which takes input from user and sends off a request for search results every time. For a long query it may cause lot of requests to be sent on server to process (performance will be different for slow vs fast typing user & also depends on internet connection).

Another use case that I faced today is to log an impression when user sees the TableViewCell. I found and interesting example on Github. I created an extension for this to make use of it everywhere.

Create a protocol.

protocol Throttable {
    func perform(with delay: TimeInterval,
                 in queue: DispatchQueue,
                 block completion: @escaping () -> Void) -> () -> Void
}

Provide the default implementation using the extension.

extension Throttable {
    func perform(with delay: TimeInterval,
                 in queue: DispatchQueue = DispatchQueue.main,
                 block completion: @escaping () -> Void) -> () -> Void {
        
        var workItem: DispatchWorkItem?
        
        return {
            workItem?.cancel()
            workItem = DispatchWorkItem(block: completion)
            queue.asyncAfter(deadline: .now() + delay, execute: workItem!)
        }
    }
}

Responsibility of this function is just to return a function, when you call the returned function.

  • It cancels the exiting workItem if exists (magical Optional).
  • Creates a new DispatchWorkItem with the completion block.
  • And the queue calls the workItem with given delay.

And that’s how it works, Just conforms the Throttable protocol wherever you want.

class UserInputHandler: Throttable {
    let triggerAPI = perform(with: 1.0) {
        print("Fetch Search Result")
    }
    
    func didReceiveInput() {
        triggerAPI()
    }
}

Here is an easy example to integration it with UIViewController

class SearchViewController: UIViewController, Throttable {
    @IBOutlet weak var searchTextField: UITextField!
    
    lazy var triggerAPI = perform(with: 1.0) { [weak self] in
        
        guard let searchText = self?.searchTextField.text, !searchText.isEmpty else {
            return
        }
        
        print("API Request to fetch result for \(searchText)")
    }
}

extension SearchViewController: UITextFieldDelegate {
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        triggerAPI()
        return true
    }
}

Thanks for reading
Find more Swift Tips and Tricks on Github.

How to check API availability in Swift, iOS / macOS / watchOS / tvOS SDK

What is Availability checking?

Today Apple leads the world of innovation with iOS, MacOS, watchOS and tvOS, and every year we see new operating system release with more enhances, and new technologies.

So all the features Apple releases is coupled with the OS releases (for example Sign-in with Apple is available on iOS 13 and above only). As a developer is highly recommend for us to delivery one binary which support latest as well as old operating system.

So this availability check is Swift gives us the power to check weather the user running a specific version or not.

Swift API to check the OS version?

class LoginViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        initLoginView()
    }

    private func initLoginView() {
        //initialise login view
        
        guard #available(iOS 13.0, *) else {
            return
        }
        
        let authButton = ASAuthorizationAppleIDButton()
        // integrate Sign in with Apple
    }
}

Code snippet shows that we are initializing a LoginView for user to login, and making use of #available API call to check the version, if it’s iOS 13.0 and above we do add “Sign in with Apple” which is only available in iOS 13.0 and above.

Swift also provides us an declaration attribute (there are two kind of attributes in Swift, one that apply to declarations and another to types) to declare that this call or function is available on which iOS version.

@available(iOS 13, *)
func initSignInWithApple() {
// use AuthorizationService framework to integrate Sign in with Apple.
}

These are the arguments we can make use in @available attribute.

  • iOS 
  • iOSApplicationExtension
  • macOS
  • macOSApplicationExtension
  • watchOS
  • watchOSExtension
  • tvOS
  • tvOSApplicationExtension
  • swift

An asterisk (*) to indicate all platforms.

Few interesting use that we can make use.

@available(*, unavailable) – Indicates that the declaration is not available on given platform.

@available(*, introduced) – Indicates the first version when the declaration was introduced.

@available(*, obsoleted) – Indicates the first version platform/language in which the declaration was obsoleted.  

@available(*, message) – A message that the complier displays during the warning or error.

@available(*, renamed) – A message that the complier displays during the warning or error about the renaming.

Interesting example that I really like from Swift documentation.

// A protocol defined in first release.
protocol ConfigProtocol {

}

Would like to change the name in next release?

// change the name.
protocol AppConfigProtocol {

}

@available(*, unavailable, renamed: "AppConfigProtocol") 
typealias ConfigProtocol = AppConfigProtocol 

In this case, complier will start giving you a error, also a fix for you.

‘ConfigProtocol’ has been renamed to ‘AppConfigProtocol’

Replace ‘ConfigProtocol’ with ‘AppConfigProtocol’

Thanks for reading.

Swift Property Wrapper | Quick Note

This weekend, I gave 👨🏽‍💻 on Property Wrapper to see where I can make use of it, so here are the quick note.

Image credit : https://www.instagram.com/buntylm

Background, Swift properties do contains some extra code (‘get’ and ‘set’) when we want to observe the changes. For example, if we want to add some log to see the new value every time a property changes. The straightforward way of implementing this is

struct Student {
    private var name_: String
    public var name: String {
        get {
            return name_
        } set {
            name_ = newValue
            print("Setting new value \(newValue)")
        }
    }
}

Wait, If we follow this approach for logging more properties, our codebase will become a mess soon, so handle this let’s create a type which will help us to log.

struct Loggable<T> {
    private var value: T

    public init(wrappedValue: T) {
        self.value = wrappedValue
    }

    public var wrappedValue : T {
        get {
            value
        } set {
            value = newValue
            print("Setting new value \(newValue)")
        }
    }
}

Let’s update our implementation.

struct Student {
    private var name_ = Loggable<String>(wrappedValue: "NA")
    public var name: String {
        get {
            return name_.wrappedValue
        } set {
            name_.wrappedValue = newValue
        }
    }
}

Great, looks better and That is the problem, Property Wrapper (require Swift 5.1) is solving. All you need to do is add ‘@propertyWrapper’ to ‘Loggable’, and below the how Loggable and Student class will look like

@propertyWrapper
struct Loggable<T> {
    private var value: T

    public init(wrappedValue: T) {
        self.value = wrappedValue
    }

    public var wrappedValue : T {
        get {
            value
        } set {
            value = newValue
            print("Setting new value \(newValue)")
        }
    }
}

struct Student {
    @Loggable var name: String = "NA"
}

Another way of giving the default value 😬

struct Student {
    @Loggable(wrappedValue: "NA") var name
}

Property Wrapper decorates a property with a custom behaviour (similar like we use annotation in Java/Kotlin).  To note, Property Wrapper

  • always need to defined with ‘@properWrapper’ and must have ‘wrappedValue’ property.
  • cannot be set as ‘lazy’, ‘weak’, ‘unowned’ or ‘@NSManaged’.
  • cannot be declared in protocol or extension.
  • cannot be overridden.
  • cannot have custom ‘get’ or ‘set’.

That’s it, Thanks for reading.
Do give a try and let me know which is the use-case you want to use it. 😃

Reference
https://github.com/apple/swift-evolution/blob/master/proposals/0258-property-wrappers.md

All you need to know Accessibility | iOS SDK | Swift

Why does Accessibility matter?

First thing first, it always feels good to know that even if your work is small but it’s making a huge difference in someone’s life. 🙂 There are millions of smartphone users all around the world with some sort of disability. Enabling accessibility into the software system ease them in interacting with it.

And on the other hand, if you’re working for any government agency you have to implement it because of 508 compliance (which says that any technology or software product must be accessible to all users).

Accessibility domains?

– Vision: a vision challenge that makes focusing difficult, color blindness or total blind.
– Hearing: difficulty hearing sound, partial hearing loss or maybe deaf.
– Physical and motor skills: difficulty when it comes to tapping the interface or holding a device.
– Learning and Literacy: hard to understand a complex user interface or hard to remember a sequence of step to do a certain task.

Image from Apple.

What is VoiceOver?

A screen reading tool that helps the user to interact with the application without seeing the screen. The feature is designed for those who have vision problems. Navigate to Settings/Accessibility/VoiceOver.

VoiceOver: Gestures?

Enable the VoiceOver to try this out.
– Single tap: Tap anywhere, VoiceOver will start speaking information as per the accessibility attributes (find more later).
– Swipe right or left: Try swipe right/left VoiceOver will navigate you through all items on the screen while reading them aloud. Right for forward/down and Left for reverse/up.
-Double Tap: is to tap on a selected item.
– Single swipe down: is to spell out the focused item.
– Three finger swipe: For page views to navigate forwards or backward

Accessibility attributes?

Core attributes that VoiceOver will use to provide information to the user.
– Label: way to identify the view (like settings button, profile image) VoiceOver will speak the same when the item will be selected.
– Traits: way to identify the element state, usage or behaviour (like a button is selected.) 
– Hint: way to describe the action of an element (like Go to detail).
– Frame: frame of the element within the screen.
– Value: The value of element like a slider bar.
– AccessibilityLanguage: The language code that the element label value, hint should be spoken. 

How to debug accessibility attributes?

Accessibility inspector is a tool given by Apple to debug your app (Navigate to Xcode/Open Developer Tool/Accessibility Inspector). Where developer can choose the target, enable the pointer to debug the view.

Accessibility Notification?

Animation or layout changes are a visual feedback to the user as a response of the action taken, Use announcements notification to provide an update (other options are layoutChanged, screenChanged delegates).

Target Touch Size?

As per Apple human interface guidelines it is recommended to maintain a tappable area of 44x44pt (minimum) for all controls in the application.

What is Dynamic Type?

Functionality that allows the users to dynamically adjust the size of text, images (choose their preferred text size). iOS app will adopt the text/image size as per user preference. (Apple Developer documentation)

Setup Smart Invert Colors?

Need to set `accessibilityIgnoresInvertColors` property to enable or prevent a control from inverting it’s colours. (Navigate to Setting/General/Accessibility/Display Accommodations/Invert Colors).

Thanks for reading this.

Swift 5 ABI Stability why matters?

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?

  1. Compatibility: which means new compilers can compile your old Swift code which means no more migration pain.
  2. Bundle Size: It will reduce the build size because of no Swift standard Library in your Framework folder.
  3. 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.

Reference:
https://swift.org/about/
https://github.com/apple/swift/blob/master/docs/ABIStabilityManifesto.md

Swift | Open source projects for learning and developers to follow on twitter

Screen Shot 2018-10-05 at 10.26.35 AM

Announced in 2014, the Swift programming language has quickly become one of the fastest growing languages in history. Swift makes it easy to write software that is incredibly fast and safe by design.

Blog for developers to highlight, top 10 trending open source to learn.

  1. MessageViewController A SlackViewController replacement written in Swift, compatible with iPhone X, iOS12. Created by Ryan Nystrom
  2. Swift interpreter for Pascal language (Inspired from Ruslan’s Blog). Created by Igor Kulman
  3. CollectionViewSlantedLayout subclass of the UICollectionViewLayout allowing the display of slanted cells in a UICollectionView.Created by Yassir Barchi
  4. Mint Package manager that installs and runs Swift command line tools, created by Yonas Kolb
  5. CryptoSwift Collection of standard and secure cryptographic algorithms implemented in Swift. Created by Marcin Krzyzanowski
  6. CocoaDebug Debugger tools for iOS supports Swift and Objective C, created by CocoaDebug
  7. iOS-Depth-Sampler Examples of Depth APIs in iOS, created by Shuichi Tsutsumi
  8. Universal Link Testing  It fetches and parses apple-app-site-association file for you to quickly check whether Universal Links are working. created by Ethan Huang
  9. Swift Syntax Set of Swift bindings for the libSyntax library. It allows for Swift tools to parse, inspect, generate, and transform Swift source code. Created by Apple
  10. WhatsNewKit Showcase your awesome new app features, Created by Sven Tiigi

 

Thanks for reading!

Quick Notes | Swift classes into Objective-C Code when you have multiple targets.

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.h TargetNameB-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

Screen Shot 2018-04-19 at 11.02.20 AM.png

Screen Shot 2018-04-19 at 11.02.38 AM.png

Later import PROJECT_NAME-Swift.h in your Objective C code to make use of your Swift code.

How to Respond to an Authentication Challenge | iOS

How to Respond to an Authentication Challenge

If a session requires authentication it creates authentication challenge

 URLSession:task:didReceiveChallenge:completionHandler: 

in order for the connection to continue, the delegate has three options.

  • Provide authentication credentials
  • Attempt to continue without credentails
  • Cancel the authentication request.

NSURLProtectionSpace will give all information about the authentication type and failure if any attempts failed earlier.

Providing Credentials

To attempt to authenticate, the application should create an NSURLCredential object with authentication information of the form expected by the server. You can determine the server’s authentication method by calling authenticationMethod on the protection space.

  • HTTP basic authentication (NSURLAuthenticationMethodHTTPBasic) requires a user name and password. P
  • HTTP digest authentication (NSURLAuthenticationMethodHTTPDigest), like basic authentication, requires a user name and password.withcredentialWithUser:password:persistence:.
  • Client certificate authentication (NSURLAuthenticationMethodClientCertificate) requires the system identity and all certificates needed to authenticate with the server. Create an NSURLCredential object.
  • Server trust authentication (NSURLAuthenticationMethodServerTrust) requires a trust provided by the protection space of the authentication challenge.

Continuing Without Credentials

If the delegate chooses not to provide a credential for the authentication challenge, it can attempt to continue without one.

NSURLSessionAuthChallengePerformDefaultHandling processes the request as though the delegate did not provide a delegate method to handle the challenge.

  • NSURLSessionAuthChallengeRejectProtectionSpace rejects the challenge. Depending on the authentication types allowed by the server’s response, the URL loading class may call this delegate method more than once, for additional protection spaces.

Canceling the Connection

The delegate may also choose to cancel the authentication challenge, by passing NSURLSessionAuthChallengeCancelAuthenticationChallenge to the provided completion handler block.

POV | Difference between ! and ? | In-Shorts Story

Whenever we write code in Swift we use optional because it beautiful way for handling null values as in Objective C its little different and difficult as well, one of the reason is, Objective C based on C, so there are legacy issues as well, but in Swift there is not legacy at all so for handling null value we have separate feature from the language itself that is called Optional (Optional chaining is a process for querying and calling properties, methods, and subscripts on an optional that might currently be nil).

Now the second question comes up in mind is, how does it work?

The idea is whenever you feel any value could be nil in future just make it as Optional simply and before using it first see, is it contains anything? if Yes than use it otherwise make the nessarary decision. In other words, we can say its something like you has a box and it may or may not contains something so before using it first unwrap and check.

How to create Optionals?

? and ! here is the answer. I also googled what is the correct difference and where to use what but only a few links were useful. Small answer is.

Use ? if the value can become nil in the future so that you test for this before using always (we have to use if let or guard statement).

Use ! if it really shouldn’t become nil in the future, but it needs to be nil initially like we do with IBOutlets always (Benefit is before using no need to unwrap using if let or guard statement). But it we use ! and the value is nil ready for the crash.

Thank you for reading.
Please share your comment it will help me to improve.

Happy Learning.

Dependency Injection | Swift | Quick Note

A short answer is, it’s scary terms for a very simple idea!!! See this lines of code.

class Engine {

}

class Car {
    let engine: Engine? = nil
    init() {
        self.engine = Engine()
    }
}

we are creating dependency internally but the object can be also received from outside with lots of benefits like the object become instantly testable, Testing becomes possible without any frameworks, No runtime effects, This makes the whole system more loosely coupled.

class Car {
    let engine: Engine? = nil
    init(engine: Engine) {
        self.engine = engine
    }
}

There are three common types of dependency injections.

Setter, Interface, Constructor based.

In iOS Constructor based is preferable one, it’s when dependency passed to the client in the initializer and don’t change during the whole client life and the biggest advantage of this type could be that it makes the violation of the single responsibility programming principle, if an object takes all dependencies in the initializer and if it has more than three parameters so it means refactoring is needed.

Thanks for reading!!!