I came across this code and I was wondering if the #ifdef check is redundant.
UIButton *doneButton = [[UIButton alloc] init];
...
#ifdef __IPHONE_7_0
if([self respondsToSelector:#selector(setEdgesForExtendedLayout:)])
[doneButton setContentEdgeInsets:UIEdgeInsetsMake(0, 12, 0, -12)];
#endif
I tried removing it and running it in iOS 6 and it ran fine. Is there some special case I need to be aware of in iOS 6/7 that causes it to not trigger or causes crashes?
The #ifdef is a compile-time directive. It will cause the code between the #ifdef and the #endif to only be compiled if the project is built against the iOS 7 SDK. If you build against the iOS 6 SDK, the code won't be compiled at all.
The #ifdef would prevent compiler errors if the code inside uses symbols that are only defined in the iOS 7 SDK. In the code you posted, I'm not sure what it's doing. The setContentEdgeInsets code is valid for most iOS versions. I would think the code should check to see if self responds to setEdgesForExtendedLayout, and then call setEdgesForExtendedLayout if it does respond.
The #ifdef is redundant. Also, depending on how __IPHONE_7_0 is defined, it may cause your app to stop working on iOS 8. Just remove it.
Related
I'm working on porting an iOS application to Catalyst. The Catalyst (Mac) version will have its own target.
Is there an official way to conditionally compile code just for Catalyst? Otherwise, I can add a target-specific define, but it would be better to use something more general.
As seen in the documentation Creating a Mac Version of Your iPad App, you do:
Swift:
#if targetEnvironment(macCatalyst)
// Code specific to Mac.
#else
// Code to exclude from Mac.
#endif
Objective-C:
#if TARGET_OS_MACCATALYST
// Code specific to Mac.
#else
// Code to exclude from Mac.
#endif
It is also possible to run code that is excluded from macCatalyst without having to use the #else. Note the use of ! (not).
#if !targetEnvironment(macCatalyst)
print("This code will not run on macCatalyst")
#endif
I was stuck with an orientation issue in iPad for all versions. My app is designed in such a way that it supports from ios 6 till ios 8.
According to apple since willAnimateRotationToInterfaceOrientation: is DEPRECATED from ios8, i used viewWillTransitionToSize: for ios8.
When hit with issue, my first solution was providing macros to decide the version as either ios 8 or below and perform the functions accordingly.
#ifdef __IPHONE_8_0
// Works on >= version 8.0
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
// my code go here for ios 8
}
#else
// Works on < version 8.0
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
{
// my code go here when version is below 8.0
}
#endif
I also checked and run it.. I received the output as expected.
But it was said that the code was wrong.. as i am trying to turn version checking into a compile-time decision. The version checking must be a RUNTIME decision. both the ios7 and ios8 code must BOTH be compiled into the executable.
So changed the function as below without any version check:
-(void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
// my code go here without any version check
}
I'm hardly unable to understand the line "both the ios7 and ios8 code must BOTH be compiled into the executable." - what this really mean.
Wish to know why i shouldn't provide compile-time decision?
Also if i want to do it... without using notification.. is there any way through which i can able to handle by calling these functions at runtime with version check?
Kindly let me have the comments on this.
I am trying to get the MIDI over BLE working as discussed at session 501 at the WWDC 2014.
I get an error "file not found" when trying to #import CoreAudioKit/CoreAudioKit.h framework
I have included the framework in the build menu and tried putting the #import line in the .h or .m ViewController file.
It recognizes and compiles CoreBluetooth/CoreBluetooth.h with no problems.
This is a brand new installation of Xcode 6 downloaded yesterday (13 Sept 2014)
I feel like Apple has not turned on the switch for CoreAudioKit for iOS.
Any guidance on what I am doing wrong would be most gratefully received.
Thank you,
Ken
CoreAudioKit is not compatible with the iOS Simulator. Run it on a device, and it should build just fine
I you want to use the simulator for some other tests (not related to midi over bluetooth) you can use a conditional import of the framework:
#ifdef __APPLE__
#include "TargetConditionals.h"
#if TARGET_IPHONE_SIMULATOR
#compatibility_alias CABTMIDICentralViewController UIViewController;
#elif TARGET_OS_IPHONE
#import <CoreAudioKit/CoreAudioKit.h>
#endif
#endif
You still have to do optional linking of the framework in your build settings since CireAudioKit is not available at all on the simulator (OS X) platform.
So here's the problem. I'm set to release an update soon for iOS that will address some problems in iOS 7. In order to do this, I need to use some specific iOS 7 functions/types. I've made absolutely certain that iOS 7 code will only be executed on iOS 7 and fallback to different code for pre iOS 7. Of course, I'm not allowed to submit with the current Xcode beta, so I'm trying to compile with the current Xcode release. However, I can't seem to find a way to disable this particular warning:
Use of undeclared identifier '<Redacted>'.
Does anyone know of a way to disable this warning using a #pragma. I've tried a bunch of different ones including
-w, -Weverthing, -Wall
but nothing seems to work.
UPDATE
Answer: You can't, of course, because the compiler can't compile an identifier it knows nothing about. My solutions was to simply create a #define:
#define <redacted> 1
UPDATE 2
The answer below actually made it much easier. I had already created a #define Xcode5Code(code, alt) that allowed me to execute code blocks conditionally. By modifying it using the solution by #maddy:
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
#define Xcode5Code(code, alt) code
#else
#define Xcode5Code(code, alt) alt
#endif
This allows me to to easily hide blocks of code from the compiler by using:
Xcode5Code({
//Code to be execute only with Xcode 5
}, {
//code to be executed in previous versions of Xcode
})
The main benefit of using the #define Xcode5Code is that Xcode will auto-complete it for you, which is a lot easier than using the full #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000, which Xcode won't auto-complete.
This won't actually distinguish between iOS 7 and pre iOS 7 devices. It only distinguishes what version of iOS the current Xcode can handle. To distinguish between iOS devices versions I use:
NSUInteger DeviceSystemMajorVersion(void) {
static NSUInteger _deviceSystemMajorVersion = -1;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_deviceSystemMajorVersion = [[[[[UIDevice currentDevice] systemVersion] componentsSeparatedByString:#"."] objectAtIndex:0] intValue];
});
return _deviceSystemMajorVersion;
}
The above is Apple's code, by the way. To dance around the NDA a little, I'll say that this helps with laying out a root controller's view, because that depends on both the version of Xcode you're using AND the version of iOS that's on the device. And if you're trying to manage beta's as well as production code, this can help a lot. Once you can submit apps with Xcode 5, the #define Xcode5Code will no longer be necessary.
If you want to compile your app with two difference versions of Xcode or two different Base SDK settings then you should use compiler directives:
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 // iOS 7.0 supported
// iOS 7 code here
#else
// Pre-iOS 7 code here
#endif
Do not use this for runtime checks. This solution is only to be used when you must compile your code with two different versions. An example would be you have added iOS 7 code but you still need to compile the code with Xcode 4.6. Using the compile directives allows you to "hide" the iOS 7 code from the compiler using the older Base SDK.
See the "SDK Compatibility Guide" in the docs for more on this and proper runtime checks.
I had a problem with the latest release of my app, where iOS 5 users said it was crashing. I quickly discovered the problem to be with using an iOS 6 method. I didn't realise this method was a new one. I was wondering if there was a way to quickly check my code (without doing it method-by-method) to make sure all code is compatible with previous versions of iOS?
You should test your app on iPhone/iPad 5.0 simulator. I think they are not available by default XCode 4.6 onwards, but you can download them from: Preferences > Downloads > Components.
Edit: It seems like XCode doesn't warn about new APIs in your code. There a workaround described in this answer: Get xcode 4.5 to warn about new API calls -
#define __AVAILABILITY_TOO_NEW __attribute__((deprecated("TOO NEW!"))) __attribute__((weak_import))
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0
#undef __AVAILABILITY_INTERNAL__IPHONE_6_0
#define __AVAILABILITY_INTERNAL__IPHONE_6_0 __AVAILABILITY_TOO_NEW
#endif