How to set the XCode FILEHEADER macro when using Swift PM? - xcode

I am working on a Swift package command line tool that has a third-party dependency. It has been working great just opening the repo folder and using SwiftPM, except that I don't seem to have control over the default file header. In other projects that have used an .xcodeproj or .xcworkspace, I was able to control this using the steps outlined here:
https://medium.com/#silmy/how-to-easily-change-your-file-header-text-in-xcode-347fa77d76f4
Putting the Plist in the Xcode data directory isn't what I want since the header could be different for different projects, and in any event I want to commit it to the repo so anyone who might contribute files to the project will use the same header.
We have tried simply creating an Xcodeproj or Xcworkspace using CocoaPods or Carthage, and have run into extremely frustrating issues. CocoaPods says that command line tools can't use third party dependencies, which seems untrue since it works fine when running purely in SwiftPM, and Carthage just completely fails to run correctly on my machine.
Does anyone know a way to set the default file header using SwiftPM in a way that can be committed to the repo and not require other dependency managers?

Related

Getting 'no such module RealmSwift' error after taking a checkout of the code

I am using RealmSwift in my project. I followed all the instructions while setting up Realm for my project, like dragging the frameworks into the embedded binaries section, setting up the framework search path and including the required Run script in Build Settings. The project works fine after that. Then while committing the changes, I committed the header files and bcsymbol files etc of the included Realm frameworks.
After that, I took a checkout of my project. After the checkout, on opening the project, I am getting this error: 'No such module RealmSwift'.
I tried deleting the frameworks and adding them again, and cleaning the project. The project just won't compile. It keeps giving the same error. What am I doing wrong?
Hmm, there's no real good answer for solving this sort of problem, as it can happen for a variety of reasons.
More often than not, like in this SO question, it can be caused by the Framework Header Search not being set up correctly, and so the project isn't able to see the framework correctly.
If worse comes to worse, make sure to absolutely delete every reference of RealmSwift in your project (Including in the build settings) and try installing it from scratch again. Good luck!

Why I can't submit or validate project in Archives organizer (XCode)? [duplicate]

