I have previously built a Keyboard extension project that has components of both Swift and Objective C. I'd like to built a new Keyboard app based on my previous app, with the simple goal of changing the name, keyboard UI and some keyboard mechanics.
I followed the guidelines here on duplicating and renaming an XCode Project. I even managed to get the project to compile after changing the Bundle IDs (for both the container app and the underlying keyboard). However, because of the name of the Targets have now changed, I am get the error that the following files:
#import "NewNameContainerApp-Swift.h"
#import "NewNameContainerApp-Bridging-Header.h"
cannot be found (these errors persist despite me manually changing OldNameContainerApp-Bridging-Header.h to NewNameContainerApp-Bridging-Header.h. It seems that the project has not regenerated a new set of bridging header and -Swift.h files matching the names of my new target.
My question is - is there a way to force XCode to regenerate a new set of these files? And if not, where do I find OldNameContainerApp-Swift.h so I can manually change it to NewNameContainerApp-Swift.h?
Thanks!
Check in your applications Define-Module in the build section. Update it to your latest project name. To find it easily just search for Defines-Module and see if it needs updating. If it is updated try cleaning your project or deleting your Derived Data
I have found no way to force Xcode to regenerate these files. Removing them just causes builds to fail. The only reliable method is to do a clean build, or removed DerivedData and rebuild (effectively the same solution).
When renaming an Objective-C/Swift mixed app, the following additional changes have to be performed for a successful build.
The Swift to Objective-C header file depends on the module name:
<ModuleName>-Swift.h
So if the Module name changes, you need to change the import in your code. In build settings search for Product Module Name to find the module name that is being used.
The Objective-C to Swift bridging header name depends on the build setting Objective-C Bridging Header. Check the Xcode target build settings and modify to match your new name.
Related
I have this code base that I decided to turn into a framework to reuse in my future apps.
So I went ahead and created an Xcode Project for Cocoa Touch Framework.
To keep things simple (and workspaces out of the picture, at least until I grasp the basics of frameworks), I created a "test-bed" iOS app that embeds/depends on/links to the framework as an additional target to the same project (not a separate project). The idea, of course, is to use this app to test my frameworks capabilities as I add or modify them.
So my project has two targets:
MyFramework
MyTestApp
...And of course, two schemes (one to build each):
I am also modifying the code so that it works both on iOS and macOS.
Warning: no umbrella header found for target 'MyFramework (macOS)', module map will not be generated.
So far, so good.
Additionally, I am also modifying the code so that it works both on iOS and macOS.
So I added two more targets:
MyFrameworkMac
MyTestMacApp
...aslo setup so that the app target-depends, links to, and embeds the framework.
Still, good.
Next, I decided to do some cleanup and file rearranging, to keep things tidy and making sense before the number of files starts to grow further.
Then, the trouble started.
After some trial and error, I discovered a few things:
1) If I change the target name for the iOS Framework and try to build the iOS app, I get the following warning:
/Users/Me/Projects/MyFramework/Code/MyFramework/:1:1:
Umbrella header for module 'MyFramework' does not include header
'PublicHeaderXX.h'
...for each of the public header that are included in my master header:
// In this header, you should import all the public headers of your framework
// using statements like #import <MyFramework/PublicHeader.h>
#import <MyFramework/PublicHeader01.h>
#import <MyFramework/PublicHeader02.h>
#import <MyFramework/PublicHeader03.h>
...
2) If I change the product name of the iOS framework in Build Settings, I get the error:
Lexical or Preprocessor Issue | 'MyFramework/MyFramework.h' file not found
...pointing at the location where I import it in the app source code:
#import <MyFramework/MyFramework.h>
for the Mac framework target, I can get away with changing the Target Name, but if I change the product name, I get the warning:
Warning: no umbrella header found for target 'MyFrameworkMacRenamed',
module map will not be generated
So I ask...
Is there a way to set the target names and product names I want for each framework target?
I'm sure there must be something somewhere that I should "modify to match" and eliminate some discrepancy, but I'm new to frameworks and can't figure it out ... (What is an 'umbrella header' anyway?)
It turns out the "umbrella header" is no other than the 'main' header for the framework that is created automatically by Xcode when you first create the project or framework target, and it must have the same name as the target (as explained, for example, here).
As to why both target and product must me named the same, I can only guess it has to do with keeping linking not too complicated (Apps are not 'linked against', so I guess there is no damage in the product name being anything you want).
I was trying to get away with a Single Header to Rule Them All (platforms), using TargetConditionals.h etc. to import either Cocoa.h or UIKit.h, which is impossible, because Xcode won't let you use the same name for both targets, and those have to match the name of their headers!
So, I settled for:
<MyFramework/MyFramework.h>: Classic. Accept No Substitutes. Exclusive for iOS, and
<MyFrameworkMac/MyFrameworkMac.h>: Now Available on the Mac too! - From the People Who Brought You MyFramework
I did a lot of reading and trying. My solution is combined:
Clean build
Close Xcode
Delete DerivedData everywhere - in project folder, user folder (~/Library/Developer/Xcode) and in root folder
/Library/Developer/...
Open Xcode and clean again
Delete app from test device
Now it works.
I have a Swift project with three Swift custom frameworks. The App builds and runs successfully but when I try to upload to iTunes Connect using Application Loader I get the following error for all three frameworks:
ERROR ITMS-90206: "Invalid Bundle. The bundle at 'XXX.app/Frameworks/YYY.framework' contains disallowed file 'Frameworks'."
As discussed in this SO answer I have set the 'Embedded Content Contains Swift Code' to NO in the frameworks and YES in the App, but this error persists.
The three Frameworks are all my own (I am seriously considering reworking the project to avoid Frameworks altogether but that is a chore I would like to avoid right now).
I am not using cocoapods.
Any ideas on how to resolve this error?
The key to solving this for me was, in addition to ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES=NO, also setting EMBEDDED_CONTENT_CONTAINS_SWIFT=NO in build settings for all targets except the main app target. Had to clear out derived data, but after that all was well.
In (SE-0133) of the Xcode 8.3 Release note, there's a description about EMBEDDED_CONTENT_CONTAINS_SWIFT setting:
The new build setting ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES replaces the EMBEDDED_CONTENT_CONTAINS_SWIFT setting, which has been deprecated. This new setting indicates that Xcode should always embed Swift standard libraries in a target for which it has been set, whether or not the target contains Swift code. A typical scenario for using this setting is when a target directly uses or embeds another product that contains Swift code. (26158130)
which means ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES has replaced EMBEDDED_CONTENT_CONTAINS_SWIFT, thus you need to change the former one(ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES) to NO in the extension target.
So this is not a good answer, but it is what I did to resolve it:
I created a new project and copied in all my files - in a flat structure without Frameworks, editing just to remove the relevant import statements. It now uploads fine. So it is the Framework structure that is the root of the problem. Not sure if the idea of Swift embedded custom libraries is just broken or I was doing something wrong so still looking for better answers...
From the beginning of my project, I use a custom framework, let's call it "custom.framework". But there was a bug in this framework and now I want to use another version of the "custom.framework".
At first, I simply removed the "custom.framework" file from my project and added the new one. But nothing changed, the bug was still there.
After multiple tries and hours, I understood that Xcode add the old version in memory and used this one instead of the new version. I know it because in the new version I added a method and when I cmd+click the class I've add the method into, it's not there and the file's path is unavailable.
Searching through the web, I tried to change some version parameters to my framework projects: Compatibility version, Curent Library version, Framework version. But this didn't change anything to Xcode which keeps using the old version.
I also tried to make the framework's project as a sub-project and add resulting framework as a dependency to my target. It worked well, but as the framework's project is on a separated remote git repository, I don't think this is an acceptable solution.
So my last try was to build a "custom2.framework", to force Xcode to use the real file and not some cached version. But again, it doesn't work and when building I get errors telling me that all my classes in custom2.framework are duplicated symbols of its cached version of "custom.framework".
So my question is simple: how can I finally tell Xcode to deleted its cached old version and let me use the file I gave him? I already tried to delete my project's derivedData but it seems cached frameworks aren't there.... I'm so desperate :(
Edit: Here are 2 screenshots to illustrate the issue
First screenshot is the path as shown by Xcode when I opened the file from the .framework object in the project navigator.
Second screenshot is the path as shown by Xcode when I opened the file from a cmd+click to a "DCEquipmentManager" in code.
As you can see, the framework linked with the code is not the framework in the project.
it seems problem with binding in new framework, your project still linked with old framework files.
try to remove all files and folder related to your "custom.framework and also remove path for that framework from project setting--> build setting --> search Path
Then after Drag and Drop Your "custom.framework" files in project.
it works for me.hope it resolve your problem.
Please try to clear derrived data:
Window -> Organizer
at the right side you will see projects list. Find your project and tap on it. I the top part of window you will see button delete in front of Derrived data, tap on it.
I guess it will solve your problem.
It might sound silly, but sometimes restarting XCode or the whole machine fix things.
Did you remove the old framework from Build Phases --> Link Binary With Libraries?
Use Clean Build Folder: option-shift-command-K, or select it from the Product menu when holding down the alt/option key.
First lets say something upfront. The build stage is a(are) command line tool(s) that is managed by Xcode according to your Build Settings.
So when Xcode doesn't find your Framework - the Build System will usually also not find it. This forces you to act but may end up in confused Xcode to catch an older reference.
Yes it may happen that the Header Xcode is pointing to is correct but the build system still uses an old copy somewhere. An outdated copy can dangle around literally anywhere depending on the steps you took before.
It (Xcode) assumes where it is located but the Build System still uses another version or the Search Paths just pointing in the wrong Locations even if they are visible to you and even your Framework icons are visible in the lists. So when you erase the last build you actually only force Xcode to rebuild from the known arguments, the settings stay the same, the lists stay the same. Even restarting Xcode does not change anything, the problem persists.
Ergo: Compiler Instructions, Xcode settings and Build System settings don't match what the code tells with #import <NAME/Name.h>
So you will check at least those 6 stages again:
Is your Framework Header File published in your Framework project?
are Build Settings really pointing to the right Framework Search Paths or System Framework Search Paths?
Is your Framework in linking list?
Is your Framework in Embed Framework list?
Does your framework appear in the Framework Group Folder in Workspace/Project Browser? (usually the very last Group Folder in the Browser below all your other files)
Is my Folder Structure correct?
At least 1 to 4 must be right otherwise it will fail.
Here a random list of common causes
Framework is located outside your Source Paths structure
Structure got changed after you added it to the project
You use Workspace's where Framework development and Final Application can appear side by side but you assume Xcode uses this to change its Search Paths
The contained build settings are misleading from former drag and drop operations, ending up tricking Xcode in the "wrong" corner. In this case recreating a project is just one of the possible ways to fix it but not the solution.
Also dragging a Framework into your Project > General or separated in Build Phases > Link Binary list or Embed Framework lists does not make Xcode aware of the wrong Build Settings.
The Linking works, embedding works, but compiling does not. The Header information is still missing.
The solution must be to correct your Build Settings.
As mentioned above Build System and Xcode are two different things. In particular only setting the right Framework Search Paths will solve those issues, even if you managed to kick your derived data manually.
Erasing Derived data?
Derived data is the place where precompiler collects data to compile. So it can be seen as expression of what all the settings are told to do. Erasing it does of course not change the settings but may fix inconsistencies related to former Build Settings. It would erase the derived data and rebuild from the Build System Settings you gave.
Correcting Linking?
Also Linking is not the same as making Xcode aware of the desired Headers. Linking is for your final Product to know where Symbols are to call on them at runtime, it does not change Framework Search Paths and System Framework Search Paths, they stay the same as given.
But it is not wrong to start fixing first with
Product > Clean Build Folder, it forces your build to parse all and compile all again on the next Build.
When the troubles come up because of folder structure in parallel or Frameworks are simply placed outside the Source Directory then you must point to them directly or relative.
Most likely you should place one extra entry in your Framework Search Paths like $(SRCROOT)/../Yourframeworksource/build/Debug. expression to point to relative higher folder structure.
Needless to say that a Release Build likely needs another entry ending in "/Release".Hint: Well you can have different Search Paths for different Compile Schemes..
This works particular good after you cleaned Linking List, Embed Frameworks List and then also check the very last Group Folder "Frameworks" for double entries to drag and drop a fresh Framework reference in there.
How to know if leading /../ will fix it?
Click on the dropped Framework Icon inside the workspace Framework Group Folder (lower most) while your Project is the active selected to work on, now watch for the relative Path information on the very upper right side of Xcode, if there is some /../ you know you need it as well.
Sorting of Framework Search Paths
play a role of course, just the same as #import/#include rule sorting matters.
Remember the first found, first wins rule because often we use #import that works different then #include but ignores second attempts to declare. This leads to once wrongfully declared headers to hide corrected declarations later on in parsing that share the same filename or define rules
#ifndef xyz
#define xyz
// all your code here.
// a second read attempt would be ignored
// a second read is hidden also when you use #include then.
#endif
So you can sort those entries either by code and/or in the build settings if needed because of course it matters what is declared before other declarations depend on it.
I have a project that was started in Objective-C, and I am trying to import some Swift code into the same class files that I have previously written Objective-C in.
I have consulted the Apple docs on using Swift and Objective-C in the same project, as well as SO question like this, but still no avail: I continue to get the file not found error after putting in #import "NewTestApp-Swift.h" (NewTestApp is the name of the Product and module).
Here is what I have done so far:
In Define Modules, selected YES for the app.
Ensured that the Product Module name did not have any space in it (see screenshot below question)
I have tried using #import "NewTestApp-Swift.h" inside ViewController.m, ViewController.h and AppDelegate.m but none of them has worked.
What else am I doing incorrectly? Thanks for your help.
Screenshot of settings:
Errors that I am presently encountering:
I was running into the same issue and couldn't get my project to import swift into obj-c classes. Using Xcode 6, (should work for Xcode 6+) and was able to do it in this way....
Any class that you need to access in the .h file needs to be a forward declaration like this
#class MySwiftClass;
In the .m file ONLY, if the code is in the same project (module) then you need to import it with
#import "ProductModuleName-Swift.h"
Link to the apple documentation about it
https://developer.apple.com/documentation/swift/imported_c_and_objective-c_apis/importing_swift_into_objective-c
If the Swift code is inside a Module (like in your case):
#import <ProductName/ProductModuleName-Swift.h>
If the Swift code is inside the project (mixed Swift and ObjC):
#import <ProductModuleName-Swift.h>
In your case, you have to add this line in the *.m file:
#import <NewTestApp/NewTestApp-Swift.h>
IMPORTANT: look at the "<" in the import statement
https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html
How I managed to import swift into objective-c:
Defines Module set to YES (on project - not on target)
Product Module Name set (on target - not on project)
In your ViewController.m import the swift code with:
#import "MyProductModuleName-Swift.h"
Add a swift file to your objective-c project (File -> New -> Swift) and Xcode will create the bridging header from objective-c to Swift but this is crucial for making it work the other way around too - apparently.
For the last piece in this puzzle thanks to Swiftoverload for making me aware of actually adding a Swift file via Xcode GUI and not just dragging and dropping existing swift-files into my project for making it work:
http://nikolakirev.com/blog/using-swift-in-objective-c-project
Using Xcode 8.2.1 and if you look at Project > Build Settings > Objective-C Generated Interface Header Name, there it shows only one header file named like Product-Swift.h
This means that instead of importing each modules separately from Objective-C .m file, using individual -Swift.h file, you just import one Product-Swift.h which aggregated all Swift modules.
I encountered the same problem by looking for traditional way of importing modules separately, but the current version of Xcode and Swift 3 changed it to use only one header for all module importing.
Spent an hour on this issue, following these steps will help you to understand what's missing:
Open Xcode preference and navigate to DerivedData folder
Search for "swift.h" in finder
If you can not find any project-swift.h file, this file haven't been generated. You usually need to add #objc to one of your swift class and successfully build the app, only then will Xcode generate this file
If you found "xxx-swift.h" file, make sure your import statement contains the correct name.
I was having problems importing Swift into an Objective-C project. In the end I looked into the Derivied Data folder to check what Xcode 7 was generating. The filename was completely different to the one I was expecting.
Once I had the actual filename I imported that and the project could build.
iOS - Swift.h file not found
[Mixing Objective-C and Swift]
<name>-Swift.h should be created by Xcode automatically if Swift code expose an API via #objc or #objcMembers[About]
Usually a location looks like
~/Library/Developer/Xcode/DerivedData/
ProductModuleName-foo/
Build/
Intermediates.noindex/
ProductModuleName.build/
Debug-iphoneos/
ProductModuleName.build/
DerivedSources/
ProductModuleName-Swift.h
It can be changed by
Project editor -> select a target -> Build Settings -> Per-configuration Intermediate Build Files Path
By default the value is $(PROJECT_TEMP_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
Importing the header file, i.e.
#import "<ProjectName>-Swift.h"
within the .h file generated an error, stating:
-Swift.h' file not found
and the build failed.
Instead use:
#import "<ProjectName>-Swift.h"
within the .m file, and even though the same error appears, running the project anyway suppresses the error.
The swift classes are then available within the .m file.
If Your App name have any special character then use _ for special character.
For Example if your App name is Name "Test App®"
Then you can import swift file by "Test_App_-Swift.h".
Space and ® is replace by _ while you are import.
Make sure your swift class has the public declaration, and extends NSObject:
public class MySwiftClass: NSObject {
//...
}
The import should work with quotes, not brackets, if the swift class is in the same project.
if you add a Swift File first, rememeber to add swift file to your target..., in the left column
Had faced the same problem with my team when was working on project using git. One developer hasn't updated Xcode to the last version (7.3) which was required for latest Swift 2.2 version. So, compiler hasn't recognized new Swift syntax and couldn't generate interface for Swift library (projectname-swift.h).
Check if Xcode version is the latest one!
DEFINE MODULES: YES
and import "ProjectName-Swift.h" in .m file of Obj-C class
This worked for me to access Swift classes in Obj-c.
I had the same problem with #import "myProj-Swift.h" not found, Xcode 12.3, the year is 2021.
It appears that unless a bridging header has been generated, it is not possible to import myProj-Swift.h.
My (reproducible) solution, when needing to add Swift to objective-C projects is to create (File - New File - Swift file) a dummy empty Swift file in my project. Xcode then asks whether to create a bridging header, to which I answer yes. This causes a "myProj-Bridging-Header.h" file to be added to my project, which is visible in the Project Navigator.
Once this is done, the error on #import "myProj-Swift.h" disappears.
After that I can delete the dummy file, and insert the needed Swift classes into the project.
The logic of generating a visible bridging header, but leaving the -Swift.h entirely invisible escapes me entirely. Never mind the challenge of trying to find out about this in the official documentation Importing Swift into Objective-C, which (to me inaccurately) states "You don’t need to do anything special to create the generated header".
It is probably a good idea to also mind the answer from #Sandeep Bhandari to this question - who says the -Swift.h file will only be generated if the project compiles successfully.
More info also in this and this question.
I ran into this problem after duplicating an existing target. When I tried to build with the duplicated target, the "ProductName-Swift.h file not found" error appears.
After going through the build settings in the new target, I found the value of the setting "Product Name" somehow is set as the same as the target name. After setting it with the correct one the error disappeared.
If your product name is TestApp-Dev then filename will TestApp_Dev-Swift.h
You can verify by going to the following location
~/Library/Developer/Xcode/DerivedData//Build/Intermediates.noindex/yourProjectbuild/Debug-iphonesimulator/MashreqMobileApp.build/DerivedSources
If you want same file name for each build schemes then go to
Build Settings to be the same across your modules/schemes. (set it to $(PROJECT_NAME)-Swift.h).
If project name is TestApp, then the file generated will TestApp-Swift.h and it will remain same across the schemes
During development, there might be a possibility that you would have any swift class that is not completely implemented due to which there might be some syntax errors.
The swift header file will be available for use only if all the swift files are error free.
Make sure there are no syntax errors in the swift files and then try to import the swift header in the objective - c file
I faced the problem with the name of project (target). It included symbol "-". So the decision was next: if name of project is "Test-App", then name of imported class is "Test_App-Swift.h"
If you have multiple target make sure that you have build all frameworks
Xcode 11
I ran into this problem when building on Xcode 11. Took me a bit to figure out what was wrong, but essentially, I had changed the "Display Name" setting on the Target's "General" tab instead of changing directly in the Info.plist file through the "Info" tab on the Target.
This resulted in Xcode 11.5 going through an rewriting/creating a bunch of brand new custom build settings and modifying the name of the app module and the built .app product. In this case the new display name also had a forward slash (/) character in it which may ultimately be why it wasn't building (see #Silversky Technology's answer).
Regardless, I resolved this by undoing all of Xcode 11.5's automatic changes to the project file and manually making the same change to the bundle display name in the Info.plist file and everything works perfectly.
I wish it would tell you that it was doing stuff like this before it just up and does it without your consent.
Target executable was missing a dependency on my (or any other in fact) framework.
Build Phases -> Dependencies must list the dependencies of a target to avoid intermittent errors: in my case debug
build was fine and automated Jenkins CI builds were failing.
A nightmare to debug considering Jenkins output produces
voluminous garbage that's a huge time pit to get through.
We have a mixed code base in our WatchKit extension. In a couple of Objective-C files, we need access to the Swift code base from the extension. We've been using the following import:
#import "MyProject_WatchKit_Extension-Swift.h"
This has worked fine for the entire dev process.
I am in the process of moving to Xcode 6.3. After updating our code base to Swift 1.2, I'm getting File not found for my extension-swift file.
What I've tried:
Full clean w/ cmd + opt + shift + k
Deleted derived data
Deleted and reinstalled Xcode
Changed extension module name and used that import
Reverted to pre update commits and updated manually as opposed to the automated: `Convert > To Latest Swift>
Anybody have any thoughts.
It seems Xcode has changed it's default behaviour for file paths defined in the target's build settings. Previously it was happy to look recursively for a file within the project directory, so you could just define the file name and you were good to go. Now you need to prepend the folder name.
Go to your targets build settings and search for 'Objective-C Bridging Header', you'll probably see the entry 'MyProject_WatchKit_Extension-Swift.h'. You need to prepend the path to the file relative to the root project folder.
If your folder was structured as so:
PROJECT_ROOT_FOLDER
- CLASSES_FOLDER
-- MyProject_WatchKit_Extension-Swift.h
- .xcodeproj
- TESTS_FOLDER
Then you would need to change the value to
CLASSES_FOLDER/MyProject_WatchKit_Extension-Swift.h
I was able to figure out the answer by editing the Objective-C Generated Interface Header Name field in the extension's build settings. I had never previously edited this field, and I'm not sure how the value was removed. I'll leave this here in case others have the same problem: