Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't access singleton instance from Swift framework

Tags:

swift

Using Xcode 6.3, I created a very simple, contrived command line tool in Swift. It contains three modules.

The main module:

import Foundation

let displayer = ValueDisplayer()

displayer.displayValue()

A ValueDisplayer module:

import Foundation

class ValueDisplayer {
    func displayValue() {
        println("The value is \(ValueProvider.instance.value)")
    }
}

and a ValueProvider module:

import Foundation

public class ValueProvider {
    class var instance: ValueProvider {
        struct Static {
            static let instance = ValueProvider()
        }

        return Static.instance
    }

    var value: Int {
        return Int(arc4random())
    }
}

This all compiled and ran successfully. However, I then decided to convert the ValueProvider to a framework. I created a Cocoa Framework target, and moved the ValueProvider module into it instead of in the command line target. I modified the ValueDisplayer module to this:

import Foundation
import ValueProvider

class ValueDisplayer {
    func displayValue() {
        println("The value is \(ValueProvider.instance.value)")
    }
}

and configured the command line tool to link against the framework. Now I get the following compilation error in the ValueDisplayer module related to the println statement:

Module 'ValueProvider' has no member named 'instance'

I'm confused as to why the code doesn't work anymore. I'm wondering if the ValueProvider class is not being qualified correctly anymore, only it is unclear how that should be done.

What is needed to allow the command line tool to compile by linking against the framework?

like image 309
Tron Thomas Avatar asked May 02 '15 17:05

Tron Thomas


People also ask

Can singleton class be inherited Swift?

Pure-singleton classes must be marked as final to avoid inheritance confusion. In swift, you can use structure also to achieve the same concept. A programmer cannot inherit the pure-singleton class. When you try to inherit any class in swift, you must call the constructor of the superclass.

How does Singleton work in Swift?

In Swift, Singleton is a design pattern that ensures a class can have only one object. Such a class is called singleton class. An initializer allows us to instantiate an object of a class. And, making the initializer of a class restricts the object creation of the class from outside of the class.

How do you clear a singleton instance in Swift?

You don't destroy a singleton. A singleton is created the first time anyone needs it, and is never destroyed as long as the application lives.

Can we de init a singleton object in Swift?

If the Singleton is nil it creates a new instance. This is actually the only good way to set up a Singleton. If you have a regular object that you can't deinitialize it's a memory problem. Singletons are no different, except that you have to write a function to do it.


2 Answers

public is "opt-in". It is not applied magically to members of a public entity; you must apply it explicitly to a member of a public entity if you want that member to be public as well. You made the class ValueProvider public but you did not make its class var instance public, so it is not visible from another module.

So, you would need to rewrite like this:

public class ValueProvider {
    public class var instance: ValueProvider {
        // ...
    }
    public var value: Int {
        // ...
    }
}

[And by the way, a file is not a module. A framework is a module. That is why you have to change your code when you move it from merely being in a separate file to being in a different framework.]

like image 113
matt Avatar answered Sep 25 '22 22:09

matt


I got program to build and run. What I had to do was go to the Build Phases for the framework and remove the generated header file from the Headers section. I don’t know why this makes things work. My understanding is that header is needed to help with Objective-C interaction. If the program had needed to interact with Objective-C as well as Swift, I’m wondering how anyone could get things to work properly.

like image 25
Tron Thomas Avatar answered Sep 26 '22 22:09

Tron Thomas