Setting multiple UIBarButtonItems fails on device, but not on simulator - ios

I'm consistently running into an invalid selector exception when I attempt to set multiple UIBarButtonItems in MonoTouch.
In the simulator, there are no issues at all. Each button I add works correctly. Only when I deploy to a test device (iPhone 3G with iOS 4.2.1 installed) does it throw this error:
-[UINavigationItem setRightBarButtonItems:animated:]: unrecognized selector sent to instance 0xef7af0
I have tried using the RightBarButtonItems property and the explicit SetRightBarButtonItems method, passing a UIBarButtonItem[] instance in each case.
Maybe the way to get around this is to use a ToolBar with a custom view, but I'd rather just use the API as advertised, especially if it works correctly in the simulator.
Anyone run into this?

I assume you're using MonoTouch 5.0 and the latest iOS SDK (5) and Xcode 4.2.
The setRightBarButtonItems:animated: selector is new in iOS5. This means it will work in the simulator, which likely defaults to 5.0. However this won't work in older releases of iOS (e.g. like 4.2.1).
At this stage you have two choices:
avoid iOS5 features; or
detect, at runtime, which version of iOS is being used and adjust your application to what's available.

Check this out: http://osmorphis.blogspot.com/2009/05/multiple-buttons-on-navigation-bar.html
It works if you want to add multiple right buttons for iOS < 5.0

Related

Swift warning in Xcode 14 : Method confirm(intent:) conflicts with method confirm(intent:completion:) with the same Objective-C selector

