|
Sanan Husain Oodles

Sanan Husain (Mobile-Associate Consultant - Development)

Experience:Below 1 yr

Sanan is a motivated Mobile Application Developer with a deep passion for his work. He has gained substantial expertise in iOS Application Development, focusing on creating native iOS applications using Xcode and Swift. Sanan demonstrates proficiency in working within a scrum framework and collaborating effectively with various teams. His experience includes successfully deploying multiple apps on the App Store. With a background in Information Technology and strong programming skills, Sanan consistently shows self-motivation and excels as a valuable team player.

Sanan Husain Oodles
Sanan Husain
(Associate Consultant - Development)

Sanan is a motivated Mobile Application Developer with a deep passion for his work. He has gained substantial expertise in iOS Application Development, focusing on creating native iOS applications using Xcode and Swift. Sanan demonstrates proficiency in working within a scrum framework and collaborating effectively with various teams. His experience includes successfully deploying multiple apps on the App Store. With a background in Information Technology and strong programming skills, Sanan consistently shows self-motivation and excels as a valuable team player.

LanguageLanguages

DotENGLISH

Bilingual

DotHindi

Fluent

Skills
Skills

DotCocoaPods

80%

DotiOS

100%

DotHealthKit

60%

DotARKit

60%

DotCross Device SDK

40%

DotWatchKit

40%

DotTestFlight

60%

DotUIKit

60%

DotSwiftUI

60%

DotApple FairPlay

60%

DotReality Composer

60%

DotmacOS

60%

DotXcode

100%

DotXcode Cloud

60%

DotRealityKit

60%

DotCloudKit

60%

DotiPadOS

60%

DotObjective-C

60%

DotWidevine

60%

DotSwift

100%

DotwatchOS

40%
ExpWork Experience / Trainings / Internship

Dec 2023-May 2024

IOS developer

New Delhi Okhla Phase 1


Mobiloitte technologies pvt. Ltd

New Delhi Okhla Phase 1

Dec 2023-May 2024

EducationEducation

2021-2024

Dot

Future institute of engineering and technology

Btech-Computer science

2018-2021

Dot

Government Polytechnic Shahjahanpur

Polytechnic-Computer Science

certificateCertifications
Dot

Object Oriented Programming on C++

N.I.E.L.I.T

Issued On

Aug 2020

Dot

Data Science/ Analytics

Pregrad

Issued On

Nov 2023

Top Blog Posts
Implementing File Downloads in iOS WKWebView Using WKDownloadDelegate

Downloading files within a WKWebView on iOS has become more straightforward with the introduction of the WKDownloadDelegate in iOS 15. delegate allows developers to manage file downloads directly within their applications, providing a seamless user experience. Ins guide, we'll explore how to implement file downloading in a WKWebView and handle scenarios where the web view encounters files it cannot display.

 

1 Setting Up the WKWebView with Delegates

Begin bconfiguring your WKWebView to use both the WKNavigationDelegate and the WKDownloadDelegate. This seenables the web view to handle navigation actions and manage file downloads.

import WebKit

class WebViewController: UIViewController, WKNavigationDelegate, WKDownloadDelegate {
    var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let webConfiguration = WKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.navigationDelegate = self
        webView.uiDelegate = self
        view.addSubview(webView)

        // Load a URL
        if let url = URL(string: "https://example.com") {
            let request = URLRequest(url: url)
            webView.load(request)
        }
    }
}

2. HandliNavigation Actions

Implement the bView(_:decidePolicyFor:decisionHandler:) method to determine how the web view should respond to navigation actions. Specifically, c if the action should trigger a download.

func wee_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, preferences: WKWebpagePreferences, decisionHandler: @escaping (WKNavigationActionPolicy, WKWebpagePreferences) -> Void) {
    if navigationAction.shouldPerformDownload {
        decisionHandler(.download, preferences)
    } else {
        decisionHandler(.allow, preferences)
    }
}

In this method, naaonAction.shouldPerformDownload returns true if the web view detects that the link is intended for downloading a file. If so, we instruct the view to handle it as a download; otherwise, we allow the navigation to proceed normally.

3. Handling Navigation Responses

Similarly, implement the weiew(_:decidePolicyFor:decisionHandler:) method to handle navigation responses. This is crucial for cases whthe web view encounters content it cannot display.

func webView(_ webVi WebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
    if navigationResponse.canShowMIMEType {
        decisionHandler(.allow)
    } else {
        decisionHandler(.download)
    }
}

