I have an app where the user can make in-app purchases. The problem is that the binaries for iPad and iPhone are going to be different. Is there any way to share the in-app purchases between both apps so that the user doesn't have to pay twice for the same thing?
I think there is no way to do this, but maybe there is any suggestion.
My best regards,
Antonio.
You cannot share in-app-purchases between different apps. The solution is to create a universal app which serves both hardware platforms.
It may be confusing in the beginning, but you do not have to maintain two codebases on the long run. So make your code conditional, like ...
check if you are on an iPad
BOOL isIPad = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
load your .xib files conditonally
NSString *conditionalXibName = isIPad ? #"MyXibFileName-iPadVersion" : #"MyXibFileName-iPhoneVersion";
UIViewController *myViewController = [[UIViewController alloc] initWithNibName:conditionalXibName bundle:nil];
Related
I know it's very vague and is asking a lot but does anyone know how to convert the standard iOS starter project from iPhone to iPad (both is best)? Or does anyone know where I can download one. I am a new iOS developer and am trying to start learning with Parse.
I am referring to this project https://www.parse.com/downloads/ios/parse-starter-project/latest
P.S. Just because this question isn't perfect doesn't mean you have to go and down vote and flag it for removal I don't have a lot of points already no need to lose even more :)
Not being able to see this sample project, it's hard to say for certain what it will take.
At bare minimum go into your project summary, and select "Universal" for the device support.
Above and beyond that, it just depends on what the app is and how it's structured. For NIBs, you will want a NIB for iPhone and one for iPad. I find it easy to abstract this away so that I can simplify my view loading:
MyController *myController = [[MyController alloc] initWithView:#"MyControllerView" bundle:nil];
Then in a category, I'd define initWithView similar to:
#implementation UIViewController (Universal)
-(id) initWithView:(NSString *)view bundle:(NSBundle *)nibBundle{
bool isIpad = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad;
NSString *nibName = [NSString stringWithFormat:#"%#_%#", view, (isIpad ? #"iPad" : #"iPhone")];
return [self initWithNibName:nibName bundle:nibBundle];
}
#end
But, that's just one aspect of supporting both devices. In reality the subject is rather specific to the app you're working on. Things like OS support (e.g., am I only targeting iOS 6 or higher) play a factor in things.
I have solved it now, if anyone needs the files email me turboecreations#iCloud.com I would upload them but I dont want my MediaFire and other accounts to be removed if I run into copyright issues.
I would like to know how to present the "Open In..." Action Sheet (iPhone) / Popover (iPad) from my app, preferably an IBAction
I would hope that it'd be similar to declaring a file type then creating the view and opening the app selected by the user, but I know it is more complicated then that.
I realize that a similar question has been asked on StackOverflow, but I cannot make sense of the answer that was accepted: How to use "open in..." feature to iOS app?, and I have found some Apple Documentation on Document Interaction Programming. But, I can't really make sense of these.
Create a UIDocumentInteractionController by using the interactionControllerWithURL: class method (pass the URL of the file you want to open in another app).
Then call either presentOpenInMenuFromRect:inView:animated: or presentOpenInMenuFromBarButtonItem:animated:. The controller takes care of presenting the popover with available apps for that file type and opening the selected app.
If you want to know when the menu was dismissed and which app was selected, you need to implement the UIDocumentInteractionControllerDelegate protocol.
omz makes some good points on how to do that in his answer, however this procedure is much easier with the introduction of new APIs in iOS 6. Here's a simple and efficient way to show the UIActionSheet Open-In-Menu in iOS 6 and up:
NSArray *dataToShare = #[contentData]; //Or whatever data you want to share - does not need to be an NSArray
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:dataToShare applicationActivities:nil];
[self presentViewController:activityViewController animated:YES completion:nil];
Also, if your app is compatible with versions of iOS lower than 6.0 you may want to check if the Share Service exists:
if ([UIActivityViewController class])
Once you present the sheet, iOS will automatically handle the rest for you. It will display a beautiful uiactionsheet with icons showing each app or service the user can open / share your data with:
Note that depending on the contents of the data, iOS will show different services in the Share Sheet
EDIT: The method above shares the file content, but not the file itself. Refer to omz's answer for more on that.
I've personally never had to do this, but your answer can most certainly be found in this Apple Documentation: http://developer.apple.com/library/ios/#documentation/FileManagement/Conceptual/DocumentInteraction_TopicsForIOS/Articles/PreviewingandOpeningItems.html#//apple_ref/doc/uid/TP40010410-SW1.
Apologies if this is a silly question, but I've done some googling and searched SO and haven't found anyone asking this exact question.
I have been doing iOS development for some time now, but I am completely new to the Interface Builder. What I want to know is this: is there any way to just create ONE .xib file and then use it for both iPhone and iPad in a Universal application?
It seems silly to me to have to create them separately; why do twice the work laying something out more than once in Interface Builder when I could do it once (with minor adjustments for screen size) in code?
Please let me know if I'm missing/misunderstanding something here. Like I said, I'm a complete Interface Builder newbie :)
EDIT: I have submitted non-interface-builder games to the App Store in the past where the iPhone and iPad versions were identical, so I'm not concerned with making the game look/feel different on each device. I intend for them to look exactly the same, aside from some slight positioning changes due to the difference in aspect ratio.
If you know what the resulting view would look like, based on autoresizing, you can indeed use only one .xib. May come in handy if the view is just some sort of a shared component that autoresizes as you want it to. However, if you need the view to look way different on iPad than on iPhone, just use two .xibs. It’s possible then to load the appropriate one as needed, for example in instance initializer, like this controller’s -init:
- (id)init
{
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
{
self = [super initWithNibName:#"YourNibForPad" bundle:nil];
}
else
{
self = [super initWithNibName:#"YourNibForPhone" bundle:nil];
}
if (self) { /* initialize other ivars */ }
return self;
}
The main reason that XIBs are separate files is because Apple feel that UIs designed for iPhones/iPod touches and iPads should be tailored to each respectively. This is echoed in their their iOS App Programming Guide, which says the following:
For views, the main modification is to redesign your view layouts to support the larger screen. Simply scaling existing views may work but often does not yield the best results. Your new interface should make use of the available space and take advantage of new interface elements where appropriate. Doing so is more likely to result in an interface that feels more natural to the user—and not just an iPhone app on a larger screen.
Whilst it can take time to maintain two XIBs for what is effectively one UI, I feel it is more straightforward than using one XIB and then having to connect up most of your UI elements in order to move them around programmatically when that XIB loads. After all, with two XIBs at least you can see what each UI looks like, and then make visual changes easily.
As an aside, don't forget iOS 5's Storyboards (read about them here), which make managing a view/view controller hierarchy much simpler.
Try to name them
MyCell.xib and MyCell ~ ipad.xib
then:
[self.tableView registerNib: #"MyCell" forCellReuseIdentifier: #"MyUniqueIdentifier"];
If your using IB, you need to create 2 separate xib files for iPhone and iPad. You need a separate iPad xib to make your app comply with the Apple iPad UI guidelines.
I have an universal app that changes the screen layout based on what device the user has.
It seems to work pretty good, but I've had one user call in (and send me screen shots) of his iPhone 4 showing him the iPad view instead of the iPhone view. I haven't been able to duplicate it on any of the phones we have around here, but I'm wondering if there there is a better way to do this since iOS 4.3 has come out.
+(BOOL)isIpad{
return ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad);
}
Alternately, is there just a way to detect screen size? I mostly use this to determine how wide elements in a table should be, but if Apple comes out with iPad 3 with retina display, it would be nice to have the app just adjust everything accordingly.
Also useful if the app is in portrait or landscape. Make it so that it just anchors to the edges like elements in WPF.
When loading XIBs for a universal app this, or what you're already doing, seems to be the only way:
NSString *xibName = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)?#"SomeView~iPad":#"SomeView";
As for screen size this should work:
CGRect screenSize = [[UIScreen mainScreen] bounds];
This is like a bazillion years old, but came across it in google so I figured I'd post a poorly documented but very useful feature. If you add ~ipad to the end of the filename for your iPad specific nib it will automatically load that one instead. Same logic as #2x for loading images. So your iPhone nib would be named myview.xib and your ipad myview~ipad.xib and iOS will correctly load the ipad version wherever needed. Fancy!
UIUserInterfaceIdiomPad is now deprecated. The new way to do it would be using TraitCollections. It can only be called on Views.
-(BOOL) isiPad{
return self.view.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassRegular && self.view.traitCollection.verticalSizeClass == UIUserInterfaceSizeClassRegular;
}
Refer Apple Documentation here
Probably it has a previous version of the app and conflict with the new!
Try to remove old one and reinstall new! It works! I already encountered this issue.
Is it possible to simply duplicate ipad display to TV out (assuming both have same resolution)?
Code like this doesnt seem to work (it is a pretty naive implementation)
int i=0;
for (UIScreen *screen in [UIScreen screens])
{
if(i>0)
{
UIWindow* extWindow = [[UIWindow alloc]init];
extWindow.screen =screen;
[extWindow addSubview:viewController.view];
[extWindow makeKeyAndVisible];
}
i++;
}
[window addSubview:viewController.view];
[window makeKeyAndVisible];
Code like this doesnt seem to work (it
is a pretty naive implementation)
This code looks like a mishmash. I haven't used external screens before, but your inner if block is creating anonymous UIWindow objects, assigning a property, and then leaking them at the end of the block (no release) -- and that definitely won't do what you intend.
You should consult the iPad Programming Guide, specifically, Support for External Displays and Projectors, which summarizes how your code should be written.
If you need this for a demo presentation, then there are few apps that will duplicate the screen for you while running your app like TVOut, TVOut2, Screenspltr. However there is a catch, these apps are not approved by Apple therefore are not in the app store, in order to install them you'll need to jailbreak it and it comes with the involved risks. However for a quick dome it is probably the best solution.