Testing the new widget for iOS 16 with Xcode 14, I'm facing an issue trying to port the iOS 14 widget with the new WidgetFamily like .accessoryInline or .accessoryRectangular.
After adding conditional macros to solve some errors in order to build for watchOS and iOS (cf Apple WWDC 22 video: https://developer.apple.com/videos/play/wwdc2022/10050/), Xcode display no red errors but yellow blocking warnings:
Method 'confirm(intent:)' with Objective-C selector
'confirmConfiguration:completion:' conflicts with method
'confirm(intent:completion:)' with the same Objective-C selector; this
is an error in Swift 6
Any idea how to solve it?
EDITED : Finally works without fix that, see answer below. But I'm still interesting to remove this warning.
Finally, it passed without fixing this warning. I remove the last errors around the extension bundle name (has to be prefixed with the watch app bundle and follow by ".xxxxxx" of your choice without any further dot). I also had a "4" (Apple Watch) value to "Targeted Device Families" in build settings (was previously "1,2" for iPhone, iPad).

All IOutlet properties are "nil" in a view controller when running test on iOS 11 Simulator

I'm getting an issue in iOS 11 Simulator where in a certain unit test, all the IBOutlet properties of a swift view controller are "nil", and where the same properties were populated in iOS 10.3 and the test was also passing.
It has the additional complication that the test passes when it is run in isolation, and also passes on the the device. It only fails on the iOS 11 simulator, and when run with all the other tests.
There is no explanation as to why the test fails on simulator + iOS 11 and not other configurations, but the issue was fixed by using a static method to create the second view controller. For some reason, the empty initializer ("CardViewController()") worked previously, but now requires the full create method like above.
I was a little mistaken about how the viewController was loaded (it is loaded in the setup() method), but I also found this resource useful:
https://www.natashatherobot.com/ios-testing-view-controllers-swift/
It did not solve the issue, but is a useful reminder of possible race conditions in XCTest.

What happens if I use LAPolicyDeviceOwnerAuthentication on iOS 8?

In my app, I would like to know if the user has setup a passcode or fingerprint (touchID). There's a pretty easy method just for that: [LAContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthentication error:error].
However, Apple's docs say LAPolicyDeviceOwnerAuthentication is only available on iOS9 and above. I would rather not crash iOS 8 users without explanation, even if it is getting older. The thing is, I've tried it on an iOS8.4 simulator, and it seems to compile and just work.
What ill effects can happen if I use LAPolicyDeviceOwnerAuthentication on iOS 8?
I use code similar to this:
LAPolicy localAuthPolicy = LAPolicyDeviceOwnerAuthenticationWithBiometrics;
if (![[UIDevice currentDevice].systemVersion hasPrefix:#"8."]) {
localAuthPolicy = LAPolicyDeviceOwnerAuthentication;
}
This ensures I only use LAPolicyDeviceOwnerAuthentication on iOS 9 and later.
It's undocumented what actually happens on an iOS 8 device when you attempt to use LAPolicyDeviceOwnerAuthentication. It's very unlikely anything will crash but the authentication may return NO due to an unknown value or it may succeed because iOS 8 only had one valid value and it may not do any checking.
Unfortunately Objective-C doesn't provide any runtime checks for valid enum values like you can do with constants, methods, and classes.
If you use LAPolicyDeviceOwnerAuthentication on anything below iOS 9, the app will crash. That is what happened to my app when I didn't realize that this was not available on anything below iOS 9, but my app supported iOS 8.x as its minimum supported OS version.

SDWebImage on iOS 8.1 weird compile error

When I try to run project on real device (iPhone 5 and 5S with iOS 8.1) I get following compiler errors:
// ARC Semantic Issue - myPath/SDWebImage/UIImage+GIF.m:26:42: No visible #interface for 'UIImage' declares the selector 'initWithData:'
animatedImage = [[UIImage alloc] initWithData:data];
// ARC Semantic Issue - myPath/SDWebImage/UIImage+GIF.m:47:34: No known class method for selector 'animatedImageWithImages:duration:'
animatedImage = [UIImage animatedImageWithImages:images duration:duration];
// ARC Semantic Issue - myPath/SDWebImage/UIImage+GIF.m:155:21: No known class method for selector 'animatedImageWithImages:duration:'
return [UIImage animatedImageWithImages:scaledImages duration:self.duration];
My project was working normally until this morning. I changed nothing, just tried to debug on real device. The strangest part of that is I can run/debug on emulator (on any iPhone device with iOS 8) without any error.
When I downgrade deployment target from 8.1 to 8, XCode can successfully build and run the project for emulator and real device.
I tried completely removing SDWebImage and adding it back but didn't solve the problem.
I am using XCode 6.1 (Swift) and iOS 8.1 SDK on my project.
What might be causing the problem that suddenly appeared?
As has been said on other questions, the new "ModuleCache" directory within DerivedData has been responsible for many of these problems.
Here's the path:
/Users/[user]/Library/Developer/Xcode/DerivedData/ModuleCache
Simply delete the module cache, or the entire derived data directory as many have been doing on a daily basis for the last few iOS SDK iterations.
I came here looking for a different answer to a similar problem since this solution isn't fixing my current problem, but I figured I would share this as it will fix many of these.

XCode setting to see code which won't work on previous OS versions

I've written an app specifically for iOS7, and am now attempting to make it work for iOS6.
I'd really like a setting to enable warnings which highlight lines of code which won't work on iOS6. i.e. any calls to code which ONLY work on iOS7.
That way I can immediately identify any lines of code which I need to attend to before catching them during debugging.
Does this even exist?
There is two option to deal with this.
Use MJGAvailability, a drop in header file and it will make warnings if a selector is "too new".
Buy Delpoymate, it can scan your Xcode project and show you any incompatible calls.
If you use an older Xcode next to the newest, than use this snippet:
if ([self respondsToSelector:#selector(newSelector)]){
#if __IPHONE_7_0
[self newSelector];
#endif
} else {
[self oldSelector];
}
There is no way of getting a warning to appear and even if there was how would the IDE now that you would have done something to handle it like the below
if([myObject respondsToSelect:#selector(myiOS7SelectorOnly)]) {
[myObject myiOS7SelectorOnly];
}
It works the other way if you where developing an app for iOS7 and you used a deprecated method that iOS7 API doesn't use any more it would give you a warning but not the other way you will have to wait for it to turn around and crash and throw an unrecognised selector exception.
At some point I had 2 Xcode installed - Xcode 4 and Xcode 5. Xcode 4 did not have API for ios7 and it was showing all incompatibilities.
But I don't know where can you find XCode4 now and will it still show errors in ios7 code or not?
At least you can try this way.

Resources