Here, navigationResponse.canShoMype checks if the web view can display the content. If it cannot, we treat it as a downl

**4. Assigning the Download Delegate*When a download is initiated, assign the KDownloadDelegate` to handle the download process.

func webView(_ webView: WKWebVi vigationAction: WKNavigationAction, didBecome download: WKDownload) {
    download.delegate = self
}

func webView(_ webView: WKWebView, navigationResponse: WKNavigationResponse, didBecome download: WKDownload) {
    download.delegate = self
}

5. Implementing the WKDownloadDelegate Methods

The WKDownloadDelegate provides methods to mage the download's destination, monitor progress, and handle completion or errors.

// Define a property to store the fila
private var filePathDestination: URL?

func download(_ download: WKDownload, decideDestinationUsing response: URLResponse, suggestedFilename: String, completionHandler: @escaping (URL?) -> Void) {
    // Determine the destination URL for the downloaded file
    let temporaryDirectory = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
    filePathDestination = temporaryDirectory.appendingPathComponent(suggestedFilename)
    completionHandler(filePathDestination)
}

func downloadDidFinish(_ download: WKDownload) {
    guard let filePath = filePathDestination else { return }
    // Handle the downloaded file as needed
    print("Download finished. File saved to: \(filePath.path)")
}

func download(_ download: WKDownload, didFailWithError error: Error, resumeData: Data?) {
    print("Download failed with error: \(error.localizedDescription)")
    // Handle the error and possibly resume the download if resumeData is available
}

In these methods:

  • decideDestinationUsing:compiHandler: specif whe to save the downloaded file.
  • downloadDidFinish is called when the download compls scessfully.
  • didFailWithError handles any errors that occur during doload, with the option to resume if possible.

6. Handling BLOB URLs

For downloads initiated from BLOB s, additional handling is reired. You can intercept the navigation action and use JavaScript to rete the BLOB content, then convert it into a downloadable format. This process involves executing JavaScript within the web view to f the BLOB data and then processing it accordingly. 

Conclusion

By implementing the WKDownloadDelegate and handling navigation actions and responses appropriately, you can etively manage file downloads within a WKWebView on iOS. This approach ensures a seamless and user-friendly experience w dealing with downloadable content in your applications.

Category: Mobile
Mastering Timer and Alarm Management in iOS : A Developer's Guide

Timers and alarms are two essential features in many iOS apps, from fitness trackers to productivity apps. Handling timers and alarms effectively can enhance the user experience by providing timely notifications, reminders, and countdowns. Whether you're building an app that tracks workout sessions, helps users manage time, or needs to notify users at specific intervals, understanding how to work with timers and alarms is a key skill for any iOS developer.

In this blog, we'll walk through the fundamentals of managing timers and alarms in iOS, and explore various ways to implement them in your app using Swift.

 

1. Understanding Timers in iOS

timer is a tool that allows your app to execute a task after a specified amount of time has passed or repeatedly at regular intervals. Timers are often used for countdowns, periodic updates, and even scheduling background tasks.

Setting Up a Basic Timer in iOS

In iOS, timers are primarily managed using the Timer class. This class provides methods for creating one-off or repeating timers. The most commonly used methods are:

  • scheduledTimer(withTimeInterval:repeats:block:): Creates and schedules a timer that executes a block of code after a given time interval.
  • init(timeInterval:target:selector:userInfo:repeats:): Initializes a timer without scheduling it.

Let's create a simple timer that fires once after a specific interval:

import UIKit

 

class TimerViewController: UIViewController {

 

    var timer: Timer?

 

    override func viewDidLoad() {

        super.viewDidLoad()

        

        // Schedule a timer to fire after 5 seconds

        timer = Timer.scheduledTimer(timeInterval: 5.0, target: self, selector: #selector(timerFired), userInfo: nil, repeats: false)

    }

 

    @objc func timerFired() {

        print("Timer fired!")

        // You can perform other actions here like updating UI

    }

 

    deinit {

        timer?.invalidate()  // Always invalidate the timer when the view is deallocated

    }

}

 

Timer Invalidation

It's essential to invalidate the timer once it's no longer needed to prevent memory leaks and unnecessary processing. The timer can be invalidated using the invalidate() method, as shown in the deinit method above. This is especially important if the timer is repeating or triggered based on events that might get canceled.

2. Using Timer for Countdown

A countdown timer can be extremely useful in apps that involve time-sensitive events such as games, workouts, or reminders. Here's how you can implement a countdown timer in your app:

 

class CountdownTimerViewController: UIViewController {

 

    var countdownTimer: Timer?

    var remainingTime = 10

 

    @IBOutlet weak var countdownLabel: UILabel!

 

    override func viewDidLoad() {

        super.viewDidLoad()

        

        // Start a countdown timer

        startCountdownTimer()

    }

 

    func startCountdownTimer() {

        countdownTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateCountdown), userInfo: nil, repeats: true)

    }

 

    @objc func updateCountdown() {

        if remainingTime > 0 {

            remainingTime -= 1

            countdownLabel.text = "\(remainingTime) seconds remaining"

        } else {

            countdownTimer?.invalidate()

            countdownLabel.text = "Time's up!"

        }

    }

 

    deinit {

        countdownTimer?.invalidate()

    }

}

 

This example demonstrates a simple countdown timer, updating the UILabel every second until the timer reaches zero.

3. Handling Alarms in iOS

An alarm typically involves triggering a sound, notification, or alert at a specific time. Unlike a timer, which is typically for intervals, alarms are meant to notify users at a predetermined time, regardless of whether the app is running in the foreground or background.

Using Local Notifications for Alarms

In iOS, local notifications are a great way to implement alarms. Local notifications allow your app to alert the user even when the app is not in the foreground, making them ideal for reminders, alarms, and notifications.

Here's how to schedule an alarm with a local notification:

Step 1: Request Notification Permission

Before you can schedule notifications, you need to ask for permission from the user:

 

import UserNotifications

 

func requestNotificationPermission() {

    let center = UNUserNotificationCenter.current()

    center.requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in

        if granted {

            print("Notification permission granted")

        } else {

            print("Notification permission denied")

        }

    }

}

 

Step 2: Schedule a Local Notification for an Alarm

You can now schedule a local notification to trigger an alarm at a specific time:

 

func scheduleAlarm() {

    let content = UNMutableNotificationContent()

    content.title = "Alarm"

    content.body = "Time's up!"

    content.sound = .default

 

    // Set the alarm time (e.g., 5 seconds from now)

    let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)

    

    let request = UNNotificationRequest(identifier: "AlarmID", content: content, trigger: trigger)

 

    UNUserNotificationCenter.current().add(request) { (error) in

        if let error = error {

            print("Error scheduling alarm: \(error.localizedDescription)")

        }

    }

}

 

Step 3: Handle Alarm Notification

Once the alarm is triggered, the user will receive a notification. You can handle this notification and respond accordingly, such as updating the UI or performing an action when the user taps on the alarm notification.

 

func setupNotificationDelegate() {

    UNUserNotificationCenter.current().delegate = self

}

 

extension ViewController: UNUserNotificationCenterDelegate {

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {

        if response.notification.request.identifier == "AlarmID" {

            // Handle the alarm action here

            print("Alarm triggered!")

        }

        completionHandler()

    }

}

 

4. Handling Alarms and Timers in the Background

One challenge when dealing with timers and alarms is handling them when the app is in the background. iOS apps are subject to background execution limitations, which means your app may not always be able to run a timer or trigger an alarm if it's not actively in use.

Background Tasks and Notifications

To ensure that alarms or timers still work even when the app is not in the foreground, you'll need to rely on background tasks and local notifications. As shown earlier, local notifications can trigger alarms even when the app is in the background. For timers, using background fetch or silent push notifications can help ensure the task gets performed in the background.

You can also use background audio or location updates if your app requires continuous updates (e.g., fitness apps).

Background Fetch for Timers

To use background fetch for tasks like updating a timer, you'll need to enable background fetch in your app's capabilities and implement the following method in your app delegate:

 

func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

    // Perform background task

    print("Background fetch initiated")

    completionHandler(.newData)

}

 

Conclusion

Handling timers and alarms in iOS requires careful planning, especially when considering performance, notifications, and background tasks. By leveraging the Timer class for interval-based tasks and local notifications for alarms, developers can build robust and reliable features that enhance the user experience. Always keep in mind the power consumption and system constraints, particularly when dealing with background tasks and notifications.

By mastering these techniques, you can create apps that keep users on track, notify them of important events, and help them manage their time more effectively — whether they're at the gym, at work, or simply managing daily reminders.

Category: Mobile
Creating Dynamic Particle Effects with UIKit: A Sparkling Challenge

When was the last time you added a touch of magic to your iOS app? Beyond buttons, lists, and layouts, UIKit offers creative opportunities to craft immersive user experiences. One such opportunity lies in dynamic particle effects—imagine confetti raining down, spark trails following your touch, or snowflakes gently cascading across the screen. These effects can elevate your app from functional to delightful.

In this blog, I'll guide you through creating a sparkling particle trail using UIKit's CAEmitterLayer, a versatile tool for building particle systems. By the end, you'll have a reusable, interactive effect to enhance your app's interactivity and charm.

 

What is CAEmitterLayer?

CAEmitterLayer is part of Core Animation and is used to generate particle systems in iOS. Think of it as a powerful engine capable of spawning dynamic, animated particles like sparks, bubbles, or even abstract shapes.

It works alongside CAEmitterCell, which defines the appearance and behavior of individual particles. Together, they form the foundation for creating mesmerizing animations with minimal code.

Creating a Sparkling Trail

Let's create an interactive particle trail that follows the user's finger as they touch and move across the screen.

1. Setting Up the CAEmitterLayer

To start, we configure a CAEmitterLayer to serve as the base for our particle system. This layer will emit particles from a specific position.

Swift Code

let sparkEmitter = CAEmitterLayer() sparkEmitter.emitterShape = .point

sparkEmitter.emitterSize = CGSize(width: 1, height: 1)

sparkEmitter.emitterPosition = CGPoint(x: 0, y: 0)

2. Defining the Particle with CAEmitterCell

Next, we configure the CAEmitterCell, which represents individual particles. This includes properties such as size, lifetime, color, and how the particles behave over time:

Swift Code

let spark = CAEmitterCell() spark.birthRate = 50

spark.lifetime = 1.5            

spark.velocity = 100                  

spark.velocityRange = 50                

spark.scale = 0.05                      

spark.scaleRange = 0.1                  

spark.emissionRange = .pi * 2        

spark.contents = UIImage(named: "spark.png")?.cgImage

spark.color = UIColor.systemYellow.cgColor          

spark.alphaSpeed = -0.4              

The cell is then assigned to the emitter layer:

Swift Code

sparkEmitter.emitterCells = [spark]

3. Making It Interactive

Now comes the fun part—making the emitter move dynamically based on user interaction. By updating the emitterPosition of the CAEmitterLayer in response to touch events, we create an interactive trail effect:

Swift Code:-

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

guard let touch = touches.first else { return }

let touchLocation = touch.location(in: self.view)

sparkEmitter.emitterPosition = touchLocation

}

To ensure the effect starts immediately when a touch begins, update the same logic in touchesBegan.

4. Adding the Layer to the View

Finally, add the emitter layer to the view's hierarchy.

 

Swift Code

view.layer.addSublayer(sparkEmitter)

5. Enhancing the Effect

Here are some ways to make your particle system even more magical:

  • Multiple Colors: Use multiple CAEmitterCell instances with different colors or images to create a multicolor effect.
  • Gravity Simulation: Adjust the yAcceleration property for particles that fall like snowflakes or rain.
  • Dynamic Birth Rate: Change the birthRate property dynamically for bursts of particles (e.g., fireworks).
  •  

Real-World Use Cases

  • Celebrations: Fireworks or confetti when a user completes a task, levels up, or makes a purchase.
  • Ambient Effects: Gentle snow or glowing particles to enhance the mood in a splash screen or background.
  • Interactive Feedback: A spark trail for touch gestures or drag-and-drop features.

Wrapping Up

Particle effects add a layer of visual richness and engagement that can make your app memorable. While CAEmitterLayer is a Core Animation class, it integrates seamlessly into UIKit, letting you add stunning effects with just a few lines of code.

Experiment with the settings, push your creativity, and let your app sparkle—literally! Whether it's a confetti shower for a milestone, a magical touch trail, or an ambient snowfall, the possibilities are endless.

Got a unique particle effect idea or a question? Let me know in the comments—I'd love to hear your thoughts! ✨

Category: Mobile
Banner

Don't just hire talent,
But build your dream team

Our experience in providing the best talents in accordance with diverse industry demands sets us apart from the rest. Hire a dedicated team of experts to build & scale your project, achieve delivery excellence, and maximize your returns. Rest assured, we will help you start and launch your project, your way – with full trust and transparency!