How do I create an importable module in Swift? - swift

I have read through Apple's documentation for Swift and can find nothing about how to create modules or how to define class or stucture members as private or public.
There are references to the import statement in the syntax but I can find no information on what it does or how to use it.
Does anyone know where I can find this?

In Swift, "Modules" refers to Frameworks. Xcode now has a template for creating a framework project for both iOS and OS X.
There is currently no way to declare methods or properties public / protected. If you would like to see this added as a feature, you can make a feature request on Apple's bug reporter. It should also be noted that Apple has stated that the language could change with each release of Xcode, so it is possible that member access levels could be added before the public release.

Also, there is a way to make a module by yourself, but it's a bit harder way.
If you'll look at xcrun swift -help you may see a few options, and there are -emit-module, -emit-library and -emit-object which might be useful, but, probably, you should prefer official way and distribute modules via Frameworks.
If you still want to make module on your own, you can read this guide with some explanation

Apple mentioned that private methods don't exist yet but they are in the process of being implemented. Remember that this is a newborn language and it is still being build up.

Update
You can modularize a swift project using frameworks.
We modularize by creating separate framework projects for each module and link them via Xcode workspace. It looks more natural when we separate the components into different projects & it also makes sure that there is only a one-way communication between modules. Developers can work/test on isolation without thinking much about other modules.
By default classes/structs/etc created within a framework will have an internal access control type so it is only visible within the modules. In order to make it visible outside the module, you can make it public.
More info on access controll level here
The latest Xcode 6 beta update (beta 4) bring access control to swift
Swift Enables Access Control
Swift access control has three access levels:
private entities can only be accessed from within the source file where they are defined.
internal entities can be accessed anywhere within the target where they are defined.!
public entities can be accessed from anywhere within the target and from any other context that imports the current target’s module.

Swift 4.0
Description from the chapter "Access Control" in the Apple book "The Swift Programming Language (Swift 4 Edition)"
Swift provides five different access levels for entities within your code. These access levels are relative to the source file in which an entity is defined, and also relative to the module that source file belongs to.
open access and public access enable entities to be used within any source file from their defining module, and also in a source file from another module that imports the defining module. You typically use open or public access when specifying the public interface to a framework. The difference between open and from another module that imports the defining module. You typically use open or public access when specifying the public interface to a framework.
internal access enables entities to be used within any source file from their defining module, but not in any source file outside of that module. You typically use internal access when defining an app’s or a framework’s internal structure.
fileprivate access restricts the use of an entity to its own defining source file. Use file-private access to hide the implementation details of a specific piece of functionality when those details are used within an entire file.
private access restricts the use of an entity to the enclosing declaration, and to extensions of that declaration that are in the same file. Use private access to hide the implementation details of a specific piece of functionality when those details are used only within a single declaration.”

Related

Can I use library keyword in personal project but not in library

I am using Flutter. As you are aware, Flutter doesn't have protected keyword to make classes package private. But interestingly, the same could be achieved using library, part, part of keywords once I name widgets starting with underscore. But, I am a bit worried about performance issues.
Question: Is it ok to use library/part/part of keywords inside ordinary projects?
public classes inside lib/src are considered package private. Only classes in lib are truly public, so are files in lib/src when they get exported by a file in lib.
enchilada/
lib/
enchilada.dart <-- public
src/
beans.dart <-- package private unless exported
While technically you can access everything in lib/src, you get a warning when you use implementation files.
Don't use part
The part keyword can not be used to hide code, it inherits the same visibility as the library. All it does is splitting a file into multiple files. It should only be used for code generation these days https://stackoverflow.com/a/27764138/669294
Note: You may have heard of the part directive, which allows you to split a library into multiple Dart files. We recommend that you avoid using part and create mini libraries instead.
source
Performance
Visibility doesn't affect performance in any way.
Naming your entity starting with an underscore (for example _test) should make it private.
Libraries not only provide APIs, but are a unit of privacy: identifiers that start with an underscore (_) are visible only inside the library. Every Dart app is a library, even if it doesn’t use a library directive.
Source

How to make a Swift framework submodule really private?

