Skip to main content
deleted 23 characters in body
Source Link
nhgrif
  • 25.3k
  • 3
  • 63
  • 129

In our swift project, there are multiple service classes that encapsulate functions, mostly network-api calls. They implement a protocol, and depend on other service classes, e.g. an authorization service or a network facade.

Their instances should only exist once, hence they are designed as singletons, with a private constructor and a single point to access, like so:

static let defaultInstance = MyManagerImplementation(networkFacade: MyApiFacade())

In order to write unit tests for each service class, i want to mock the dependencies. Sadly this is not possible in the code above.

So i re-wrote the initialization like this.

let networkFacade: MyApiFacade

private static var instance: MyManagerImplementation?

static func defaultInstance(apiFacade apiFacade: MyApiFacade = RestApiImplementation.defaultInstance) -> MyManager {
    if instance == nil {
        instance = MyManagerImplementation(networkFacade: apiFacade)
    }
    return instance!
}

init(networkFacade: MyApiFacade) {
    self.networkFacade = networkFacade
}

Which should be the classic singleton pattern, as i know it from other languages.

The problem i have with this is that swift seemingly wants to avoid this way of defining a singleton. It is way longer than the single-line-singleton, which is considered best practice in many posts i found on the web.

So, would it make sense to you to define these service-classes completely static? Or would you go with another solution or the solution above?

Thanks for all help

In our swift project, there are multiple service classes that encapsulate functions, mostly network-api calls. They implement a protocol, and depend on other service classes, e.g. an authorization service or a network facade.

Their instances should only exist once, hence they are designed as singletons, with a private constructor and a single point to access, like so:

static let defaultInstance = MyManagerImplementation(networkFacade: MyApiFacade())

In order to write unit tests for each service class, i want to mock the dependencies. Sadly this is not possible in the code above.

So i re-wrote the initialization like this.

let networkFacade: MyApiFacade

private static var instance: MyManagerImplementation?

static func defaultInstance(apiFacade apiFacade: MyApiFacade = RestApiImplementation.defaultInstance) -> MyManager {
    if instance == nil {
        instance = MyManagerImplementation(networkFacade: apiFacade)
    }
    return instance!
}

init(networkFacade: MyApiFacade) {
    self.networkFacade = networkFacade
}

Which should be the classic singleton pattern, as i know it from other languages.

The problem i have with this is that swift seemingly wants to avoid this way of defining a singleton. It is way longer than the single-line-singleton, which is considered best practice in many posts i found on the web.

So, would it make sense to you to define these service-classes completely static? Or would you go with another solution or the solution above?

Thanks for all help

In our swift project, there are multiple service classes that encapsulate functions, mostly network-api calls. They implement a protocol, and depend on other service classes, e.g. an authorization service or a network facade.

Their instances should only exist once, hence they are designed as singletons, with a private constructor and a single point to access, like so:

static let defaultInstance = MyManagerImplementation(networkFacade: MyApiFacade())

In order to write unit tests for each service class, i want to mock the dependencies. Sadly this is not possible in the code above.

So i re-wrote the initialization like this.

let networkFacade: MyApiFacade

private static var instance: MyManagerImplementation?

static func defaultInstance(apiFacade apiFacade: MyApiFacade = RestApiImplementation.defaultInstance) -> MyManager {
    if instance == nil {
        instance = MyManagerImplementation(networkFacade: apiFacade)
    }
    return instance!
}

init(networkFacade: MyApiFacade) {
    self.networkFacade = networkFacade
}

Which should be the classic singleton pattern, as i know it from other languages.

The problem i have with this is that swift seemingly wants to avoid this way of defining a singleton. It is way longer than the single-line-singleton, which is considered best practice in many posts i found on the web.

So, would it make sense to you to define these service-classes completely static? Or would you go with another solution or the solution above?

Source Link

Singleton manager/service classes with mockable dependencies in swift

In our swift project, there are multiple service classes that encapsulate functions, mostly network-api calls. They implement a protocol, and depend on other service classes, e.g. an authorization service or a network facade.

Their instances should only exist once, hence they are designed as singletons, with a private constructor and a single point to access, like so:

static let defaultInstance = MyManagerImplementation(networkFacade: MyApiFacade())

In order to write unit tests for each service class, i want to mock the dependencies. Sadly this is not possible in the code above.

So i re-wrote the initialization like this.

let networkFacade: MyApiFacade

private static var instance: MyManagerImplementation?

static func defaultInstance(apiFacade apiFacade: MyApiFacade = RestApiImplementation.defaultInstance) -> MyManager {
    if instance == nil {
        instance = MyManagerImplementation(networkFacade: apiFacade)
    }
    return instance!
}

init(networkFacade: MyApiFacade) {
    self.networkFacade = networkFacade
}

Which should be the classic singleton pattern, as i know it from other languages.

The problem i have with this is that swift seemingly wants to avoid this way of defining a singleton. It is way longer than the single-line-singleton, which is considered best practice in many posts i found on the web.

So, would it make sense to you to define these service-classes completely static? Or would you go with another solution or the solution above?

Thanks for all help