Why am I able to use MessageUI without a framework reference? - swift

In my Swift 2 project, targeting iOS 9.2 and above, in Xcode 8.2.1, I have code that shows the mail-compose screen like so:
if MFMailComposeViewController.canSendMail() {
let composeMailVC = MFMailComposeViewController()
composeMailVC.mailComposeDelegate = self
composeMailVC.setSubject("Test")
// etc
}
Originally I had a reference to the MessageUI.framework in my project properties, but after removing the framework reference and cleaning the project, it still builds fine and when I run the code on my device the mail compose window still appears and seems fully functional.
I cannot find any explicit references to MessageUI.framework in the raw text of my .xcodeproj file, nor is there anything in my Objective-C bridging header.
I know that Swift does make some implicit framework references, but I couldn't find anything that suggests MessageUI.framework is one of them.
Curiously when I jump to the definition of MFMailComposeViewController XCode shows it in the MessageUI module.

The compiler automatically added the frame work in given its previous direction - IE. Import.

Related

Cleaning an older swift application project using storyboards

I have been assigned a "new" old app project from my company, where there is a mix of older swift code and newer swift code. I am slowly getting comfortable with deleting and refactoring parts of the code, trying to remove the Xcode warnings and making the code safer in general... But since I am new to swift (especially storyboards), I am not sure when an #IBOutlet or #IBAction can be removed.
I have some #IBOutlets and #IBActions, where there are no 'dots' next to them:
the circles to the left-side of the outlets don't have a dot
Does this mean it is safe to change these from outlets to "regular" views? and is this also true for #IBActions?
Is this simply straight forward, no dot = No #IBOutlet/#IBAction needed?
Or is it trial and error: Try and remove, build & run, see if broken, redo...?
Or are there smarter ways to check these things?

Xcode Ignoring import

I have just installed Xcode 11 and when I try to create new fresh project with the SwiftUI check mark selected it returns an error.
Not able to build and run successfully.
File 'ContentView.swift' is part of module 'SwiftUI'; ignoring import
ContentView.swift
Use of undeclared type 'View'
SceneDelegate.swift
Use of unresolved identifier 'UIHostingController'
I have tried removing all derived data and also set command-line tools to 11
Your project is named SwiftUI - please try using a different name.
Detailed Answer
Each project you create has a module with the same name as the project. So there are two SwifUI modules here:
The actual SwiftUI
The project itself
Xcode always takes the nearest definition as the default. So your SwiftUI is closer than the system's SwiftUI. But you are in the project's module already! So Xcode ignores the import.
A very common mistake is to name the project same as one of the using frameworks! (e.g. CoreData, SwiftUI, SceneKit, Metal)
Solution
As Matteo mentioned in his answer, Don't name your project same with another module. Change it to anything else.
Note that It could appear as an error too. For example, if you name your project CoreData and using SwiftUI, the error appears as Circular dependency error:
Circular dependency between modules 'CoreData' and 'SwiftUI'
Because Xcode gets confused about modules and can not detect what the real issue is.
How can we access our module's classes instead of the system's module?
Imagine you have a class named Section in a custom framework called MyProject and you imported it alongside the SwiftUI.
import SwiftUI
import MyProject
Section // <- This could be either SwiftUI's section or MyProject's Section
To make it clear for the compiler (and anyone else), you should call the module before the class name:
SwiftUI.Section // <- This returns the SwiftUI's Section
MyProject.Section // <- This returns the MyProject's Section
Try with different project name. With SwiftUI, it will always show compilation error. Just change the name and enjoy coding with SwiftUI

How to (Using Storyboard) create JSON Parser in iPhone?

Currently I am working in iPhone application, Using Storyboard to create JSONParser, Import JSON Library inside the application, then I have add #import JSON/JSON.h inside ViewController.h file, but the error comes in "file not found", and JSON Framework classes error in release because I am using RFC, so how to fix these issues?
Inside JSON Framework classes error found here
Your project uses ARC, but the JSON library doesn't. You need to disable ARC for the library files. To find out how, see this question:
How can I disable ARC for a single file in a project?, or this one: ios5 ARC what is the compiler flag to exclude a file from ARC?
the error you are getting is ARC issue. your project is ARC enabled , but the JSON framework is not using ARC.
you can disable the ARC in your whole project, or use it for single file . see

XCode doesn't recognize UI Class UITextChecker

I am writing an app for my iPad running 3.2.2 with XCode 3.2.3. It seems that the highest version of the iOS for iPad this version of XCode has is 3.2, but other apps load fine onto the phone so this doesn't seem to be an issue. I am attempting to make use of the new UITextChecker class. I have imported UIKit, and UITextChecker.h appears in the headers folder under the UIKit.framework icon. However, when I try to compile this code:
NSString *theLanguage = [[UITextChecker availableLanguages] objectAtIndex:0];
or simply this:
UITextChecker *textChecker;
XCode tells me that UITextChecker is undeclared. Any ideas what it going on here? Thanks!
James
Here is a picture of the UIViewController's header file:
For whatever reason, UIKit.h does not import UITextChecker.h. You can fix this by also adding the following line.
#import <UIKit/UITextChecker.h>

conditionally import framework

well to begin with I'm sure this is a simple question.
I am developing an iPhone app with the iAd Framework, which only runs for iOS 4.0 or higher.
Still, I wanna choose a iPhone OS 3.0 deployment target, which causes everything to crash.
How do I conditionally include the iAd framework?
...I mean, it would be something like:
...if([[UIDevice currentDevice] systemVersion]>=4.0]) #import
Obviously this won't work because I don't know the correct syntax. Also:
How do I conditionally declare an AdView* variable?
How do I conditionally handle this AdView* variable in my implementation file.
If you guys could help me, I will be very well impressed.
Thanks
You don't need to change your include, you need to make the iAd (or any other new framework) linked weakly:
In your target, find iAd in the linked frameworks and change its "Role" from "Required" to "Weak".
To handle the variable conditionally, use NSClassFromString function, like this:
Class AdClass = NSClassFromString(#"ADBannerView");
if(AdClass) {//if the class exists
ADBannerView* myAd = [[AdClass alloc] initWithFrame:CGRectZero];
// do something with the ad
}
If OS is older than iOS 4.0, AdClass will be nil and the code won't execute. Note that using ADBannerView* as the type of the variable shouldn't cause any problems, as it's just a hint for a compiler and is the same as id after compilation.