How to add the iOS "Open In..." feature to an app - objective-c

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.

Related

How to check what frameworks and methods supported by winobjc

I tried to port a sample iOS app with a UITableView to Windows 10. In which it tries to display 100 rows with each row contains label with value as row number. Here is the code
UILabel *label = (UILabel*)[cell viewWithTag:1];
label.text = [NSString stringWithFormat:#"Name %ld", indexPath.row];
And when launched this app in windows10 i see only empty rows.
Does viewWithTag is supported?.
How do i check what api's and methods supported by winobjc? Is there any documentation available on this?
I work on the iOS bridge project at Microsoft. The problem you're seeing here has to do with cell reuse identifiers, not viewWithTag. Our Xib2Nib tool handles converting Storyboards and Xibs when you run vsimporter. Currently, Xib2Nib does not support cell reuse identifiers defined in Storyboards (although it does support cell reuse identifiers in Xibs). So when you call dequeueReusableCellWithIdentifier:forIndexPath:, the correct cell with your UILabel in it is not instantiated, which results in you getting blank cells.
There are a couple of potential solutions to this. You could build your layout programmatically in a UITableViewCell subclass and use registerClass:forCellReuseIdentifier:. You could also lay out your cell in its own xib file (separate from your Storyboard) and use registerNib:forCellReuseIdentifier:.
In either case, you should file an issue on the project on Github if you'd like to see support for cell reuse identifiers in Storyboards – Github is the best way to get in touch with our team and informs all of our prioritization decisions.
More generally, you can see what's supported and not supported by the bridge in the Visual Studio debug console; when missing or stubbed APIs are called, you'll get a message with details. We're also working on tools that will make browsing the API surface area easier.
Thanks for checking out the project!

Define a controller for NSDocument for document-based application

I'm not very sure how Document-Based Applications works.
I've created some actions for NSObject in the Mainmenu.xib. One of this is called when the user click on "File>new":
-(IBAction) newDocument:(id)sender{
Document* newDoc =[[Document alloc] init];
[[NSDocumentController sharedDocumentController]addDocument:newDoc];
[newDoc addWindowController: [[NSWindowController alloc] initWithWindowNibName:[newDoc windowNibName] owner:newDoc]];
[newDoc showWindows];
}
I've also this code inside the openDocument:(id) sender action that does the same but of course loading data to define the application workspace.
If I run the application it show a blank document without to call newDocument action. I don't know how to stop default blank document and to set newDocument: to be called.
Then if i do openDocument: too (so I've two documents, one blank and one not) and I do some operation on the second document it also replicate in the first blank one.
I've double check delegates, file owners, and also if the - (void)windowDidBecomeMain:(NSNotification *)notification return different pointers and all seem to be ok.
Probably I've not understood document based application work flow but I've read the Apple guide and other istructions. What do I miss?
An IBAction method is called, when the user did something. So this is not called from the system at app launch.
You can customize the behavior at app launch with -applicationShouldOpenUntitledFile: (NSApplicationDelegate) and – this is probably your next question – -applicationShouldHandleReopen:hasVisibleWindows: (NSApplicationDelegate). Changing the behavior in both cases is not recommended.
Looking to your action method, I see no reason, why you want to customize it.
A instance of your document class is created automatically.
You can create a window controller for it in your document subclass. This is documented.
Just let NSDocumentController do the work for you. What is the problem of the default behavior?
No. I thought to be confused instead the only problem was about releasing observer notification. When you call the close message for a NSDocument notification observers still persist. Working in ARC I miss this point.
So This is the solution at my issue. Thank you anyway.

How do I use a RootViewController when making an app without a ViewController?

I am trying to make a simple app from a tutorial that does not have a viewController at all. All the code is in the AppDelegate. I am on xcode 4.2 and I am getting this error:
Applications are expected to have a root view controller at the end of application launch
I'm not sure how to deal with this. There are some blogs out there with fixes but none of them are working for me and I really would like to understand what is going on here. And, how to fix it.
I do have a view that contains some buttons and labels. But I have no "ViewController". The files contained in my project are: AppDelegate.h, AppDelegate.m, and Window.xib only. There is no ViewController.h, ViewController.m
** edit **
I ended up making the app from a 'view based application' instead and just moving all the logic from the app delegate to the view controller. So, I didn't really solve the problem per se. The app works now though. Thanks for the help
It's not possible to have an iOS app that doesn't have a view controller. You can always create a trivial view controller, i.e.,
[[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds].rootViewController =
[[[UIViewController alloc] init] autorelease];
It sounds like you're looking at an old tutorial. UIWindow got a rooViewController property in iOS4. I believe it became required in iOS5 to help keep controller hierarchies and view hierarchies in sync with the addition of custom container controllers (and to fix a corner case where replacing the "root controller" of a UIWindow could stop orientation changes from propagating). There was a WWDC presentation in 2011 that explained this in some detail. I think it was Session 102, Implementing UIViewController Containment.
At then end of the day, there's no good reason not to have a root view controller. Apple wants to be able to assume it's there in their APIs going forward. If the tutorial you're looking at doesn't account for that, it's broken.
While I agree that there may be workarounds, another question to address is: why do you want an app without a view? Even if it's designed to run in the background and present no visual interface, at least make a simple view showing the application name and version, a largeish icon and perhaps a status. This kind of idle screen uses very little system resources, especially when the app is backgrounded, but improves the overall experience of the app.
If you set your deployment target to 4.3 and run on the iPhone 4.3 simulator, you won't get the warning.
To install the iOS 4.3 simulator, go to Xcode > Preferences > Downloads.

How to switch views using Objective-C and Interface Builder

I am creating a program that will run an experiment on a user. It has a 'start' page with a button. When they click the button, I want the window to change to the 'test' page.
I believe this is done by switching views, and I have tried to find some tutorials/answered questions on it by I have had trouble due to a few things:
-I'm not sure how to create the views themselves in Interface Builder
-I am NOT developing for the iPhone
Do I need to create a new XIB file? Should I have made multiple windows instead?
Any help or direction in this matter would be very much appreciated! :D
Let me strongly suggest that you forget about your particular task for a little while and instead spend some time learning how the Cocoa framework works. A good place to start might be the Cocoa Application Tutorial, which will walk you through the creation of a small MacOS X application (and quite possibly answer your question in the process). It's fine that you're new to Objective-C, Cocoa, etc., but in that case you should spend some time with Apple's documentation to help you get up to speed.
I would suggest you to have a look at one of the many tutorials around there:
Learn Cocoa Tutorial: this one will guide you step by step through IB;
A full Cocoa/Xcode/Interface Builder Tutorial: this will deal more in detail with IB/Xcode integration.
Apple Tutorial: this is more in-depth and explains many more details and concepts, so good for a second read.
Or you might reach out for some good book, like the classic Cocoa Programming for Mac OS X By Aaron Hillegass
As a further suggestion, since you specify that you are NOT programming for the iphone, there are a lot of docs on the web. Main thing to find them out is use the keyword "cocoa" when searching for them.
I rather suggest to use view controllers, every view controller should have xib file you can simply handle actions like on button click etc...
I suggest to try out create window based app, so one view controller is already created, now click file add file and choose view controller.
in first xib you could add buttons and every component you like...then set the second one.
you could create function
-(IBAction)foooFunction{
SecondViewController *foo = [[SecondViewController alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController: foo
animated: YES];
[foo release];
}
then in xib of your first view controller you just simply drag and drop the foooFunction onto the button and you have it.
Apologies, I am new to Objective-C
And it is not problem that you are new :)
have a nice day and hope it helps

Can anyone help out an Objective C novice?

I feel i am totally out of my depth here, im very new to objective c but have been asked to design an iphone app as part of my uni course. I designed a sinple quiz before, but I was hoping to design a more advanced quiz game with 3 levels (each level will have a different quiz).
I dont know how to use the UIViews and I have tried a tutorial online to help me code a navigation controller. It allows gives me 3 options to go into subview 1, 2 or 3. All the subviews have the same screen though, with one label and a button.
I have 3 classes so far, RootViewController, BasicNavigationAppDelegate and SubViewOneController.
I really dont understand the code at all, im familiar with Java but this objective c is nothing like it. Could someone maybe take a minute to help out a person in distress and explain if i am doing this right by using the navigation controller to display my levels? When i check the xib interface files i dont see the button or label, or dont know where to add the quiz interface objects!! I really am confused by all this. Could anyone help?
You should search google for sample source code, and see how some of the views can be handled. There are many ways you can handle a view, whether its by a UINavigationController, UITabBarController, etc. If you are new to Objective-C, then your not really going to get an answer to this question that will instruct you on what exactly to do.
Interface Builder + View Controllers
Here's a good one for you: View Controllers Programming Guide
(Apple's) View Controller Reference Guide
Some Code Samples
Getting Started Sample Code
I recommend Head First iPhone Development: A Learner's Guide to Creating Objective-C Applications for the iPhone. Within a few chapters you'll know everything you need to build this app and you'll actually understand what you're doing.
(I don't know the authors or the publisher, I just think it's a great book for quickly getting up to speed.)
for a 3 level quiz, UINavigationController is definitely an option.
if you need to find out how to use a class, in xcode, type its name, then press -alt- and double click the class name, this will bring up a short description, with two icons, one will take you to the header file, and the other to the documentation.
to add elements to the nib/xib files, you will need to open the library window, where you will find labels, buttons etc. to use a button, you will need to define an action in your header file, and hook it up in IB, to be able to interact with UIElements in your code, you want to set up outlets in the header file, and hook them up in IB.
something you need to decide on, is how you are going to present the questions, and will also depend if the answer will be true/false, multiple choice, or text entry.
if you arent familiar with obj-c and xcode, it is probably worth picking up an ebook from someone like http://www.pragprog.com. they have an iPhone one up there by Bill Dudney which is quite good(i believe he now works for apple.)
for the standard slide out transition you could use this.
//you would probably want to call this something like level1NavBarItemWasPushed: instead
- (IBAction)lvl1pushNavBarItem:(id)sender {
//create instance of AnswersViewController class.
AnswersViewController *level1AnswersVC= [[Level1AnswersViewController alloc] init];
//pass it some kind of identifier so it can tell which quiz/question it is dealing with and pull in the answers, so that you can reuse the view
[level1AnswersVC setAnswersObject:<<insert object dictionary here>>];
//push the view controller onto the navigationController's view stack
[self.navigationController pushViewController:level1AnswersVC animated:TRUE];
//pushing it onto the view stack has given it +1 retain, so we can now release it without worrying about it disappearing prematurely.
[level1AnswersVC release];
}
for the page flip transition you could use this.
- (IBAction)lvl1pushNavBarItem:(id)sender {
//create instance of AnswersViewController class.
AnswersViewController *level1AnswersVC= [[Level1AnswersViewController alloc] init];
//pass it some kind of identifier so it can tell which quiz/question it is dealing with and pull in the answers, so that you can reuse the view
[level1AnswersVC setAnswersObject:<<insert object dictionary here>>];
//set the current viewController as the delegate, so that it can call back to us when its done
level1AnswersVC.delegate = self;
//set the modal transition style
level1AnswersVC.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
//show answers as modal view, which has been setup to use the page flip transition.
[self presentModalViewController:level1AnswersVC animated:YES];
//pushing it onto the view stack has given it +1 retain, so we can now release it without worrying about it disappearing prematurely.
[level1AnswersVC release];
}