I've found another question which brings more details regarding the problem and possible solutions. It seems like there is a known bug which is a subject for future improvements.
Objective C classes within an iOS Swift-based dynamic framework
I'm developing a framework in Swift and I'm using some Objective-C code inside the framework. So far my module map looks like this:
framework module MyModule {
umbrella header "MyModule-umbrella.h"
export *
explicit module Private {
header "MyTools.h"
}
}
My concern is that all the APIs from MyTools.h are visible from outside the framework: for example, if you install the framework using Cocoapods, then you import MyModule into your application (not MyModule.Private), you are able to access MyTools.h which is not desirable and redundant. Is there any way to make MyTools invisible from outside the framework?
PS. I use Cocoapods to distribute the framework, here is my podspec (the most significant part):
s.module_map = 'Pod/MyModule.modulemap'
s.frameworks = 'CoreData', 'CoreTelephony', 'SystemConfiguration'
s.resources = 'Pod/Classes/MessageStorage/*.xcdatamodeld'
s.public_header_files = 'Pod/Classes/**/*.h'
s.private_header_files = 'Pod/Classes/MyTools/**/*.h'
s.source_files = 'Pod/Classes/**/*.{h,m,swift}'
PSS. My umbrella header does not import MyTools.h
PSSS. Just tried to exclude the header from the main module:
framework module MyModule {
umbrella header "MyModule-umbrella.h"
export *
exclude header "MyTools.h"
explicit module Private {
header "MyTools.h"
}
}
No luck.
I found another question which brings more details regarding the problem and possible solutions (which don't work though). It seems like there is a known bug which is a subject for future improvements.
Objective C classes within an iOS Swift-based dynamic framework
I had exactly the same problems recently. The quick answer is you can't :) Even if you declare "private" modulemap, it can be always imported by your framework users. Please note, that usually, it is not a concern, especially with open source. You just say "this is an internal module, don't use it".
But (there is always but) - you can have behavior, that effectively works the same - allows you to use your Objective-C classes withing same framework target, without making them public. It works in closed source setup, I'm not 100% sure how would it behave with pods.
The case a bit too complex to paste everything here. I'm adding a link to my article about the topic, maybe it will help you. But speaking honestly - it might be a bit of overhead in your setup.
Creating Swift framework with private Objective-C members. The Good, the Bad, and the Ugly
Github example project

How to distinguish wizards in Eclipse RCP?

We have an Eclipse IDE application on 3.x that uses various newWizards to allow the user to create different files. Although these files differ slightly contentwise, the structure of the wizards is quite similar.
Thus, a sound object-oriented approach would be to instantiate different wizards from the same class and initialize them with different data.
Problem:
To decide what wizard needs which data we need a way to distinguish the different already instantiated wizards (e.g during the call to the init method of the wizard).
Is there any way to do so? It would e.g. help if somebody knows a way to get the wizard's id defined in the extension point from within the instantiated wizard.
If your wizard implements IExecutableExtension, it will be passed the configuration element that represents the extension for which it is created.
You can also use extension factories in that you specify a type that implements IExecutableExtensionFactory.
The interface allows you to control how the instances provided to extension-points (wizards in your case) are created.
Extension example:
<extension point="org.eclipse.ui.wizards">
<newWizard
name="..."
class="com.example.WizardFactory">
</newWizard>
Note that the extension factory may also implement IExecutableExtension to gain access to extension attributes before creating the extension's executable class.

Swift: how can I create external interface for static library (public headers analog in Objective-C .h)

I need to create a static library with Swift,
and I need to know how can I implement interface for the library.
In Objective-C I can mark needed headers as public in build phases,
but there is not any headers and any interfaces in Swift.
What should I do with Swift?
Simply put: you don't.
Swift is not a language that separates headers and implementations. When you create a library or framework based on Swift and only for consumption by Swift, the Xcode default build setting of DEFINES_MODULE already does the job for you. This will create a .swiftmodule file, which will be used by import in other Swift projects.
If you want your code to be importable from Objective-C though, you might want to check if the SWIFT_INSTALL_OBJC_HEADER build setting is also enabled (which it is by default for frameworks as far as I know). Then the Swift compiler will generate a <ProductName>-Swift.h file for you, which you can import in Objective-C code to access your Swift classes and functions.
If you want your Swift framework to expose certain classes to the interface, simply mark the 'entities' (functions, variables etc.) public:
public class Class {}
public var variable: Int
public func function() { }
By default, all entities have internal access.
public entities are intended for use as API, and can be accessed by any file that imports the module, e.g. as a framework used in several of your projects.
internal entities are available to the entire module that includes the definition (e.g. an app or framework target).
private entities are available only from within the source file where they are defined.
Source: the official Swift blog.

Using only part of a class from a different target

I just created a new target for the Lite version of my app. The Lite app only uses part of a base class that I have in the main app, ie it won't need to use an option that requires it to import 4 or 5 files.
My question is, from a design perspective, what is the best way to handle this so that my Lite version can only use the part of the class that it needs? Obviously, one solution is I just import those 4 unnecessary files into Lite build phase, and just use the whole class (even the parts it doesn't need). This seems inefficient though. I know I can do an ifndef to block those files from being imported if the Lite version is running, but how do I block out the code in the class from also not being picked up by the compiler?
Would a better way just be to have my Lite version create a subclass of the Base class that only uses the options it needs? But then I believe, would I still need to import those unnecessary files?
Just a bit confused about this, first time I've ever created another target that utilizes code from the main target. Any help appreciate thanks.
Put the common/lite functionality in a super class. Heavy functionality in the sub-class.
As another answer points out, you can handle this by putting the lite functionality in a subclass and the full functionality in a superclass.
Another option is to use a single class, and add the full functionality in an Objective-C category. Essentially, you can define methods in the category to supplement – or replace – methods in the base implementation.
Unlike a subclass, however, methods defined in a category can't invoke super to get the base class's functionality. super still refers to the base class's superclass, whether that's NSObject, UIDocument, or what have you – not the implementation without the category.
The advantage is that you only have one class name, so the code which instantiates your class (or classes) doesn't need to use something like #ifdef to switch classes and #includes depending on whether you're building the lite or full version.