HSM

HSM Contact information, map and directions, contact form, opening hours, services, ratings, photos, videos and announcements from HSM, Internet Company, Lahore.

19/08/2025

DO SAJDO KE B**H KI DUA دو سجدو کے بیچ کی دعا

18/08/2025

Saim ayub against Australia

18/08/2025

گاجروں کی سازش | गाजरों की साज़िश | The carrot plot

15/08/2025

What Makes a Mother's LOVE So Selfless?

15/08/2025

3 things you must come to accept

14/08/2025

گرین ٹریکٹر سکیم میں درخواست دینے کا مکمل طریقہ اور اہل کاشتکار

17/01/2020

We are looking for Male/Female who can speak good English.
Proven work experience as a Recruiter or fresh.
Ability to manage the first hiring stages (job posting, sourcing, screening, interviewing)
Experience with various interview formats, including phone screening calls, in-person interviews and group interviews
Experience evaluating candidates for various roles and seniority levels
Knowledge of resume databases and Applicant Tracking Systems
Excellent communication and relationship-building skills
Solid organizational and time-management abilities

16/12/2019

When you try to build a release version for the first time after adding hundreds of dependencies and you start getting weird proguard errors you can’t fix??

Depending on your workflow, it’s usually a good practice to try to create a release version frequently and not wait for months until the project is complete. This allows you to test your app in release mode and easily detect issues while the code base is still small.
Another good practice is to always look for library’s Proguard rules when you are adding them to your project. Add any required rules for a library and it should work fine with Proguard.

25/03/2018

Detecting the first launch of the iOS application — the wrong and the right way

The concept of the “first launch” is crucial for many apps. You may want to show a quick presentation screen, populate your model layer with pre-defined data or do many other interesting things.

The actual logic behind this functionality is quite trivial: we need to persist some flag indicating that the app was launched before, and on every launch check the existence of that flag, so if it doesn’t exist, it’s our first launch.

So let’s not talk too much about that and dive right into code. The wrong one, actually. But it doesn’t matter now. So:

final class FirstLaunch {

let userDefaults: UserDefaults = .standard

let wasLaunchedBefore: Bool
var isFirstLaunch: Bool {
return !wasLaunchedBefore
}

init() {
let key = "com.any-suggestion.FirstLaunch.WasLaunchedBefore"
let wasLaunchedBefore = userDefaults.bool(forKey: key)
self.wasLaunchedBefore = wasLaunchedBefore
if !wasLaunchedBefore {
userDefaults.set(true, forKey: key)
}
}

}
And then at the call site:

let firstLaunch = FirstLaunch()
if firstLaunch.isFirstLaunch {
/// do things
}
This approach works just fine. Nothing is wrong with the logic, it really detects the first launch of your application. However, there is a huge problem with this code:

How are we going to test this?

And I mean not just testing the logic (and even that’s now is quite hard even though the class does so little), but testing the code which relies on this logic as well. All our “run only at the first launch” functionality should be tested, but how are we going to do it? Deleting the app every time we made a change is not an option, obviously.

So we need to make our FirstLaunch hackable. We need it to report “first launch” when it’s actually not while we’re testing. And we need it to be production-ready as well.

So in order to do that, we have to look at what FirstLaunch actually does. We should limit the scope as much as possible. So, what are the responsibilities of FirstLaunch?

It checks the existence of “was launched” flag and stores that in memory.
If the flag is false (meaning it’s our first launch and the flag was explicitly set to false or it simply doesn’t exist), it creates the true flag and persists it.
And, actually, that’s it. That’s all our FirstLaunch has to do.

So think of that: why should our FirstLaunch bother at all about UserDefaults? Does it really matter how exactly we retrieve and persist this “was launched” flag? It’s a simple implementation detail, after all. And FirstLaunch should be bare logic. So let’s get rid of the UserDefaults dependency, once and for all:

final class FirstLaunch {

let wasLaunchedBefore: Bool
var isFirstLaunch: Bool {
return !wasLaunchedBefore
}

init(getWasLaunchedBefore: () -> Bool,
setWasLaunchedBefore: (Bool) -> ()) {
let wasLaunchedBefore = getWasLaunchedBefore()
self.wasLaunchedBefore = wasLaunchedBefore
if !wasLaunchedBefore {
setWasLaunchedBefore(true)
}
}

convenience init(userDefaults: UserDefaults, key: String) {
self.init(getWasLaunchedBefore: { userDefaults.bool(forKey: key) },
setWasLaunchedBefore: { userDefaults.set($0, forKey: key) })
}

}
Instead of using UserDefaults, from which we needed only two functions, we now just inject exactly those two functions right into our init. And we also made a convenience initializer to make the creation of UserDefaults-based FirstLaunch easier.

let firstLaunch = FirstLaunch(userDefaults: .standard, key: "com.any-suggestion.FirstLaunch.WasLaunchedBefore")
if firstLaunch.isFirstLaunch {
// do things
}
And now creating our “hacked” FirstLaunch is a trivial task:

let alwaysFirstLaunch = FirstLaunch(getWasLaunchedBefore: { return false }, setWasLaunchedBefore: { _ in })
if alwaysFirstLaunch.isFirstLaunch {
// will always execute
}
Or we could go fancy (and we should):

extension FirstLaunch {

static func alwaysFirst() -> FirstLaunch {
return FirstLaunch(getWasLaunchedBefore: { return false }, setWasLaunchedBefore: { _ in })
}

}
let alwaysFirstLaunch = FirstLaunch.alwaysFirst()
if alwaysFirstLaunch.isFirstLaunch {
// will always execute
}
So what did we just do? We isolated the real responsibility of FirstLaunch from the implementation details, and we made it still easy to work with from the outside. With this approach, we can simply swap the underlying storage for our flag, and we can also easily test both the FirstLaunch and our app without breaking the code.

This is, of course, not about the first launch. This is about the design of your classes and their responsibilitites. You should aim to isolate the functionality as much as possible and always think about how to test it and the code that relies on it. You can read more about the ideology behind it here.

Thanks for reading the post! Don’t hesitate to ask or suggest anything in the “responses” section below. You can also contact me on Twitter.

Hi! I’m Oleg, the author of Women’s Football 2017 and an independent iOS/watchOS developer with a huge passion for Swift. While I’m in the process of delivering my next app, you can check out my last project called “The Cleaning App” — a small utility that will help you track your cleaning routines. Thanks for your support!

Address

Lahore
54000

Alerts

Be the first to know and let us send you an email when HSM posts news and promotions. Your email address will not be used for any other purpose, and you can unsubscribe at any time.

Share