UIDocumentPickerViewController - possible to remember last import location/service? - ios

When using UIDocumentPickerViewController for importing data into my app, I would like to remember the last service/location that was chosen by the user, and start the navigation with that service.
E.g. if a user imports something from Dropbox, and then later on wants to import something again, I would like the document picker to start with Dropbox as the initial location.
Unfortunately, the default behaviour is that the picker always starts with iCloud Drive, so each time a user wants to import something from Dropbox, they have to tap on Locations, and pick Dropbox from there - two unnecessary taps.
I've tried to keep a strong reference to a previously shown picker, but presenting that picker again doesn't seem to work - it just shows a blank view.
if(self.documentPicker) {
[self presentViewController:self.documentPicker animated:YES completion:nil];
return;
}
UIDocumentPickerViewController *vc =
[[UIDocumentPickerViewController alloc] initWithDocumentTypes:#[#"public.audio"] inMode:UIDocumentPickerModeImport];
vc.delegate = self;
self.documentPicker = vc;
[self presentViewController:vc animated:YES completion:nil];
There's also UIDocumentMenuViewController, which lets you choose a location/service up front and lets you then show the document picker which was chosen by it, but again, I have found no way to store a reference to a location with which to show a document picker in future import actions.
cheers!

Related

Need to bring Profile ViewController Functionality like Facebook and Twitter

If we Tap any Profile Picture it will lead to their Profile View. Even in same view if user taps Other's Profile Pic like in Followers list, then it should lead to their profile View.But the View controller is same.Just Same functionalities as Facebook and Twitter. I need to implement this Functionality. But I don't know how can I achieve this process. Using same profile UIViewController for multiple Users.
Or is there any other way to achieve this Functionality ? Please guide me how can I achieve this Process.
For Example : VC1 is myprofileVC and VC2 is friendsProfileVC. i'm selecting friend's Pic in myprofileVC(VC1) and loadingData in friendsProfileVC(VC2).then if i select another person's ProfilePic in friendsProfileVC(VC2) means where it should lead ? or what to do ? How to Loaded that Newly Selected Person's ProfileView?In Same (VC2) or ? in this place only im getting confused !!
Ref Image :
Suppose we have 2 viewControllers, the first one is class FriendViewController and other is class UserViewController.
Step 1
We are at UserViewController. When you tap an image of a
specified user you check your id with the id that the user has.
Step 2
Depending on user id, if the user id is the same as yours, you tapped your image, so you don't have to go to another viewController, so just reload your data for any update.
Step 3
Else is user id is different, we are dealing with another user, so we have to go to another FriendViewController. Example doing that:
FriendViewController *fc = [[FriendViewController alloc]init];
[self.storyboard instantiateViewControllerWithIdentifier:#"friendvcID"];
fc.stuff = stuff;
[self.navigationController pushViewController:fc animated:YES];
Step 4
Now we are at FriendViewController and if depending on a image we tap, if we have it as the same as our id, we are navigating to our profile, so what we do is check if we already have it to our navigationStack, if we don't we need to push.
//Check if we have userProfile on navigationStack
if ([self hasUserProfileOnStack]!=-1)
{
//We have it on specific index, so we are popping to that viewController, which is UserViewController
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:[self hasUserProfileOnStack]] animated:YES];
}
else
{
//We dont have it in navigationStack so we are pushing it
UserViewController *fc = [[UserViewController alloc]init];
[self.storyboard instantiateViewControllerWithIdentifier:#"uservcID"];
fc.stuff = stuff;
[self.navigationController pushViewController:fc animated:YES];
}
//Method which helps us to find if we have it to navigationStack by returning the index on navigationControllers
-(NSInteger)hasUserProfileOnStack
{
for (NSInteger i=0; i<[self.navigationController.viewControllers count]; i++)
{
if ([[self.navigationController.viewControllers objectAtIndex:i] isKindOfClass:[UserViewController class]]) {
return i;
}
}
return -1;
}
Step 5
If that ID is not as the same as our ID then we just have to execute Step 3
This is the info that I could give to you right now, it's a bit difficult explaining with words, but this is how I can explain it here. Hope it helps
You should start learning iOS Programming from scratch, and start developing apps step by step. There are plenty of sites and books where you can learn. I would suggest Ray Wenderlich because it has great iOS tutorials.
Referring to that question you have, I am developing a social iOS app right now where this thing is achieved by:
Using an ID for every User
I download data on a specific server by sending that ID
Passing them to the ProfileViewController properties which are
declared in .h file
Then I load these properties there where I want
Anyway I think is too early for you to achieve these things, you have to learn iOS step by step and practice will give you experience to achieve great things.

uiimagepicker differentiate where the call was made

I guess this is a two part question. First part is: I have a view controller where there are two Image Views, both user inter-actable. In both I call:
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
UIImagePickerController *imagePicker = [[UIImagePickerController alloc]init];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:imagePicker animated:YES completion:nil];
}
And the delegate method handles the picked image form the photo library. But right now I have to way of choosing which Image View gets that picture unless I make a custom UIView with two buttons where the user picks the Image View. It's more clicks and not very practical. I tried making another NSObject file but it can't use [self presentViewController...]. Calling the method in a new View Controller can't present UIImagePickerController because it's not in the window hierarchy. Is there a way to differentiate inside didFinishPickingMediaWithInfo which Image View calls the picker?
And maybe this second part of the question doesn't really belong here but it still has to do with pictures. If the user selects one picture and adds it to the gallery, goes and selects another and another...lets say 10 pictures...what's the best way of doing this, I mean GCD or NSOperationQueue? Reason why I'm asking is what if the user is on a slow mobile internet connection and after loading them to either GCD or NSOpQueue they leave the view controller...will those images continue loading to the server? I know you can make an order with NSOpQueue and I guess you can cancel the operation when the viewWillDisappear...Is that the way to do it?
I know it's a log of writing and not a lot of code but trying to learn the best way to go about all this. Thanks!
Here is my experience of what I've done in similar situations, I hope this helps.
First, regarding the initial part of your question, you have not way of reading the parameters of the method didFinishPickingMediaWithInfo to determine what UIImageView was the one pressed. But you can easily keep a reference to the lastPressedImageView in you view controller and keep it as simply as reading this variable once you receive didFinishPickingMediaWithInfo.
Regarding the second part of your question I recommend you reading / researching about AFNetworking which is a really powerful and easy to learn library for networking in iOS. You'd need to add your own logic to create the requests and send them, as well as for controlling possible errors, but this lib will help you to concentrate on logic instead of low-level networking concerns.

UIImagePickerView blank images?

I am instantiating a UIImagePicker like so:
self.picker = [[UIImagePickerController alloc] init];
[self.picker setDelegate:self];
[self.picker UIImagePickerControllerSourceTypePhotoLibrary];
[myVC presentViewController:self.picker animated:YES completion:nil];
And for some reason, it doesn't ask me for permission to view my images (on device, it is magically already allowed access (checked in Privacy settings)) and the images are blank. Yes, you heard correctly. Blank. They're completely white. However when I tap in a location where a image should be present, it shows the image in the editor view and displays the image.
Interestingly enough, this issue had nothing to do with NavigationControllers, UIImages/ImageViews or even ViewControllers. I had a category on NSDictionary that overrode objectForKeyedSubscript. I guess users images are stored or retrieved in a Dictionary and when they tried to index into it for the UIImage, it failed somehow. Or maybe pulled a path that was nil.
The moral of this story is, BEWARE the CATEGORY.

Pass data between UITabBarController views

I have searched for an entire day for a simple example on this and haven't found it yet. I am working on an app and I want to make an API call on the initial load and populate some variables that will be accessible in any of the tab views.
Example: I want to make a single API call to get my data which will include data relating to alerts for the alerts tab. I want to use this data on the initial load to update the "Alerts" tab badge. However, I want to also use that information on the alerts page once the person goes to that tab without having to make another API call to get the same information again.
I have read a ton of explanations that do not fit my requirements, so I am looking for a good example to help me out.
Use your UITabBarViewController's viewControllers property to access the array of view controllers in your tab bar controller. Typecast them according to your architecture of tab bar controller.
Then get a pointer to any of view controller using that array.
For example, say your tab bar controller has 5 tabs, each tab having a UINavigationController which has particular UIViewController as root view controllers. Say you want to set badge value of 3rd tab to your web response array count. You can do that as
[[[self.tabviewController viewControllers] objectAtIndex:2]
setBadgeValue:[NSString stringWithFormat:#"%d",[myArray count]];
You can also get to particular view controller's property by typecasting the view controllers. For example
MyViewController *myVc = (MyViewController*) [[(UINavigationController*)[[self.tabviewController viewControllers] objectAtIndex:2] viewControllers] objectAtIndex:0];
[myVc setPropertyName:propertyValue];
I had this question typed up since yesterday and made sure to search before posting. There was no question similar that I found that had the answer, and it may be very straight forward or maybe this is not the way to do it but here is how I solved this issue: using NSUserDefaults and the code example on this page
Put the data in your app delegate object. You can access it from anywhere in your app by (MyAppDelegate *)[[UIApplication sharedApplication] delegate], or you can give each of your view controllers an explicit link to it.
NSUserDefaults isn't really meant for sharing data globally in your app, although it would get the job done. It also has the benefit that the information sticks around if your app can't connect to the server next time. Is that a good thing or a bad thing?
Put all of those variables in a single class and access a shared instance of it whenever you want.
Add
+ (YourClass *)sharedObject
{
static YourClass *sharedClassObject = nil;
if (sharedClassObject == nil) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedClassObject = [[YourClass alloc] init];
//Initialise it here if necessary
});
}
return sharedClassObject;
}
To access the shared instance, simply use [YourClass sharedObject].
You should use NSNotificationCenter to post the notification that new data arrived and your new data as an object.
Each of the viewControllers that need that object should just subscribe to that notification and just consume the new data.

