i used following code showing error that file not found.
#import <SwiftDemo/ViewController-swift.h>
even ViewController.swift file is present in project, help me to sort out problem.
I assume you are trying to use Swift code from Objective-C. Is your product name "ViewController"? If not, then you are not importing the correct header. You should use the Xcode generated header ProductModuleName-Swift.h (replacing ProductModuleName with your specific product name).
In simplest terms, the ProductModuleName is just the name of your application. Example: my app is Application so this header is Application-Swift.h
Also, this header will connect ALL of your Swift to Obj-C, it is not file specific.
Please refer to this immensely helpful documentation piece on Swift/Obj-C interoperability.
You should import a synthetic file generated by the compiler called "<YourProductName>-Swift.h".
I think that this file is generated on the fly, but you can still inspect what it expands to by e.g. creating a dummy Objective-C file that contains just this:
extern int ____BEGIN_SWIFT_IMPORTS____; // dummy marker declaration
#import "<YourProductName>-Swift.h"
(you should of course substitute <YourProductName>)
and then by running the preprocessor on it (Product → Perform Action → Preprocess). All the output after the dummy marker declaration will come from the generated file. It's useful to see how Swift code marked with #objc gets translated to Objective-C declarations.
Related
I have a subclass of NSOperation and custom init method which can take couple of arguments. this class is written in OBJ C. and I wanted to call this init method from Swift class for unit testing. is there a way I can call the init method directly from swift? Compiler couldn't recognize the init method.
You have to create a bridging header and import the ObjC class there. Then that class will be available in all of your swift classes
Add a new file to Xcode (File > New > File), then select “Source” and click “Header File“.
Name your file “YourProjectName-Bridging-Header.h”. ...
Create the file.
Navigate to your project build settings and find the “Swift Compiler – Code Generation” section. You may find it faster to type in “Swift Compiler” into the search box to narrow down the results. Note: If you don’t have a “Swift Compiler – Code Generation” section, this means you probably don’t have any Swift classes added to your project yet. Add a Swift file, then try again.
Next to “Objective-C Bridging Header” you will need to add the name/path of your header file. If your file resides in your project’s root folder simply put the name of the header file there. Examples: “ProjectName/ProjectName-Bridging-Header.h” or simply “ProjectName-Bridging-Header.h”.
Open up your newly created bridging header and import your Objective-C classes using #import statements. Any class listed in this file will be able to be accessed from your swift classes.
Above info was found here: http://www.learnswiftonline.com/getting-started/adding-swift-bridging-header/
I'm facing the following problem :
I've declared an protocol in a Swift file and I want to implement it in Objective-C.
I added the #objc annotation to my protocol so Xcode can generate a definition inside my (Project)-Swift.h file and it works fine.
However I cannot import the (Project)-Swift.h file in any of my objc headers since (I suppose) it is generated after those headers has been processed. It is not a big deal because I can simply use this workaround in my objective header file :
#protocol MySwiftProtocolName;
It compiles and works just fine but it will also throws a warning for each class that implements my swift protocol :
Cannot find protocol definition for MySwiftProtocolName
So my question is : Is it possible to force Xcode to generate the (Project)-Swift.h file before it starts processing the regular .h files ?
Thanks
You should be able to add #import "(Project)-Swift.h" into the file where you do implementing this swift protocol. Some times Xcode syntax gets funny and not autocomplete this header name, but in compile time it should work.
If it's not could you please provide more context of what is protocol looks like, as it may be not commutable with Objective-C and so it's not get generated at all.
I'm trying to convert an Objective-C app to swift.
I'd like to import classes in aurioTouch to Swift app, so I created the following Bridging-Header file:
#import "AudioController.h"
but I received following errors in DCRejectionFilter.h, BufferManager.h, FFTHelper.h:
Unknown type name 'class'; did you mean 'Class'?
Expected ';' after top level declarator
and also in AudioController.h:
Unknown type name 'BufferManager'
Unknown type name 'DCRejectionFilter'
Of course I use .mm instead of .m, but this does not work.
update
The simple swift project just including aurioTouch Library (with Obj-C and C++) is as follows:
https://github.com/pika-shi/aurioTouch-Sample
The present answer shows you how to solve the Bridging Header #import, and is a step-by-step tutorial on how to create an Objective-C wrapper object.
.mm does not mean Swift
.mm does not mean Objective-C either
It means Objective-C++, and merely renaming a file to .mm offers no improvement. Notice that you are still including the same .h files, and those are where the problem starts. These .h reference C++ classes, and they must be wrapped.
Wrap the C++ in Objective-C
The file AudioController.h is not an Objective-C file: it includes BufferManager.h which is a C++ file, and compilation stops right there.
You need to create a true wrapper, say AudioControllerBridge which .h is in Objective-C, and .mm can, in turn, make references to C++:
.h
Absolutely, positively no C++ allowed, explicit, included, or else.
#import <Foundation/Foundation.h>
#interface AudioControllerBridge : NSObject
// ...
#end
.mm
Objective-C++ tolerates all the C++ you need, as long as it is not exposed in the interface.
#import "AudioControllerBridge.h"
#import "AudioController.h"
#implementation AudioControllerBridge
// ...
#end
Of course, you could simply modify the AudioController.h directly, but we will consider this bad practice: for the rest of this answer, we will assume that you are attempting to integrate aurioTouch as-is, with exactly 0 lines of code changed.
In the implementation of AudioControllerBridge, you can now instantiate the AudioController, and import all the C++ files you need for proper compilation, something you could not do in the .h. Remember that the .h you are exposing to Swift in Briding-Header must be a pure Objective-C interface.
// Bridging Header
#import "AudioControllerBridge.h"
ARC
You will soon see that you need to download CoreAudio/PublicUtility because some files, like CADebugPrintf are simply missing from the example, and somehow will not build in your new project, at least in DEBUG mode.
If you made it so far, you will then find out that you will get a dozen deprecated warnings, which you can ignore for now, and half as much ARC errors in AudioController.mm. Fix with -fno-objc-arc Compiler Flag:
If you made it so far (props), and have added:
Accelerate.framework
AudioToolbox.framework
AVFoundation.framework
to your target in Build Phases and compiled, you will find that it builds and links.
Wrapping it up
It took me 1h 47mins to reach that point (proof below). The next step is of course to actually put the wrapper code in AudioControllerBridge, so that it returns (wraps):
BufferManager* _bufferManager;
DCRejectionFilter* _dcRejectionFilter;
- (BufferManager*) getBufferManagerInstance;
which are the 3 non-Objective-C elements in that class.
It may be cleaner to to wrap BufferManager and DCRejectionFilter as well, so that they can be used freely in Swift. I will let that decision to the reader.
Demo
Just for the record, all the instructions above lead to a successful compilation of
let ac = AudioControllerBridge()
as seen in this screenshot. It reveals all the files needed, and show a successful build on Xcode 7 for iPhone 6 on iOS 9.
I have a build error when trying to subclass a custom Objective-C class (a subclass of UIViewController) in Swift.
When I try to subclass in Swift, I get the build errors in the picture below. All of them relate to the use of the word class as an argument in the OCMapper library (where I've opened an issue as well).
Some more notes:
In the project, I both import and use Objective-C code in the Swift code and import and use Swift code in the Objective-C code.
I import the compiled Module-Swift.h only in .m and .mm files and forward declare classes that I need in .h files.
I've attempted to create a Module-Swift-Fixed.h class where I forward declare and/or import the custom Objective-C class headers (as recommended here), but that hasn't made a difference.
Has anyone seen anything like this before or have a solution?
I have as yet not been able to trace where in the language spec this is documented, but I suspect you have come across the same problem that I recently faced in objective-c since moving to Xcode 6.4.
I had a message (method) defined as follows
- (BOOL)canProcessClass:(Class) class {
return [class isSubclassOfClass:[NSSet class]];
}
with the same compile error as you mentioned Expected identifier. The fix was simple - just rename the the class argument to something like classToProcess. Which would give you the following
- (BOOL)canProcessClass:(Class) classToProcess {
return [classToProcess isSubclassOfClass:[NSSet classToProcess]];
}
Hence just rename the arguments in your Swift code to not use the (key)word class and you should be fine.
If anyone can point me to the language spec that documents this I would really appreciate it. As far as I'm aware you shouldn't use Class, but I haven't able to find anything about class except the obvious that it is a message (method) available on classes.
I am trying to query the users in my Parse DB into my Table View Controller in my app in Xcode.
I am a beginner, but I have posted my code snippet from my added .swift file to my project. I am trying to query the user in the .swift file but it is not recognizing 'PFUser' from my View Controller.
Do I need to declare the PFUser as something in my .swift file before first calling it in my ViewDidLoad method?
Any ideas?
Code snippet:
You need to import the Parse-Framework in your project. Check this quickstart-guide how to do it.
If you've done it already, you need to import Parse in your File like that:
import UIKit
import Parse
Like you/Xcode has already done that with the UIKit.
First put Parse SDK into the folder into your project navigator area of Xcode.
You will get a Dialogue, You will need to check the box that says copy items if needed and then click Finish.
The next thing we need to do to connect our Swift app to parse.com is create a bridging header. To do this you need to create a new File (File -> New -> File) of type Objective-C File. Call this whatever you like. Here I have just called it testDataCustom. You will see another Dialogue that looks like having this Line at the top "Would you like to configure Objective C bridging Header?" Click on Yes.
Now it will add some new files to your project. Click on the File: testData-Bridging-Header.h. You should see this:
// Use this file to import your target's public headers that you would like to expose to Swift.
5.Underneath this comment code we need to add an #import so that our project knows to use the Parse iOS SDK. To do this we simply add a line into this file, like so:
#import <Parse/Parse.h>
Now you can successfully use Parse methods and properties.
Referred from this Link
You have to import the proper Parse file. :)
I don't know Swift but I assume that of you type
Import Parse.h
It will autocomplete for you.
From what I know in objective-c, you might need to import
Import <Parse\Parse.h>