Import file from another application using UIDocumentInteractionController - iphone

I want to develop an iOS application where i want to get any PDF/Doc/XLS file present in my Mail/Safari by using UIDocumentInteractionController and finally upload them to my local server.
I can able to upload image file present in my iPhone to my local server.
But my question is, can i able to fetch PDF/Doc/XLS file(present in safari/ Mail application) to my application by using UIDocumentInteractionController & upload them to my local server?

It is indeed possible to Import a file from another application using UIDocumentInteractionController in case of an iPad app. All you need to do is in info.plist of you application you need to add supported document formats. Add applicationDidFinshWithLaunchingOptions delegate method to your app in application delegate class in the following manner.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self applicationDidFinishLaunching:application];
if (launchOptions && [launchOptions objectForKey:UIApplicationLaunchOptionsURLKey])
{
NSString* path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSURL *url=[launchOptions objectForKey:UIApplicationLaunchOptionsURLKey];
NSString *sourceFilePath=[url path];
NSFileManager *fileManager=[NSFileManager defaultManager];
NSData *fileData=[fileManager contentsAtPath:sourceFilePath];
NSString *fileName = [NSString stringWithFormat:#"test.pdf"];
NSString *updatedFilePath = [path stringByAppendingPathComponent:fileName];
BOOL hasWrittenSuccessfully = [fileData writeToFile:updatedFilePath atomically:TRUE];
}
return YES;
}

You can't fetch documents, you can tell iOS that your app can open PDF/Doc/XLS.
Do this by adding supported filetype to you info.plist:
http://developer.apple.com/library/ios/#documentation/FileManagement/Conceptual/DocumentInteraction_TopicsForIOS/Articles/RegisteringtheFileTypesYourAppSupports.html#//apple_ref/doc/uid/TP40010411-SW1

Related

Setting NSDocumentDirectory so it doesn't backup to iCloud

I'm trying to mark the entire folder of my app's NSDocumentDirectory so that it is excluded from the iCloud backup, but when I go to the terminal and run: xattr -plxv com.apple.MobileBackup I get this error: No such xattr: com.apple.MobileBackup
Thank you in advance for any help offered.
Here is the code I'm using:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSURL *pathURL= [NSURL fileURLWithPath:documentsDirectory];
[self addSkipBackupAttributeToItemAtURL:pathURL];
}
- (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL
{
if (&NSURLIsExcludedFromBackupKey == nil) { // iOS <= 5.0.1
const char* filePath = [[URL path] fileSystemRepresentation];
const char* attrName = "com.apple.MobileBackup";
u_int8_t attrValue = 1;
int result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);
return result == 0;
} else { // iOS >= 5.1
NSLog(#"%d",[URL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:nil]);
return [URL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:nil];
}
}
How can you run Terminal on your iOS app's folder? You mean in the Simulator?
For sure Apple is going to ignore or strip out that attribute from the primary Documents folder. What you should do is what Apple tells developers to do (from File Systems Programming Guide):
Handle support files—files your application downloads or generates and can recreate as needed—in one of two ways:
In iOS 5.0 and earlier, put support files in the <Application_Home>/Library/Caches directory to prevent them from being backed up
In iOS 5.0.1 and later, put support files in the <Application_Home>/Library/Application Support directory and apply the com.apple.MobileBackup extended attribute to them. This attribute prevents the files from being backed up to iTunes or iCloud. If you have a large number of support files, you may store them in a custom subdirectory and apply the extended attribute to just the directory.
So you create a new directory for your files inside Application Support, and apply the attribute to that directory.
EDIT: Well, it seems that info is out of date and the document has not been updated. From the iOS 5.1 Release Notes:
iOS 5.1 introduces a new API to mark files or directories that should
not be backed up. For NSURL objects, add the
NSURLIsExcludedFromBackupKey attribute to prevent the corresponding
file from being backed up. For CFURLRef objects, use the corresponding
kCFURLIsExcludedFromBackupKey attribute.
Apps running on iOS 5.1 and
later must use the newer attributes and not add the
com.apple.MobileBackup extended attribute directly, as previously
documented. The com.apple.MobileBackup extended attribute is
deprecated and support for it may be removed in a future release.
It turns out that you can get actual code to do this in the Technical Q&A QA1719.
Also, I found I need to create the Application Support directory, at least in the Simulator. Hope this code helps:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// got to make sure this exists
NSFileManager *manager = [NSFileManager defaultManager];
NSString *appSupportDir = [self applicationAppSupportDirectory];
if(![manager fileExistsAtPath:appSupportDir]) {
__autoreleasing NSError *error;
BOOL ret = [manager createDirectoryAtPath:appSupportDir withIntermediateDirectories:NO attributes:nil error:&error];
if(!ret) {
LTLog(#"ERROR app support: %#", error);
exit(0);
}
}
...
}
- (NSString *)applicationAppSupportDirectory
{
return [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) lastObject];
}

