I have the following code
BOOL ios5 = [mapview respondsToSelector:#selector(setUserTrackingMode:animated:)];
if(ios5)
{
if(compass && tracking)
[mapview setUserTrackingMode:MKUserTrackingModeFollowWithHeading animated:YES];
else if (tracking)
[mapview setUserTrackingMode:MKUserTrackingModeFollow animated:YES];
else
[mapview setUserTrackingMode:MKUserTrackingModeNone animated:YES];
}
else
{
// Do it the version 4.0 way
}
It works as expected depending on whether I have the compass or tracking flags on and tracks the user location in iOS 5.
However, it also works in version 4.3.3 which is the other device I'm testing on. It seems to respond to the selector and actually behaves as it does in iOS 5.
Is this because the functionality was in iOS 4 but not made public and I run the risk of the app being rejected for that reason?
Can anyone shed some light on this?
thanks
Donie
I believe you're doing the right thing by checking the functionality first before using it. It doesn't matter what version you're running on, that API is already documented. By doing it this way you are providing backwards compatibility to your 4.3 users.
Related
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.
Long story short:
How can I debug an iPhone-App directly on the hardware (iPhone) in exactly the same version/binary as it would be distributed by AppStore without the need to wait for AppStore-Preview-Process?
En detail:
I detected strong differences with the behaviour of an MKMapView between a compiled IPA running on an iPhone using Developer Profile via XCode/USB-Cable and between the Version installed directly from an AppStore after the Distribution-To-AppStore-Process.
I will attach two significant Screenshots.
This is how the App launches the MKMapView on an iPhone via XCode/USB-Cable pointing to the current users location with a special region:
And this is how the same App launches on the same iPhone after installing the distributed version from the AppStore without any code changes to the previous one:
Here i will provide some Code:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.mapView removeAnnotations:[self.mapView annotations]];
CLLocationCoordinate2D noLocation;
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(noLocation, 6500, 6500);
MKCoordinateRegion adjustedRegion = [self.mapView regionThatFits:viewRegion];
[self.mapView setRegion:adjustedRegion animated:NO];
mapView.delegate = self;
mapView.showsUserLocation = YES;
mapView.mapType = MKMapTypeStandard;
}
- (void)mapView:(MKMapView *)theMapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
theMapView.centerCoordinate = userLocation.location.coordinate;
}
Btw, just for your information: here occured another difference between an IPA running directly on the iPhone launched by XCode and the distributed Archive via AppStore. Without the Line "[self.mapView removeAnnotations:[self.mapView annotations]];" the App crashed directly after launch in the installed Version from AppStore, but not when running from XCode. This issue i ran into in a previous version and is not part of this question, just an addition to the main question
The main question is:
Is it possible to debug an iPhone-App exactly the same way as it would be distributed by AppStore without the need to wait for AppStore-Preview-Process, and if yes, how?
The main difference here is just likely to be a release build versus a debug build. You've got:
CLLocationCoordinate2D noLocation;
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(noLocation, 6500, 6500);
You don't set any initial value to noLocation. It's a raw struct so nobody else does either. It could have any value whatsoever. As a result adjustedRegion could be any region. No doubt it just happens to be something vaguely valid on your debug build and something completely nonsensical on your release build. Then probably MKMapView decides to show the entire earth if it can't make sense of the thing and when you shift the centre to the shops in your area it doesn't affect the zoom.
To fix, give noLocation a defined, valid value.
The version of the app you run on your iphone via Xcode will be in debug mode, the one on the App Store is in release mode. If you use preprocessors macro (like DEBUG), this could change the behaviour of your app.
If you think this could be the problem, go in XCode, in Product > Scheme > Edit Scheme, select your project's target and change the BuildConfiguration to Release. You will see how your app run in release mode even if you run it from Xcode. It will be easier to debug the behaviour of your app.
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.
Using the Worklight v6.0.0 code sample/tutorial "Integrating server-generated pages in hybrid applications" (http://public.dhe.ibm.com/software/mobile-solutions/worklight/docs/v600/IntegratingServerGeneratedPagesProject.zip) allows for the web content to be integrated. The code sample doesn't work in iOS 7/XCode 5. When show web view overlay page, it shows white blank page.
However, Android version works fine.
How can I get the WebViewOverlay to work on iOS 7/XCode 5?
I'm using Worklight Studio 6.0.0.20130926-1933, Xcode 5.0.2 and the iOS 7.0.3 simulator. When I first imported the project, it crashed on startup. It was something about iOS7, because it worked on the iOS6 simulator.
I deleted the iPhone environment and re-created it (including the customizations in the iPhone environment's css and js folders, and installed the WebViewOverlay plug-in in Xcode) and the crash was fixed. At that point the app worked fine, and the WebViewOverlay opened and populated with content. But it wouldn't close. I had to modify the close() method in WebViewOverlayPlugin.m
- (void)close:(CDVInvokedUrlCommand*)command{
NSLog(#"WebViewOverlayPlugin :: close");
WLCordovaAppDelegate *appDelegate = (WLCordovaAppDelegate*) [[UIApplication sharedApplication] delegate];
if ([[[appDelegate window] subviews] count] > 1) {
UIView *appView = [[[appDelegate window] subviews] objectAtIndex:1];
for (UIView *view in [appView subviews]){
if (view.tag==12345) {
[view removeFromSuperview];
}}
}
}
It looks like something changed since the sample was written, and objectAtIndex:0 needed to change to: objectAtIndex:1. Someone who actually knows objective c could probably do a better job with the condition I added (and explain why the change), but with the iPhone environment re-created, and the above implementation of close() it all seems to work on iOS 7.
I built an app that has a simple tel link:
- (IBAction) makeCall:(id)sender
{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"tel://8005555555"]];
}
It worked fine when I was testing on iOS 4.
Just before I released it, I upgraded to iOS 5, and now I find that the tel link isn't working. Does anyone know if this might be something to do with iOS 5, or am I barking up the wrong tree?
UPDATE: This is for an app I built for the company I work for, and in order to fix it, my boss has to give me access to the code, which he's kind of dragging his feet with. I'll update as soon as I have access and can find out if the solution ott gave works.
The correct URL should be tel:8005555555. It could be that the // were ignored earlier.
See also http://developer.apple.com/library/ios/#featuredarticles/iPhoneURLScheme_Reference/Articles/PhoneLinks.html