I have a problem generating a iOS App archive from an application. The application compiles just fine and even works in the simulator. Now I wanted to make som ad hoc testing and cannot generate the iOS App Archive. When I click on the Product -> Archive it generates a generic xcode archive. Can anyone help me. I should mention, that I have already generated an iOS App Archive of this application. It has just stopped to generate iOS Archive for some reason. Thanks a lot.
Check Build Settings:
Skip install is NO for the main project target
Skip install is YES for framework (sub-projects) targets
In Build Phases for sub-projects, Copy Headers needs to be in Project, not Public (does not apply if building static library)
Installation Directory under Deployment is valid (/Applications for example)
This can happen if you've added a framework/library ... you need to edit the Target->Build Settings of that library and set the 'Skip Install' setting to 'Yes'. When you re-archive, XCode should start producing a 'iOS App Archive' again rather than a 'generic xcode archive'.
In addition of Skip Install to Yes and in case you opened another lib/framwork project within your app project you have to move headers (if any) from public to project in the Build Phase / Copy Headers.
I did the following to make it work for me:
I had a three20 static library, I used cocoapods to include the files within the main project
followed the skip install for all other sub projects/static libraries and switched the copy headers from public to project as stated above
most importantly: in each library your project uses go to build phases -> Copy Files and ensured that destination is changed from Absolute path to products directory. Note: see the hint below to narrow your search to find the library causing this error.
and that was it!
hint: to get an idea of the offending files that's causing your archive to create an archive file rather than an ipa do this:
Select the archive and click the Distribute button.
Select the 'Save Built Products' option.
Hit Next and Save.
Browse the created directory in Finder.
The 'libraries' subdirectory will identify the libraries that you need to set the Skip Install to Yes.
in some cases usr/local/include will identify the culprit header files you need to move from Public to Project or the files that you have to change from absolute path to products directory (or even the files you forgot to set the skip install to yes flag). but that directory (ie usr/local/include) varies depending on your sublibrary directory structure. In many cases.. you will see all the files listed under Copy Files in step 3 above listed here. If you find them here, then you have a definite answer for the cause of your problem.
update to hint: to make life even more simpler.. whatever files appears under step 4 in hint above.. simply search for it in the global search of xcode.. and you should get immediate results for what you want.. for example, this was the content of my folder (following the steps in hint above):
So I could tell it has something to do with the crypto and ssl libraries.. searching for them:
made me realize that i forgot to set skip install to yes.
If you export the archive, open it and see /urs/local/include in Products try this suggestion:
In each pod, under Packaging, Private Headers Folder Path and Public Headers Folder Path is set to /usr/local/include. If I clear them then I get a valid archive.
Worked for me after upgrading my React Native app to 0.11.0, Xcode 7 and CocoaPods 0.39.0.beta.4.
If you're using CocoaPods as well as WatchKit or a Today Extension, there is an open issue on the CocoaPods repo explaining what your problem might be.
The solution for me was to remove the Copy Pod Resources phase from the WatchKit Extension and Today Extension targets under Build Phases. The project compiled and archived as expected once I did this.
Hope this helps someone, this had me stumped for an entire day!
If any of the above answers don't work, your issue is probably with cocoaPods. The latest update 0.38.1 messed things up for me, but then i downgraded to 0.37.1 and things returned to normal. Using Xcode 6.3.1
Later edit: updating to 0.38.2 will also fix this. More info about what caused this issue here: Cocoapods 0.38.1 failed to create valid Archive
Although I'm using Xcode5 and what sorted it for me was editing the Build Scheme - trying all of the above suggestions that were applicable didn't help in my case.
I had two targets, say, "App" and "App FREE". My problems with the generic archive happened when I was trying to Archive the FREE version, which I added after the 'normal' version of the app. In my case, when I selected its Scheme in the toolbar and chose Edit Scheme ... I saw that Build section had two targets, namely App and App FREE.
I unchecked all columns for App, leaving only App FREE's columns checked, and clicked OK. Next time I chose Product > Archive I got my App FREE instead of a Generic Archive. :)
If you have only single project, maybe this solution would be useful.
This problem had occurred, when I duplicated the target. As a result I had two targets parallel built. This was causing the issue. Generic IOS archive was built.
To turn the parallel built off go to
Manage schemes,
Edit scheme,
Build,
Remove the other target.
I had this problem after updating to iOS 9 and Xcode 7. Josh H's solution worked for me:
In each pod, under Packaging, Private Headers Folder Path and Public
Headers Folder Path is set to /usr/local/include. If I clear them then
I get a valid archive.
I also made a post install script for my Podfile to do this automatically!
post_install do |installer_representation|
installer_representation.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['PUBLIC_HEADERS_FOLDER_PATH'] = [""];
config.build_settings['PRIVATE_HEADERS_FOLDER_PATH'] = [""];
end
end
end
Just add it to the bottom of your Podfile and run pod install
I had this issue. In my case, it was caused by keeping a Mac app target as a dependency of the iOS app.
The reason it was setup like this was that the Mac app was a tool used to generate some data for the iOS app, which was then included in the bundle.
I had to remove that dependency and build the tool separately before making a build of the iOS app itself.
In my scenario I was getting the erroneous "Generic Archive" only after I began including Swift code in my predominantly Objective-C project. After lots of troubleshooting and examination of the archive file that Xcode was spitting out, I noticed that the SwiftSupport folder (with the required dylibs for the Swift runtime) was in a different place in my archive than from a vanilla brand-new Swift project app archive.
I found the Installation Directory build setting and noticed it was set to a custom path in my project. I simply deleted it (setting it to its generic value of /Applications) and the next Build -> Archive I did worked as expected and gave me a proper iOS App Archive.
TL; DR: Make sure your Installation Directory build setting is set to its default value of /Applications when including Swift code in your app, especially if you are starting with an older project file that may have some unexpected legacy build settings.
I have multiple project in my workspace, (GTL, Pods and my main project) and this is what worked for me:
Select the Project, there will be 2 types there, there's the Project and there's the Targets.
For projects that is not your main like GTL or PODS:
Projects:
Skip Install = NO
Installation Directory = /Applications
// For pods
Private Headers Folder Path = ""
Public Headers Folder Path = ""
Targets:
Skip Install = YES
Installation Directory = /Applications
// For pods
Private Headers Folder Path = ""
Public Headers Folder Path = ""
For the main project (which is usually named the same as your product name):
Projects:
Skip Install = NO
Installation Directory = /Applications
Targets:
Skip Install = NO
Installation Directory = /Applications
Check the ios deployment target on each projects and targets to make sure they are all the same.
Leaving this here to save others from the same journey.
I found I needed to remove the same Copy Pod Resources build phase from a static library target in my workspace too.
Addition to Alex L 's answer.
Point 3. Change 'Build Settings' -> 'Public Header Folder Path' to 'include/xxx' also works.
If none of the above helped you...after a lot of time.......
I deleted the value in the Info.plist for Bundle Version because I was happy enough with just Bundle Version Short 1.0. Bad. Don't do this.
*Note I actually did this by editing it in the UI on the right not realizing it would put an empty key in the Info.plist file. I think that makes it invalid. My bundle showed up as other items while archiving and had no icon, and I couldn't upload to anywhere.
This boils down to invalid values in the Info.plist. If it's not a valid archive, try unzipping an old archive and dropping in / overwriting your current one and see if it fixes it when rebuilding the archive.
Go to Build Settings and add
yourAppName/Resources/dist.plist to the Code Signing Entitlements
Press cmd + B with iOS Device or a Real Device selected as Build Target
When done -> scroll to "Products" folder and right-click on yourAppName.app
Choose "Show in Finder"
Create a folder with Name Payload (capital "P")
Copy yourAppName into your Payload Folder
Create a zip from your Payload Folder
Rename the zip to yourAppName.ipa
DONE
After trying just about everything:
Clean, Archive
delete DerivedData, Archive
restart Xcode (I was using XCode7), Archive
combinations of above...
I then noticed my boot partition was 'low on free disk space'... about 1GB or so.
I rebooted, then got about 18GB free.
Then opened Xcode and project, performed Archive... and surprisingly (after an hour of trying to build an Archive) I finally got a non Generic Archive.
No idea if its a free disk issue which fixed it or a reboot of the macOS that fixed it, but it worked for me.
If you have any .xcodeproj files in Project>Targets>Build Phases>target dependencies remove it from there and then build your ipa. It works for me. Cheers
You can get answer here : xcode is creating generic xcode archive instead of iOS App Archive
In my case, i had to move both FMDB and BlocksKit to static libraries. Previously they were built as subprojects. Remember you can use lipo to create universal libraries. When building the final products, the simulator code will be stripped automagically.
Another possible reason for this is to have references in "Target Dependencies" to projects for a different platform. In my particular case, I was working on a project that shares code for OSX and iOS. In one of the iOS targets, I had accidentally added an OSX target as dependency.
In order to be thorough, I am posting my solution.
I experienced the exact same problem trying to build an Archive of an iOS project in Xcode 5.1.1 (5B1008). None of the above suggestions fixed the problem, and most of them were irrelevant (I had not added any Frameworks, and did not have any Public entries in the Copy Headers section of my Build Phases).
In my case, fixing the problem consisted of simply closing my project, deleting any archives that I had previously made, going to Preferences > Accounts, removing my developer account, quitting Xcode, relaunching, re-adding my developer account, starting the Archive process again. This fixed my problem immediately.
One more solution, since all the above didn't work for me...
Changed the User Header Search Paths (I suppose Header Search Paths would work just as elegantly) to "$(BUILT_PRODUCTS_DIR)/BlocksKit".
Background:
In BlockKit, the developers have structured the headers in the main project differently than the structure on deployment. So, you can't reference the headers in the project, and must reference the headers copied into the build directory.
The way this worked for me in (Xcode 5) I had 2 targets and when I edited the scheme, on the left pane of the scheme editor, you will see the [BUILD, RUN, TEST, PROFILE XXX.APP, ANALYZE, ARCHIVE] from the BUILD pane, you will see your project targets listed in a list. At the far right end you will see the ARCHIVE selections, make sure only one target is selected for archiving.
I had 2 of my targets selected in my project, I checked only the target I wanted in the product, and it worked!
I solved this error by opening solely the app project in XCode, ie. not opening a workspace comprising the application and other projects/libraries/frameworks.
Having 2 separate project, a framework or shared library and an iOS application, I had to open 2 different XCode windows, each by directly opening the .xcodeproj file instead of the common .xcworkspace, in order to preperly build each.
As a nice side effect, XCode no longer rebuilds every target of every project after I do a Clean, resulting in shorted build times.
Background: I am creating an open source SDK, and a demo iOS application. I had both opened in a single workspace.
Setting Skip install to YES on the SDK targets would prevent anyone from creating an archive, as it would be empty, so this was not an option. Using Project instead of Public headers would lead to an archive missing the header files that should be distributed, so this was not an option either.
For it was because i was working in a workspace.
The project did archived but would ne be displayed in the organizer window.
I closed the workspace and open the project on its own.
The archived has been opened in the organizer ... hope it's help.
In my case, I had a custom script that was copying some temporary files into:
${TARGET_BUILD_DIR}/myTempDir
That meant that, after investigating the archive to inspect its contents, I found right next to the .app file a myTempDir folder. Once I modified the script to save elsewhere things were sorted.
Try setting $(PROJECT_NAME)Headers in Framework projet's Public Headers Folder Path. You have to go to build settings of the Library Target then edit the Public Headers Folder path as $(PROJECT_NAME)Headers.
If using Xcode 7 with cocoapods v.0.38.2. Try removing copy pod resources from your today extension target.
I encountered this problem after adding a OS X command line tool to my iOS app's project, and Skip Install was set to NO by default for the command line tool's target. Since you obviously can't install an OS X binary to an iOS device, archiving defaulted to a generic Xcode archive. Setting Skip Install to YES for this target fixed the problem.

