Some of the frameworks are missing when I generate Xcode project through Unity. What would be the reason? How can I solve this?
I mean manually I have added them in Build Phases to fix the error, but why are they missing?
They're missing because they are required when you use those APIs.
If you're coming from a language like Java this might seem strange, but with Objective-C (which is ultimately C) you need to let the compiler know where the APIs come from beyond just the header file import.
Unfortunately, Unity doesn't provide any support for specifying additional frameworks for your Xcode project to link to. However, if you can you should generate and modify your Xcode project once and then subsequently always have Unity update rather than override the project.
Related
Does anyone have a guide to setting up a project that produces a static library under recent versions of Xcode? There are a few for older versions, but they use a project setting called "C/C++ Library" which seems to have been removed.
I notice "External build system" is still in there, and maybe that's a solution? The C code won't be changing structure too much, so a makefile could be a solution - but I've never used this type before, so I'd like to hear from people that have.
Ultimately the C code will be consumed by a Swift/Cocoa application. Am I correct in thinking that I simply include both projects in a workspace, drag the .a and bridging .h into the Swift project, and go?
I have a Swift demo project that comes bundled with my framework. I want to ensure that the Swift code in the demo compiles successfully with both Xcode 6 (Swift 1.2) and Xcode 7 (Swift 2.0) without user intervention.
Since there's only marginal preprocessor support in Swift, how can I determine at compile-time which version of Swift or Xcode is being used to compile the code?
Now, here's the important detail:
It has to work automatically!
Open the project in Xcode 6 -> compiles
the Swift 1.2 code.
Open the project in Xcode 7 -> compiles the Swift
2.0 code.
No build settings or other means that require the user to specify, one way or another, which Swift/Xcode version she is using.
I keep thinking: this is such a trivial task, how could that not be possible with Swift?
As a framework developer this is driving me nuts since a successful compile of a Swift project now entirely depends upon the user's version of Xcode, and I can't ask them all to "update to Xcode 6.4" and at a later point having to ask them all over again to "update to Xcode 7.1". This is insane!
The alternative would of course be to have separate demo projects, managing different code bases, one for each version of Swift. And hoping the user will know what project will work with her version of Xcode. Not a real alternative.
The other alternative, to simply not use any of Swift 2.0's enhancement, is unfortunately not possible either. There is syntax, classes and methods that won't work in one or the other Swift version, if only due to the compiler being more picky in newer Xcode versions.
You can accomplish this using some of Xcode's advanced build settings, in particular:
XCODE_VERSION_MAJOR: Which encodes the Xcode major version as a string like "0700".
EXCLUDED_SOURCE_FILE_NAMES: A "fnmatch"-style pattern of source files to exclude by default.
INCLUDED_SOURCE_FILE_NAMES: A "fnmatch"-style pattern of source files to include.
I would not generally recommend doing this, as it will make your project hard to understand for most Xcode users, but if you absolutely want to make it work you can use this technique.
The way you accomplish it is as follows:
For any source files which need to be versioned, name them something like "Thing-Versioned-0600.swift" and "Thing-Versioned-0700.swift". Make sure both files are in the sources build phase.
Use the excluded mechanism to prevent any versioned files from being compiled by default, by adding a project-level build setting: EXCLUDED_SOURCE_FILE_NAMES = *-Versioned-*.swift.
Use the included mechanism to only add back in files that match the current Xcode major version, by adding another project-level build setting: INCLUDED_SOURCE_FILE_NAMES = *-Versioned-$(XCODE_VERSION_MAJOR).swift.
Having 2 versions of the code inside your project won't work since the code would not compile. There is no compiler directive for conditional compiling based on a version.
There is one workaround that could work (did not test it)
First create 3 files named version_current.swift, version_1_2.swift and version_2.swift. Make sure that only version_current.swift is part of your build target.
Then create a new build script phase and place it right above the 'compile sources' phase. In that script you will copy over the content of either the 1_2 or the 2 version over the current.
My scripting knowledge is not so good, so I can't give you much help doing this. You can get the version with code like:
$ xcrun swift -version
And then just execute a copy statement.
But then this will only work for the default Xcode version on your system. When you want to use a different version, you also have to change the default version.
I added the iAd framework to my app, which has two targets. I am able to compile and run one of my targets, but the other does not compile. (The code that doesn't compile in one case does compile in the other case.) Apparently, the framework is not recognized or linked.
I checked the linked libraries in Build Phases for both targets, and the framework is listed. Most of my other libraries were added before I split off another target, and I didn't have this problem for most of them. I recall having something like this happen once before, where I went back into build phases and removed and re-added the framework. That resolved the problem. (I don't remember exactly what I did that one time, though.) I tried this again, and it still does not work.
What can I look for to see what is happening and how I might fix it?
I'm compiling for a target with iOS 5.0 using SDK 6.0.
Make sure your iAD framework is set as a member for the second target.
In other words, look at the file inspector for your iAD framework and make certain the checkmark is checked for both targets.
Here is what it looks like just for a .m file... it would be the same case for the framework:
The documentation for the project says just add the framework and the linker flags and you are good to go. Hours and hours of wasted time later, I have figured out that that's not true. If you do that, the project does not see the header files. You have to put the framework somewhere were the compiler will find the headers. In my case, that worked when I dropped the framework into /Developer/Library/Frameworks and then told it to recurse in searching that framework directory (do not fiddle around with the headers search directories).
Then the problem I get is that the link fails with the message:
ld: framework not found OCHamcrestIOS
I noticed that the documentation for the project says that it was updated for Xcode 4. I pulled down the binary of the framework after checking out the code and wasting a ton of time unable to build the IOS version of the framework.
The documentation is here.
I also noticed in that documentation that the cocoa instructions tell you to put a copy files phase into the build. I tried that. Didn't change the outcome.
The last time I fell into a sink hole it was because the library was C++ code. Maybe that's still the problem.
Barring a rapid solution here, I am going to go back to using STAsserts, as sickening as that prospect is, this is far, far worse.
Update: reinstalled Xcode. Still doesn't work. There are cheap ways to make this work, like add the header files to the project. Did a blog post about this that brought out a person with the same experience.
I use a number of frameworks in my projects. Some from other people and some are mine. Looking at the documentation I would suggest that the copy phase stuff is not for iOS development. So I would not do that. I downloaded the latest zip from https://github.com/jonreid/OCHamcrest and it appears to contain a ready to go iOS static library. (Not on my mac so I cannot test to confirm).
Anyway, the way I include static libs is to
Select the project (XCode 4).
Select the target I want to add the library to.
Select the Build phases tab.
Expand Link binary with Libraries.
Click the [+] button to add a framework.
Click the [Add Other ...] button and navigate to the directory containing the <lib>.framework directory and select that.
Thats all. The targets search paths will be updated to include the framework directory and the framework will be listed on the left under the project. Expanding it will show the headers.
The problem you mention sound like a couple of things. Firstly the framework not found sounds like the framework has not been included in the target. When you select the framework in the project list on the left, you should be able to see it's Target Membership displayed on the right. Check it's on for the target you are compiling.
Secondly building frameworks is not a trivial task so don't attempt it unless you have the scripts to do it. I say this because building a iOS static framework means compiling for both simulator and devices, combining the compiled lib files into a universal one, and then storing it and the header in a specific directory strucuture.
The downloaded zip from OCHamcrest though, appears to have the correct OCHamcrestiOS.framework in it. So if you store that directory somewhere and link to it using the steps I've outlined above it should work just fine.
So the solution I adopted for now, after much thrashing around, was to include the framework in the project.
Create a group inside the Xcode project called Third Party.
Link it to a folder called thirdparty.
Go to the Add Files in Xcode and pick the framework.
Drag it over to the dependencies.
Run the tests, they pass!
This is maybe preferable anyway because referencing it in /System/Library/Frameworks would present some versioning issues, and this can be setup very quickly. Furthermore, we have a continuous integration server, and having to get in there and sync versions whenever something changes is not so great.
Thanks for checking it out, Derek.
For example, if I created a framework that put together Ogre3D with RakNet and OIS, and I only wanted to have to distribute my framework for recompilation, is that possible?
I tried doing something like that, but I was getting linker errors. That would seem to suggest that you can't do that (and that's fine), but I want to make sure I'm not missing anything.
That's possible as long as the person doing the compiling has all those other frameworks. I'm not sure what you would want Xcode to do for you.