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.


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.


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"
        }
    }
}

我不相信你可以做你想要的东西,但我已经使用下面的方法为仅仅实现接口的特定类提供功能:

protocol ExampleProtocol {

}

extension ExampleProtocol where Self: UIViewController{

    // extend what you need to here
}
链接地址: http://www.djcxy.com/p/33710.html

上一篇: 如何使用JSON作为contentType使Kendo MVC Helpers的CRUD

下一篇: Swift扩展仅适用于导入它们的情况