Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift extensions that apply only when you import them

I have some swift extensions I want to across projects.

I'd like to avoid category pollution though, unless those extensions are requested.

Is it possible to write them so that they only apply if I've done a certain import, like:

import MySwiftExtensions

// Use custom extensions
let x = [1,3,5,7].average()
let y = [1,3,5,7].firstWhere { $0 > 3 }
let z = "campervan".make1337()

I could write these as static methods wrapped in a single letter class (eg: ø.average([1,3,5,7]), like lodash) to achieve the same thing but sometimes you get much more concise usage from instance methods.

like image 792
SimplGy Avatar asked Apr 29 '16 17:04

SimplGy


People also ask

What are extensions in Swift?

Extensions in Swift are a powerful way to add your own functionality to types that you do not own. This overview of extensions and the examples herein are designed to help you understand how extensions work so you can implement and use them in your own Swift projects.

How do you extend a type in Swift?

Creating extensions is similar to creating named types in Swift. When creating an extension, you add the word extension before the name. extension SomeNamedType { // Extending SomeNamedType, and adding new // functionality to it. } You can extend a particular named type, add a new computed instance, and type properties to it.

How to add new functionality to an existing Swift class?

In Swift, we can add new functionality to existing types. We can achieve this using an extension. We use the extension keyword to declare an extension. For example, Here, we have created an extension of the Temperature class using the extension keyword. Now, inside the extension, we can add new functionality to Temperature.

Can you extend a protocol in Swift?

In Swift, you can even extend a protocol to provide implementations of its requirements or add additional functionality that conforming types can take advantage of. For more details, see Protocol Extensions. Extensions can add new functionality to a type, but they cannot override existing functionality.


2 Answers

You wrote:

I have some swift extensions I want to across projects...

When I have code that I want to use across projects I create a separate framework to hold that code. Then, when I want to use that code in a new project, I embed the framework in that project. Or, for development purposes, I create a workspace that includes the project and the framework. That allows me to work on both at the same time, and then only embed the framework in the final product when it is time to export it.

Once the framework is either embedded or in the same workspace, then you should be able to import it into any individual file in your project with:

import MySwiftExtensions

Any file that does not have the import statement will not have access to the extensions.

EDIT:

Here is a link to a blog that describes how to create a Cocoa Touch Framework. And here is another link that describes in detail how to use workspaces to use frameworks in development projects.

like image 177
Aaron Rasmussen Avatar answered Sep 18 '22 18:09

Aaron Rasmussen


I would like to focus attention on what you reported: "..only apply if I've done a certain import.." It would also mean you want these extensions can be applyed only to a specific class

As reported in this interesting Apple blog chapter and in the official Apple doc you can handle the "Access Control" of your extension

You can extend a class, structure, or enumeration in any access context in which the class, structure, or enumeration is available. Any type members added in an extension have the same default access level as type members declared in the original type being extended. If you extend a public or internal type, any new type members you add will have a default access level of internal. If you extend a private type, any new type members you add will have a default access level of private.

Alternatively, you can mark an extension with an explicit access level modifier (for example, private extension) to set a new default access level for all members defined within the extension. This new default can still be overridden within the extension for individual type members.

/* no access level modifier: default access level will be 'internal' */
    extension UIViewSubClass
    {
        // default access level used: internal
        var helloWorld : String { 
            get {
                return "helloWorld"
            }
        }
    }
    
    // modify default access level to public
    public extension UIViewSubClass
    {
        // default access level used: public
        var helloWorld : String { 
            get {
                return "helloWorld"
            }
        }
    }

The members of extensions marked private are available within the file where they’re defined, and are not available outside that file. Outside the file where the private extension members were defined, any attempt to use them results in an error, and auto-complete wouldn’t even list them

// modify default access level to private
private extension UIViewSubClass
{
    
    var helloWorld : String { 
        get {
            return "helloWorld"
        }
    }
}
like image 34
Alessandro Ornano Avatar answered Sep 18 '22 18:09

Alessandro Ornano