How to List out .EPUB files in iPhone?

I am creating an epub reader. In that I want to list out .epub files from iphone. So I want to know is there any possible way to list out the .epub files from iphone (not just from the project directory path but also anywhere else in the phone)?
No, this is not possible.
Since there is no filesystem access, except the the directory with in apps sandbox.
All apps have to store the files they use with there sandbox, you tell iOS that you app can op .epub files. Which will allow the user to open the file from, example an email in your app.
As answered by #rckoenes, it is not possible to access the filesystem other than your app bundle.
You can access the files in your app bundle like this:
NSString *bundlePathName = [[NSBundle mainBundle] bundlePath];
NSError *error;
NSArray *bundleContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:bundlePathName error:&error];
for (NSString *currentItem in bundleContents) {
if ([currentItem rangeOfString:#"." options:NSBackwardsSearch].location != NSNotFound) {
int tempIndex = (int)([fileName rangeOfString:#"." options:NSBackwardsSearch].location);
tempIndex++;
NSString *aStrExtension = [[fileName substringWithRange:NSMakeRange(tempIndex, [fileName length]-tempIndex)] lowercaseString];
if ([aStrExtension isEqualToString:#"epub"]) {
//Add this file to an array, to make it available for choosing and view its details
}
}
}
If you mean you want to open ePub files saved not inside your application bundle, then you cant, you will have access only to the files inside your app sandbox
As per the #rckoenes: Any files out of App bundle is not accessible,
So I retrieved .epub files like this way.
NSString *bundleRoot = [[NSBundle mainBundle] bundlePath];
NSFileManager *manager = [NSFileManager defaultManager];
NSDirectoryEnumerator *direnum = [manager enumeratorAtPath:bundleRoot];
NSString *filename;
while ((filename = [direnum nextObject] )) {
if ([filename hasSuffix:#".epub"]) { //change the suffix to what you are looking for
[arrayListofEpub addObject:[filename stringByDeletingPathExtension]];
}
}

Xcode upload a plist file on a server (iPhone)

I have a simple (I think) question :
I got an iPhone. He create a plist file and he save it. I want to upload this file on a server.
Then, with 3 others iPhone, I will download this plist file and decrypt the informations.
My question is : How can I upload this plist file into a server !!
I don't have any FTP server or others ... Can I use instead Dropbox by exemple ?
Or is an other way to communicate between iPhone (private - not for AppStore) ?
Thanks very much for your answers !
Yes, you can use Dropbox API to upload a plist on the Dropbox user's folder.
Check first this link to setup your project
You can use these snippets (from this page):
NSString *localPath = [[NSBundle mainBundle] pathForResource:#"Info" ofType:#"plist"];
NSString *filename = #"Info.plist";
NSString *destDir = #"/";
[[self restClient] uploadFile:filename toPath:destDir
withParentRev:nil fromPath:localPath];
then implement the callbacks
- (void)restClient:(DBRestClient*)client uploadedFile:(NSString*)destPath
from:(NSString*)srcPath metadata:(DBMetadata*)metadata {
NSLog(#"File uploaded successfully to path: %#", metadata.path);
}
- (void)restClient:(DBRestClient*)client uploadFileFailedWithError:(NSError*)error {
NSLog(#"File upload failed with error - %#", error);
}
EDIT:
(if you want, you can load the plist from the Documents folder of your app. remember that the mainBundle is read-only so you can't modify the plist that resides in the main bundle, you can only read it)..like this:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *plistFilePath = [[paths objectAtIndex:0]stringByAppendingPathComponent:#"info.plist"];
NSDictionary *plistFile = [[NSMutableDictionary alloc] initWithContentsOfFile:plistFilePath];

iTunes file sharing. But sharing over http? iOS

I have a file which I want to file share. 'hello.mp3'
At the moment the code enables file sharing if the file is in the app.
I was hoping I would be able to do it over http. So file sharing with the link instead of the sound being in the app. I want to do this because it will save memory for the user.
Here is the current code. The code allows file sharing if the file is in the app. I want it so the user will 'download' the sound from a http server such as http://test.com/hello.mp3
Thanks
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSArray *names = [NSArray arrayWithObjects: #"hello.mp3",
#"hi.mp3", nil];
for (NSString *fileName in names)
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *documentDBFolderPath = [documentsDirectory stringByAppendingPathComponent:fileName];
if (![fileManager fileExistsAtPath:documentDBFolderPath])
{
NSString *resourceDBFolderPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:fileName];
[fileManager copyItemAtPath:resourceDBFolderPath toPath:documentDBFolderPath error:&error];
}
}
}
I may be wrong, but that may not be allowed. In the guidelines:
2.7 Apps that download code in any way or form will be rejected.
While an audio file may not be "code", if it is used within the app, perhaps as a language translation item, etc...I would think it would be rejected...just my 2 cents worth though.
Correct, you can "stream" content over HTTP, but if your using HTTP AND saving to the "Documents" directory to hold content you risk rejection by the app store.
If you need a workaround maybe use the "tmp" directory and save a file off a file there. The complaint Apple has is mainly using phone data more than should be in a 3rd party application.

Check if it exists an app that can open a file before calling presentOpenInMenuFromRect

I have stored a file (pdf) in the "documents" directory and I would like to know how could be possible to detect if there are applications (app) installed in the mobile device that can open this file (for example, "pdf" files can be opened using "iBooks", "DropBox", ...). I would like to detect this before calling the method "presentOpenInMenuFromRect"; which shows a list of the possible applications that can handle a specific file. The desired behavior is:
1) Given a pdf stored in the "Document" directory, check if there are "app's" installed in the iPhone/iPad, which can open this file (iBooks, DropBox, ...). This is what I do not know how to do.
2) If no application in de iPhone/iPad can open the application, then do nothing, otherwise draw a "Save" button and then, if the user presses this "Save" button, then the "presentOpenInMenuFromRect" method will be called in order to show a list of possible app which can open that file. I know the way to present a list of of applications which can open a file; here are the source code:
The source code related to the "Save" button is:
- (void) saveFile:(UIWebView*)webView
{
NSString* fileName = [[NSFileManager defaultManager] displayNameAtPath:webView.request.URL.absoluteString];
#if DEBUG
NSLog(#"<%p %#: %s line:%d> File name:%#", self, [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __PRETTY_FUNCTION__, __LINE__, fileName);
#endif
NSURL* fileurl = [NSURL URLWithString:webView.request.URL.absoluteString];
NSData* data = [NSData dataWithContentsOfURL:fileurl];
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* docsDirectory = [paths objectAtIndex:0];
NSString* filePath = [docsDirectory stringByAppendingPathComponent:fileName];
[data writeToFile:filePath atomically:YES];
NSURL* url = [NSURL fileURLWithPath:filePath];
//UIDocInteractionController API gets the list of devices that support the file type
docController = [UIDocumentInteractionController interactionControllerWithURL:url];
[docController retain]; //Very important, if "retain" is not called, the application crashes
//Present a drop down list of the apps that support the file type,
//clicking on an item in the list will open that app while passing in the file.
BOOL isValid = [docController presentOpenInMenuFromRect:CGRectZero inView:webView animated:YES]; //Using "webView" instead of "self.view"
if (!isValid)
{
[self showAlertSaveFileError:fileName]; //Shows an alert message
}
}
Thanks in advance.
Note: The response time of calling the method "presentOpenInMenuFromRect" is about several seconds, so this is the reason why I would like to know if there is a another way to detect and get a list of possible app installed on the mobile device which can open a specific file (pdf, ...)
Check out ihasapp.
http://www.ihasapp.com/
it says that it is an iOS framework that lets developers detect apps that are currently installed on their users' devices.