0

I'm making an app that uses HealthKit. The app must not work on an iPad, and as such my viewDidLoad method contains an if/then/else statement to show an alert to iPad users. This is my code:

if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone && SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0") && [HKHealthStore isHealthDataAvailable] == 1) {
    ...
}
else {
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Whoops!" message:@"Looks like your device doesn't support HealthKit :(" preferredStyle:UIAlertControllerStyleAlert];
    [self presentViewController:alertController animated:1 completion:^(){
        NSLog(@"Showed error alert because of unsupported device.");
    }];
}

The SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0") bit is from this gist.

The UIAlertController should show when the device is an iPad, is not running iOS 8.0+, or just (for some other reason) cannot use HealthKit. This is all good on paper, but when I run the app on the iPad 2 simulator running iOS 8, the app launches as normal and does not show the alert. For the record, I know the alert has no buttons but I don't want it to go away. It should only show on an iPad or device with less than iOS 8, and as such shouldn't need to go away when it's shown.

So why is my app not showing the alert view on iPad? The console shows no errors.

EDIT: The notification without buttons will not be in the final product, just in testing. The point still remains, however, as the alert should still be showing up.

Will Eccles
  • 394
  • 1
  • 5
  • 15
  • Apple won't let you do this. iPhone-only apps MUST work as-is on an iPad. You can make the app require certain things of course, but in general, your attempt to prevent running on the iPad won't work and won't be accepted if it did. – rmaddy Oct 16 '14 at 21:42
  • @rmaddy I know, this is just to test the system while in development. Whether apple likes it or not, this _should_ work in the simulator, but it doesn't. – Will Eccles Oct 16 '14 at 21:46
  • @rmaddy probably should have mentioned that in the question. I've just edited the question to make that clear. – Will Eccles Oct 16 '14 at 21:48
  • iPhone only apps don't know they are on an iPad. `userIntefaceIdiom` will return "iPhone" even on an iPad for an iPhone-only app. – rmaddy Oct 16 '14 at 21:50
  • @rmaddy I added that one in there just for good measure, though I guess I could technically remove it. – Will Eccles Oct 16 '14 at 21:51
  • Have you checked that the device family is set to universal? Seems to have resolved a similar problem asked in this [question](http://stackoverflow.com/questions/16319714/userinterfaceidiom-always-indicate-iphone) – Lev Landau Oct 16 '14 at 21:56
  • @LevLandau I didn't want it to be a universal app, but I realized it would just be easier to make it one :/ I'll go answer my question now. – Will Eccles Oct 16 '14 at 22:07
  • @LevLandau Actually, would you mind answering this with that answer? I can't accept my answer for 2 days but I can accept yours now. – Will Eccles Oct 16 '14 at 22:10

3 Answers3

1

Have you checked that the device family is set to universal? If it is set to iPhone only the user idiom will never be iPad. Making the app universal seems to have resolved a similar problem asked in this question

PS, Apologies for my first answer not reading the question properly.

Community
  • 1
  • 1
Lev Landau
  • 788
  • 3
  • 16
0

If you want to target the iPhone only, the proper way to go about this is to set it in your deployment targets

I've changed this one to match the iPhone only

I've changed this one to match the iPhone only

Now, that being the case, you'll still wind up with iPads running iPhone applications via the "scale up" method ( by scaling the iPhone version up to match the iPad ).

If you still want that alert in this case, then you can drop this in your ViewDidLoad

    if (self.traitCollection.userInterfaceIdiom == UIUserInterfaceIdiomPad) {
    NSLog(@"I'm an ipad");

    UIAlertController *alert = [ UIAlertController alertControllerWithTitle:@"Sorry dude, no iPads" message:@"go buy an iphone" preferredStyle:UIAlertControllerStyleAlert];

    [self presentViewController:alert animated:YES completion:^{}];
    }

In this case i'm using the new traitCollection property to determine the interface idiom.

If you're just wanting to avoid larger screens, then I recommend focusing on size classes as per iOS 8 this will definitely be the best route.

http://www.learnswift.io/blog/2014/6/12/size-classes-with-xcode-6-and-swift

one place to get a start on it,

and of course apple's trait collection reference

https://developer.apple.com/library/IOs/documentation/UIKit/Reference/UITraitSet_ClassReference/index.html

domitall
  • 655
  • 5
  • 15
0

Try something like this:

NSString *modelString = (NSString *)[UIDevice currentDevice].model;
if ([modelString hasPrefix:@"iPad"])
{
   // iPad
   return YES;
}

I believe this should work even when running iPhone only app on iPad.

Dominik Hadl
  • 3,609
  • 3
  • 24
  • 58