Does it make a difference to use the GitHub app when integrating Xcode with GitHub?

My team is using GitHub with Xcode. We use the GitHub application for OS X to commit, branch and sync. The problem is that when two or more developers add files to the project, conflicts occur in the 'project.pbxproj' file. Recently I realized there is a commit/push/pull option in Xcode.
If I stop using the GitHub application and use Xcode's commit, push, pull and merge, would those conflicts in 'project.pbxproj' file stop occurring?
You can still have conflicts.
If somebody makes a change to the project file and you make a change to the project file and you try to commit it at the same time as (or soon after) the other person, there's a good chance you'll see conflicts.
Thankfully, the "project.pbxproj" project file is text which can you can open with your favorite editor (vi or emacs or whatever) and you can resolve the conflicts rather easily.

xcodebuild says does not contain scheme

I have a curios issue.
I have a project that I've worked on and always built from the XCode IDE, and it worked fine. Now I'm setting up Bamboo to build the project and as such am building it from the command line.
The issue is, if I check my code out of GIT and then use xcodebuild to build it it says that the scheme cannot be found, but if I open the project, it builds and if I then try to build it again from the command line with the same command, it works.
What magic is XCode doing when I open the project or am I doing something dumb, maybe excluding a file in my .gitignore that I shouldn't?
You are definitely on the right track with respect to the .xcscheme file -- I had this problem appear while setting up my own projects!
For posterity, or at least anyone getting here from a search, here are two versions of things -- the "I'm busy, so just the facts please" version and a more involved discussion and rationale. Both of these versions assume you are trying to build from a Workspace file; if you aren't then my apologies as this mostly applicable to workspace-based projects.
Condensed 'Fix-it' Version
The root cause is that the default behavior of Schemes is to keep schemes 'private' until they are specifically marked as shared. In the case of a command-line initiated build, the Xcode UI never runs and the xcoderun tool doesn't have its own cache of Schemes to work with. The goal is to generate, share, and commit the scheme you want Bamboo to run:
On a clean working copy of the code, open your Project's workspace.
Choose Scheme > Manage Schemes... from the Product Menu.
The list of Schemes defined for the project appears.
Locate the Scheme Bamboo is trying to run
Ensure the 'Shared' box is checked for that scheme and that the 'Container' setting is set to the Workspace and not the project file itself.
Click 'OK' to dismiss the Manage Schemes sheet.
A new .xcscheme file has been created in your project at WorkspaceName.xcworkspace/xcshareddata/xcschemes.
Commit this file to your repository and run a Bamboo build.
Deeper Discussion and Rationale
Xcode 4 introduced Workspaces and Schemes as a way to help try and tame some of the chaos that is inherent to dealing with the mechanics of wiring related Xcode projects, build targets, and build configurations together. The workspace itself has its own set of configuration data that describes each of the smaller 'boxes' of data it contains and acts as a skeleton for attaching .xcodeproj files and a set of shared configuration data that gets mirrored to each developer machine or CI system. This is both the power and pitfall of Workspaces -- there are 1) lots of ways in which one can get things configured 100% correctly, but put into the wrong container or 2) put into the correct container, but configured improperly thus rendering data inaccessible by other parts of the system!
The default behavior of Xcode 4 schemes is to automatically generate new schemes as projects are added to the Workspace file. Those of you that have added several .xcodeproj files may have noticed that your scheme list quickly becomes unruly especially as project files are added, then removed, and then readded to the same workspace. All schemes, autogenerated or manually created, default to being 'private' schemes visible only to the current user even when .xcuserdata files are committed with the project's data and configuration. This is the root cause of that cryptic build error Bamboo reports from xcodebuild -- Because Bamboo operates the build through the command line and not the Xcode UI, it doesn't have an opportunity for Schemes to get automatically generated and relies only on those that are defined in the workspace itself. Assuming you've configured Bamboo to build from a workspace using a command like this:
xcodebuild -workspace MyWorkspace.xcworkspace -scheme MyApplication -configuration Debug
xcodebuild goes looking for file <'scheme' Parameter Value>.xcscheme existing at <'workspace' Parameter Value>/xcshareddata/xcschemes.
Obviously there are bunches of ways in which one could configure both Bamboo and a workspace, so keep in mind that your unique configuration may not map 100% to what is presented here. The key takeaways:
Certain automated tasks the Xcode UI magically takes care of are not available via the Xcodebuild CLI.
You can attach scheme and build configuration data to many places in the 'container hierarchy' -- Make sure your data winds up in the right container (Workspace, Project, and/or Build Target)
Consider where in the container hierarchy the xcodebuild tool may be looking for configuration data; a great indicator of where it will start looking is based on the use of '-workspace' or '-project' arguments.
The 'Shared' box is already checked...now what?
I encountered this same issue on my own Bamboo instance; it turned out that the scheme that was committed in my repository was outdated and the latest version of the command line tools wasn't handling it gracefully. Since this existed previously, I took a look through the settings to make sure there wasn't anything glaringly custom about the scheme, deleted and recreated the scheme ensuring that I marked it as 'Shared', and recommitting the new .xcscheme file to the repository.
If everything looks good and rebuilding it doesn't solve the issue, double check that container setting -- it is really easy to get that scheme attached to the wrong container in the hierarchy!
Debug the issue like this:
xcodebuild -list
or if you are using a workspace (e.g. with pods)
xcodebuild -workspace MyProject.xcworkspace -list
If you scheme is not listed fix like so:
Most of the answers would suggest you to make your scheme shared using Xcode, then commit changes to repo. That works, of course, but only if you have access to source code and have rights to commit changes, and couple of other assumptions.
But there's a number of "what ifs" to consider
What if you just can't modify the Xcode project for some reason?
What if you create a new scheme automatically on CI server? This actually happens quite often. If you use test automation framework, like Calabash, you'll normally end up duplicating an existing target, which automatically duplicates a scheme as well, and the new scheme is not shared, even if the original scheme was.
Ruby & xcodeproj gem
I would recommend using xcodeproj Ruby gem.
This is a really cool open source tool that can help you to automate tons of Xcode-related tasks.
Btw, this is the gem used by CocoaPods to mess around with your Xcode projects and workspaces.
So install it
sudo gem install xcodeproj
Then write a simple Ruby script to re-share all the schemes, the gem has recreate_user_schemes method for that purpose
#!/usr/bin/env ruby
require 'xcodeproj'
xcproj = Xcodeproj::Project.open("MyProject.xcodeproj")
xcproj.recreate_user_schemes
xcproj.save
It doesn't just copy scheme files form user's folder to xcshareddata/xcschemes, it also creates those files first by parsing the pbxproj file.
Ok I know its 2 minutes later but I found another stack overflow that says the scheme has to be set to shared... Where does Xcode 4 store Scheme Data?
One common reason for the scheme to be missing is forgetting to push the commits to the origin. If you get a missing scheme message, you should first verify the scheme is shared, then verify you have committed the changes AND pushed them to the origin server.
I had this error while implementing CI.The Question above is identical to my problems except I am using Gitlab's own CI tool.You can check if there is any such file in Bamboo.
I solved it by making some changes to gitlab-ci.yml file.
After you hav made your scheme availabe by sharing. In Xcode Go to Products>Scheme>Manage Scheme and check share to share.
Changes
Set absolute path everywhere.
eg.xcodebuild clean archive -archivePath /path/to/your/project/build/testDemo -scheme testDemo | xcpretty
here you need to change /path/to/your/project/ with your path and testDemo with your project name.
I faced this issue and even if some of the answers here actually provide the solution, I didn't find it very clear. So I will just add one more. In a nutshell how to share a schema from excode.
Navigate to Product > Scheme > Manage Schemes
You will then be shown a list of schemes, with each denoted as being shared or not. Just check the ones that you want to share (it may be different ones for dev and prod builds)
Images taken from this article https://developer.nevercode.io/docs/sharing-ios-project-schemes
Got the same problem but during building with xcode as subproject of main one. Built subproject in xcode standalone - after that this error disappeared.
I want to add solution for my case related to this thread. This one is for you who clone existing project, with all the schemes you need are already being shared:
, with fastlane lanes correctly display all your lanes including all your schemes:
, but fastlane gym only show main schemes (not dev and test schemes):
The solution is to uncheck the shared option for schemes that not listed by fastlane gym and then check it again. It will generates .xcscheme for the schemes:
Now, if you check with fastlane gym, all the schemes will be listed:
Then you should commit those .xcshemes file to the repository, so other developer who clone the project will get the files.
For anyone with Xcode 11.4 trying to find "Shared" button on scheme, it's now moved into the individual scheme.
Select the scheme you want
Press "Edit"
Check the "Shared" box

XCode Source Control File Owner

I am using XCode 4.5 and I use the build in Source control, I have modify a file and still not committed, I tried to access this file form another iMac and modify the same file and there is no problem with modifications.
The issue is how I can own this file and no other developer can modify it until I commit it?
Using git? You don't. That's not how git works, there's no concept of "file locks" and they wouldn't make sense in a distributed version control system. You'll have to actually talk to the other developers if you think it is important to avoid merge conflicts on that file.

Resources