iOS Using HTML links to fetch data

I'm creating an interactive book for learning languages. It has reading, quiz and some simple game. The content of each chapter is an HTML file. The book allows the user to learn about 300 words that exist in the text. Earch word was enclosed in a link like this: < a href="word">word< /a> when the user touch the link, a modal view appears with the translation and information about that word.
This is the code I'm using to get the link:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
// currentWord is the word in the link
self.currentWord = [[request URL] lastPathComponent];
// okToCatchLinks is a BOOL that I use to avoid showing the modalview when the page
// is loaded for the first time.
if (okToCatchLinks){
NSLog(#"Ok to catch links!");
WordViewController *viewController = [[WordViewController alloc] initWithNibName:#"WordViewController" bundle:nil]
// I did my homework creating the delegate protocol to dismiss the modal view.
viewController.delegate = self;
// This is a label in the modalview showing the word in the HTML link.
viewController.labelTitle = self.currentWord;
// Create a Navigation controller to add the "DONE" dismiss button
UINavigationController *navController = [[UINavigationController alloc]
initWithRootViewController:viewController];
navController.modalPresentationStyle = UIModalPresentationFormSheet;
navController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
// show the navigation controller modally
[self presentModalViewController:navController animated:YES];
// Clean up resources
[navController release];
[viewController release];
}
okToCatchLinks = YES;
return YES;
}
With this code I will get the selected word in a string variable. Then I search that word in the DB using CoreData.
The HTML is UTF-8 encoded. I have to be able to search for that word in different languages. So if the user click on the word (日本語) or (résumé) I have to be able to find it in the DB.
For the data store I converted an CSV file to a .sqlite file.
I wonder if there is a better way to do this. Personally I don't like to use < a href=""> to get the link, but I couldn't find any other way to get the current word in a link. Also performing the search of that word in the DB is not clean, because I'm not using any UID for each row. I just compare the string holding the word with the words in the corresponding column of the DB.
Is there a more efficient way to do this?
To resume: Having a list of words, mark those words in the HTML so the user can touch and retrieve information about that word from a DB.
Some observations:
UIDs: As long as your words are unique, you can use that column as the primary key without using a separate UID. Actually, Core Data will create one for you anyway, so you can use objectWithID to retrieve your word.
HTML Links: Your solution with UIWebView, HTML files and links seems feasible to me. However, you could of course also use a UITextView and handle the selections programmatically, working with NSRange. That would perhaps be more complicated, but also more "native".
Delegate: You only need a delegate if you want to pass information back to the view that first presented the model view controller (too much homework! ;-)). Just dismiss it from within with
[self dismissModalViewControllerAnimated:YES];

Resources