The UIKit framework:
import UIKit.NSAttributedString
import UIKit.UIViewController
My question is how to create a custom framework which contains a lot of submodules like the UIKit framework
Here's a tutorial on how you can create modules in Swift, but it doesn't talk about the extra magic on how to do submodules.
For that you need to dive into the Clang documentation, which discusses how to declare modules and submodules. Apple's open source Module description says:
Warning
This feature was never implemented, or even fully designed.
Related
I'm looking into iOS/tvOS docs for GCKeyboard & GCMouse types.
However Apple docs seem to be missing basic info such as what I import to use a type. For example C# docs always show what libraries are needed on MS websites for types. So do Googles Android docs. I'm not seeing this on Apples docs here: https://developer.apple.com/documentation/gamecontroller/gckeyboard
Is there an easy way in ObjC or Swift to check where a type is from?
Does Apple provide any way to lookup what source file I should import for a type? How do people normally go about these lacking docs with xCode dev work?
Apple do indicate on its doc on which framework the class/object that the document referred to is relevant. See my picture for details. Its has a documentation hierarchy from the framework down to the objects and apis within it.
Specifically for GameController framework you’d use the following import
import GameController
A nice anecdote:
In older class and objects it is also customary to add the initials of the framework/library as a prefix for the name. In this case GC(i.e game contoller)Keyboard. Or UI(UIKit)ViewController. With newer libraries like SwiftUI and Combine they have stopped using the prefix.
The prefix was used due to legacy Objetive-C limitation for namespace.
I have basically two frameworks running on Xcode. "ResearchKit" and "AppMethods". While all works fine, the "AppMethods" framework utilizes code within "ResearchKit". In fact it is there to abstract out more methods into framework. A superclass of sorts.
When using them in code, I have to import both frameworks
import ResearchKit
import AppMethods
Is there a way to embed ResearchKit within AppMethods such that I only need to import AppMethods. Without ResearchKit, AppMethods would not exist.
It really depends on the way you implement and use these frameworks within the app.
Generally speaking, iOS doesn't support nested frameworks - please read the follwoing.
But imports can be done within each framework - i.e you can import ResearchKit directly from AppMethods and just "tell" Xcode that the code will be there on compile time, you will have to link the frameworks within the App level. Another useful guide I found
It is quite simple to achieve with CoacoaPods and SPM
Your "stack" is this:
App
|
AppMethods (AM for short)
|
ResearchKit (RK for short).
Within your classes in the app, where you dont explicitly call a RK API (class or method) you dont have to import RK. Otherwise, you have to import RK.
Please note you can embed one library inside another (in this case RK inside AM), and maybe make sure that nobody outside AM knows anything about RK. But once you start explicitly calling RK api within your app, there is no other way than importing RK explicitly along AM.
If I'm building a framework A and import Reachability, maybe via Carthage of Swift PM, although the app using framework A would never be able to use A.Reachability, import Reachability still appears in interface of final built of A.
How to avoid this?
Swift doesn't support internal/private imports at the moment. All of your imports are forwarded to anyone using your framework. If you look at Foundation for example it pulls in a lot of other frameworks such as GCD and Darwin.
If you need to hide it then you are currently limited to copying the code into your framework and making sure it is all internal/private so people importing your framework don't see it.
Why can I just use the types defined in the Foundation framework just by importing the UIKit framework?
import UIKit
// String is a Type defined in Foundation framework
let foo: String = ""
I understand that the UIKit framework depends on the Foundation framework.
// Dependency
Application --> UIKit --> Foundation
Are there any compiler options that allow an application to use a dependent framework indirectly?
I would like to specify any such options when creating my own embedded framework.
I may need correcting on this, but my understanding of this is that there are not.
Even though UIKit depends on Foundation, UIKit does not contain it. If that were the case, it would lead to immeasurable bloat as the majority of Frameworks use types defined in Foundation.
If you want a Framework to be able to 'pass on' types and methods in a Framework it is dependant on, you'll either need to include the Framework it's dependent on and allow the application to access them directly, or alternatively you could add some method signatures and typedef declarations in your own Framework to bridge the gap, for want of a better expression.
It's also worth looking at This article on the swift.org forums which may help you do what you need, although so far it looks as if what you're trying to do is not officially supported.
Background
I'm new to iOS development and playing with Swift for the sake of learning. As a small challenge, I'm trying to get the SSID of network to which a device is currently connected.
This is well-covered ground on Stack using Objective-C: iPhone get SSID without private library, for example ... but the Objective-C / Swift dance is causing me some conceptual challenges.
Specifically, the suggested solution (discussed in the above-linked post) is to call the function CNCopyCurrentNetworkInfo() -- but, according to Apple's documentation, this function is not available in Swift.
So far
I've included (I think correctly) SystemConfiguration.framework by adding it to the Linked Frameworks and Libraries of the project. I've also brought it into the View Controller using import SystemConfiguration.
Questions
Do I need to also use import SystemConfiguration, or is that already done due to including the framework with my project?
Is there another / better way to include the SystemConfiguration library?
The big one: How, once the required library is imported, do you call the Objective-C function from the library?
Thank you!
I know this is not directly answering your question, but it's an answer to your problem.
You can do everything in swift in your case.
After importing the library,
import SystemConfiguration.CaptiveNetwork
You can immediately call:
CNCopySupportedInterfaces()
and it will work.
Confirmed in Xcode 6.3.2.
Apple's interoperability book (from Understanding the Swift Import Process):
Any Objective-C framework (or C library) that’s accessible as a module
can be imported directly into Swift. This includes all of the
Objective-C system frameworks—such as Foundation, UIKit, and
SpriteKit—as well as common C libraries supplied with the system.
Regarding your specific questions:
The opposite is the case: you do not need to manually include Apple's frameworks. Xcode will automatically make them available to you given a valid import statement (such as import SystemConfiguration in your case), even – or rather: especially – in a playground!
ditto...
Given the above import statement, SystemConfiguration is indeed imported since you can call its functions (e.g. SCCopyLastError() // --> __NSCFError) and access its constants (e.g. kCFErrorDomainSystemConfiguration // --> com.apple.SystemConfiguration). Unfortunately, CaptiveNetwork does not seem to be imported with it (e.g. CNCopySupportedInterfaces() // --> Use of unresolved identifier).
You should be able, however, to use this framework on the Objective C side and simply call your own wrapper functions from Swift. You just need to remember to include them among the imports listed in your bridging header (see Swift and Objective-C in the Same Project for more about bridging headers).