How does imports work in swift? - ios

I frankly have a hard time understanding how imports work in Swift. When I make a new class it will start out with:
import foundation
As an alternative we could use import Swift or import UIKit depending on what libraries we need. BUT I've noticed that if I simply remove the imports my projects runs without any problems (even though I use classes from these libraries). This is where I need some help: I'm wondering if that is because I have internal frameworks that I import Swift/UIKit/Foundation and thereby get the import. So imports works like plague... if they touch a new class everything that class touches will have access to that import.

Yes, when a class that you use imports that framework, it is imported in your class too. This is to make things more clear, for example when class Foo's method abc has a parameter that needs UIKit, which is present in Foundation. Therefore, when you use the class Foo, UIKit is automatically imported.
As a side note, importing UIKit will import Foundation, in which it will also import Darwin. So it is really like plague. If a third party library (such as Charts) imports UIKit, it imports Foundation and Darwin too.

So we found the issue. Someone had added header file to each framework with:
#import <UIKit/UIKit.h>
Removing this line made everything less mad.
Now about how imports works. If a class A in library A import library B, class A will not have access to UIKit even though library B imports UIKit. This is how I'd expect it to work and how it actually works.

Related

swift - cocoa class handling

I'm new in swift-ios. I'm studying this
when I'm trying to create cocoa file,
import cocoa
is giving error.
I've searched in google and found cocoa class not work in ios-swift. it works in osx.
So I'm not getting what'll I do now. Any help appreciated.
Cocoa is a framework for macOS. However, CocoaTouch is an umbrella module for iOS. To import the main module dependency for an iOS app, you use
import Foundation
And to import the main UI module for an iOS app, you use
import UIKit
The term “Cocoa” has been used to refer generically to any class or object that is based on the Objective-C runtime and inherits from the root class, NSObject.

Is MapKit being deprecated? [duplicate]

After upgrading Xcode to 7.3, I just found that some modules are stricken out while importing, like in this screenshot:
But after adding the module (so just pressing enter) everything is fine. What does that mean? The module here is written in Swift and works fine.
This is a bug. We have fixed it in 218010af, which should be included in the Swift 2.2.1 release and is included in the 2016-04-12-a developer snapshot.
The strikethrough occurs if you try to import a module that has already been imported by your file or module:
In this case, I have already imported Foundation (which implicitly imports CoreFoundation), so Xcode is telling you that there is no need to import either module again.
It usually happens when a framework is already imported by any other framework you have already been imported.
For example, UIKit is already imported with Foundation so you don't need to import it manually.
I changed the order of the imports
import Foundation
import UIKit
import LayerKit
import Atlas < red line
import Foundation
import UIKit
import Atlas
import LayerKit
Some notes that may be causing it:
LayerKit importing Atlas even though LayerKit is the lower level API
Atlas is the UI layer
Both were Cocoapod imports
Error appeared when I created an 2nd Schema for App Store/Enteprise
releases and cleaned one and switch to the other.
Deleting Derived
Data didnt clear it.
So tried rearranging them and red line disappeared

Creating pod, use of undeclared type for my pod classes

I'm creating a pod in swift to use with cocoapods, but I'm having a strange problem when trying to use it.
My pod is downloaded normally after 'pod install' and I can import it via 'import MyPod'. So far so good, but when I try to access my classes in the pod, I get the message
"Use of undeclared type 'NameOfTheClassIwantToUse'".
If i go to my pod folder in Pods project, all the files are there, but I cannot use it.
I also noticed when I go into the import 'MyPod' with command+click I can see just few imports instead of all my classes, like:
import MyPodProjectName
import MyPodProjectName.Swift
import Foundation
import UIKit
public var MyPodProjectNameVersionNumber: Double
While other imports has all the classes that are supposed to be available upon importing.
Does anyone has a clue on what am I missing here?
Be sure to declare you class as public, as stated here
https://guides.cocoapods.org/making/using-pod-lib-create
As stated there:
It's worth mentioning here, as this catches people quite often, a Swift library needs to have its classes declared as public for you to see them in your example library.
So, just declare namespace "public" on you classes and you are good to go
I had the same problem, and this worked for me!
Yes you need to declare your class, methods and relevant variables as public and don't forget to import your module on top of the class you need.

How to import a Swift framework globally?

I want to have a way to import my Swift Cocoapods globally in every class, how can I achieve this?
I tried a lot of things and they didn't work. Here are some ways I haven't tried and thought may be possible if found a way to work them:
Have a general import statement like UIKit and put everything in there. (Edit: This failed)
Somehow put Swift frameworks in the Obj-C briding header and import the stuff in there.
You should be able to import it globally by adding #_exported before the import.
#_exported import MyPodModuleName
However, like the other answer mentions, doing that for an entire module is not recommended, because it introduces implicit coupling between modules.
Hence instead try something like:
import Foundation
#_exported import class MyModuleName.MyClassName
#_exported import class MyModuleName.MyOtherClass
It's strongly discouraged in Swift because that would introduce implicit coupling between modules.
However, you can make a certain symbol available globally by declaring a typealias in the module that imports the other module:
import ModuleName
public typealias ClassName = ModuleName.ClassName
As of Swift4:
Being in a Swift project
Want to have another Swift project globally
imported (and using cocoapods)
I just managed to do that by adding the following line to my bridging header:
#import <PodName/PodName-Swift.h>
How good/bad this practise is? Not sure, but I just wanted some extensions globally available in my project. this did the trick.
There is no way to do this. And this is not a bug, this is a language feature (so far, as speaking of Swift 2.2).
Swift uses modules (Apple introduced them in Xcode 5 for Objective-C) and each file is an semantic unit, so you need to explicitly inform Xcode which modules are exposed to defined file.
Not only there is no support for your described behaviour, but you shouldn't also try to bypass it. Using unnecessary (unused) modules could theoretically produce slower code (taking into account that compiler uses this information to its optimisation process).
You can manually achieve the same functionality by:
Creating the Objective-C Bridging Header file;
Adding #import <UIKit/UIKit.h> to the Objective-C Bridging Header file (so that you don't need to repeat this for every single .swift file).
for pods you have to do like #import <SwiftyJSON/SwiftyJSON-umbrella.h>
A reason you wouldn't want to do this:
Imagine if both your frameworks would use the same method name, it would make things ambiguous for the compiler.The compiler won't know which method it should run.
To find out more see this question

Is it possible to use "ModuleName-Swift.h" in a pod or static library?

To access swift files from objective-c, you need to import the ModuleName-Swift.h header, as described here, where "ModuleName" is the Product Module Name (and typically the project name).
Unless I'm missing something, this isn't very good for code reuse. If I make an obj-c class that uses some swift code, my import for the swift class will include the project name. If I want to reuse that class in another project, I'll have to change that import so it includes the project name for the new project.
So if I want to make my class part of a library that can be used by any project, what am I supposed to do?

Resources