Xcode 4.5 doesn't find deprecated functions - xcode

my problem is that i can't visualize deprecated warning in xcode 4.5. like viewDidUnload or presentModalViewController.
I checked the flag "Warn About Deprecated Functions" and is correct (YES).
I tried to create e new project and copies all files, but i get the same result.
I tried to building with two available compiler LLVM GCC4.2 and Apple LLVM 4.1
The strange thing is that other project has found all deprecated functions correctly.
Any idea?
Thanks

It seems that these warnings are based on your deployment target. (And not the base SDK, which is what I expected.) This seems like a wise choice, since in order to get rid of the warnings, there's a good chance you'll need to use newer methods that didn't exist yet in the older SDK.
So if you want to make sure you're seeing every deprecation warning, select your target in the Targets list, and set the Deployment Target to the latest version. Do a build or choose Analyze from the Product menu, and you'll see all the warnings.

Related

How can I force Xcode to use a custom compiler?

I want to force Xcode to use a custom compiler ('clang-llvm' build from the src) so I can use the clang plugin. My Xcode version is 7.3.1.
People say it is possible with custom toolchains. I didn't make a research on them because easier solution worked well for me:
It is also possible to run frontend plugins directly by setting appropriate "build settings" of Xcode. (Several ways to do this, you can set them on the command line for instance: xcodebuild build FOO=bla.) Here are a few build settings that I found useful to inject C flags:
OTHER_CFLAGS, OTHER_CPLUSPLUSFLAGS or to replace the compiler(s) and linker(s):
CC, CPLUSPLUS, LD, LDPLUSPLUS, LIBTOOL
The same approach works to control the "analyze" action: CLANG_ANALYZER_EXEC, CLANG_ANALYZER_OTHER_FLAGS
Disclaimer: some of those build settings are undocumented (afaik). Use at your own risk.
(Taken from [cfe-dev] Compile/refactor iOS Xcode projects)
For me it was enough to define the following User-Defined Settings in Build Settings of Xcode projects:
CC=my-c-compiler
CXX=my-cxx-compiler
LIBTOOL=my-linker-for-static-libraries
If you use CMake, the way to inject your compiler automatically is to use
set_target_properties(your-target PROPERTIES XCODE_ATTRIBUTE_CC "${YOUR_CC}")
set_target_properties(your-target PROPERTIES XCODE_ATTRIBUTE_CXX "${YOUR_CXX}")
Couple of years ago I've written an article that addresses exactly the problem you describe: Creating and using Clang plugin with Xcode
To enable custom clang you need to actually patch internals of Xcode.app itself, it is technically doable but:
it will break when you update Xcode
it will work correctly on your machine
the version of a plugin and your compiler should match, i.e.
they should be compiled using the same tree
So in general it doesn't really scale, so be careful :)
There's a somewhat obscure feature of Xcode where it supports "alternative toolchains". For example, Swift.org provides installable toolchains for Swift built from current sources.
Unfortunately, while Apple's documentation describes how to install and use such alternative toolchains, it doesn't describe how to create them. There are scripts in the Swift source base which build a toolchain and you can look at them to figure out how it's done. They are in https://github.com/apple/swift/tree/master/utils. Start at build-toolchain, which calls build-script and go from there.
Method 1: Change the User Defined settings
Under the project or target Build Settings add the User Defined settings for
CC=/path/to/cc
CXX=/path/to/c++
This is useful if you have a single compiler or linker you want to call, or if you want to call out to a trampoline that decides what to call on the fly.
Method 2: Create a complete custom toolchain via plugin
Using Clang LLVM 1.0.xcplugin as a template (found in the Xcode.app plugins folder), you can modify the plist to point at your own alternative compiler and linker.
This OLLVM on iOS tutorial walks through it.
From project setting go to build setting with target selected. then select All beside the Basic from the top bar. then under build option you can see the compiler option.
Refer below screenshot,
Update :
I think you should refer Using C and C++ in an iOS App with Objective-C++ and this tutorial.

How can I suppress the Xcode 7.3 warning "String literal is not a valid Objective-C selector"

I am working on a project with some of use on Xcode 7.2 and some on 7.3 (including myself). We don't want to force everyone to upgrade to 7.3 (most would also have to update their OS and we are closing in on release date).
If I use #selector() as advised by Xcode for the new syntax anyone running 7.2 is unable to compile the project as they get an error. Using Selector("…") allows the project to compile on all versions but it creates a warning that I would love to suppress (with a TODO next to it for removal once everyone has upgraded).
Is there any way to suppress this warning, or should I just live with it for now as a price of being fast to upgrade?
Update: By adding #objc before the function in question the original warning changes to Use '#selector' instead of explicitly constructing a 'Selector', and it is willing to make the change for me making the code un-compilable on Xcode 7.2 or earlier.
As the issue isn't a deprecated method neither of the two existing answers work in this case (I would use the #avaliable option to continue getting warnings about any other deprecated methods and make case-by-case decisions on each though).
There is a workaround:
#available(iOS, deprecated=10.0)
func _Selector(str: String) -> Selector {
return Selector(str)
}
But you have to use _Selector instead of Selector in your code, And I'm not sure if Apple approves of this, so before submitting to AppStore, I Suggest remove #available(iOS, deprecated=10.0).
Credit of using #available goes to Daniel Thorpe for his answer here
Isn't this working?
On your target Build settings: All
Apple LLVM Warnings - Deprecated fonctions -> NO

How to conditionally compile version-specific Swift (1.2 vs 2.0) code in the same source file?

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.

Framework Not Linking in XCode 4.5

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:

Easy way to detect if I am using framework not available to older iOS

After a marathon coding session, where I added too much code without keeping track of everything, I now have an app that probably has some iOS 5.0 and 5.1 specific enums, calls and frameworks, however, I want my app to support iOSes back to 4.3.
I was hoping that there was an easy way of setting Xcode to compile as if it were compiling for iOS 4.3, so that I would get errors for all of the offending code that needs to be conditioned out, and/or alternatively coded, for older iOS.
I thought I'd get that by using the compiler option:
-D__IPHONE_OS_VERSION_MAX_ALLOWED=__IPHONE_4_3
but that ends up generating error in system header files, not my code.
Given that most enums and frameworks have their availability included in the header files, I have to think that there is an easy way to do what I need.
Has anyone managed to do such a thing without resorting to downloading older Xcodes with old SDKs? There I may run into the issue of Xcodes that won't function properly under Lion (which is what I am running).
UPDATE: It appears as though I can't install Xcode 3.2.6 on Lion. I now will have to find a Snow Leopard Mac, unless I find a way to use compiler options or forcing Xcode to use old SDKs...
Here is a sample of what #mattjgalloway's answer did for me:
Lumin App Group
/Users/mz/Dev/Working/Lumin/Lumin/MyUIScreen.m
'brightness' is deprecated: TOO NEW!
'brightness' is deprecated: TOO NEW!
'brightness' is deprecated: TOO NEW!
'brightness' is deprecated: TOO NEW!
/Users/mz/Dev/Working/Lumin/Lumin/LuminViewController+Share.m
'TWTweetComposeViewController' is deprecated: TOO NEW!
'TWTweetComposeViewController' is deprecated: TOO NEW!
'TWTweetComposeViewController' is deprecated: TOO NEW!
/Users/mz/Dev/Working/Lumin/Lumin/LuminViewController.m
'scrollView' is deprecated: TOO NEW!
'connectionWithMediaType:' is deprecated: TOO NEW!
'connectionWithMediaType:' is deprecated: TOO NEW!
'AVCaptureDeviceSubjectAreaDidChangeNotification' is deprecated: TOO NEW!
'setSubjectAreaChangeMonitoringEnabled:' is deprecated: TOO NEW!
Very nice.
I placed the following in my project's .pch file, and am planning on doing so for all projects:
#if DEBUG
#define __IPHONE_OS_VERSION_SOFT_MAX_REQUIRED __IPHONE_OS_VERSION_MIN_REQUIRED
#import "MJGAvailability.h"
#endif
For any project, I am now automatically watching for SDK issues based on the earliest iOS I am targeting. While there still may be SDK changes I have to worry about, at least I know of most framework additions that are unavailable to an older iOS release.
Take a look at my MJGAvailability.h here on GitHub. Basically it defines the right preprocessor #defines so that newer APIs will look like they're deprecated, so you get a compiler warning. There's some documentation at the top of the file, but basically you just do this in your PCH file:
#define __IPHONE_OS_VERSION_SOFT_MAX_REQUIRED __IPHONE_4_3
#import "MJGAvailability.h"
For if you want to support down to iOS 4.3.
It's certainly not 100% foolproof, but I find it incredibly useful for doing what you're asking.
If you want to suppress a warning because maybe you know that it's OK to use that API (you've surrounded it with a respondsToSelector for example) then you can do something like this:
UINavigationBar *navBar = self.navigationController.navigationBar;
if ([navBar respondsToSelector:#selector(setBackgroundImage:forBarMetrics:)]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[navBar setBackgroundImage:[UIImage imageNamed:#"navbar_bg.png"] forBarMetrics:UIBarMetricsDefault];
#pragma clang diagnostic pop
}
Sorry; completely blew that answer the first time. Let's try this again...
Deployment Target sets the lowest OS version you will work with.
SDK sets the highest OS version you will work with
Between Deployment Target and SDK, you have to conditionally check for APIs. See the SDK Compatibility Guide for details on that.
You probably just want to use the old SDK instead.
The easiest way to use old SDKs with newer versions is to save a copy of the .sdk directory and copy it into the new version when you upgrade.
You can, however, download the old stuff, too. Apple just hides it. Start in the Downloads for Apple Developers. Find the copy of Xcode you want. Download Xcode 4.1 for Snow Leopard; it includes iOS SDK 4.3. You can install it in parallel with Xcode 4.3, but you don't have to. Mount the disk. Open a terminal (it's just easier that way). Go to /Volumes/Xcode/Packages. You'll find all the SDKs there.
You can try installing it directly, and that may or may not work for you. You can also unpack the .pkg and get the files you want. I typically use a program called The Unarchiver. It can unpack just about anything. That'll give you a directory that includes a file called "Payload". If you double-click that, it'll expand (it's just a tar.gz that they don't include the extension on). That will give you the Platforms directory. Copy that into the Platforms directory in your copy of Xcode and you should be golden.
All that said, I once I've gotten the system working pretty well, I usually switch back to compiling with the latest and using deployment target. It makes it easier to collaborate with others who don't have the old SDK. And Apple may or may not reject due to linking with an old SDK. They've done that in the past; I don't know the current situation there (haven't had it come up in a while). But I'd tend to recommend submitting something built against the latest.

Resources