how to add json file in ActionRequestHandler safari extinction - ios

I am develop a add blocker app, so i want to add json file in my ActionRequestHandler class from document directory. In ActionRequestHandler class already have code that add blockerList.json which is in main bundle
actually main problem is this if i edit in blockerList.json then its not editable because of permission because this file is in main bundle so aap don't provide on editing in any file.So i generate a new file in document directory which is editable but i cant add it in safari extention. here is my code
- (void)beginRequestWithExtensionContext:(NSExtensionContext *)context {
NSItemProvider *attachment;
NSString *contentOfURL;
NSString *documentsFilePath = [self grabFilePath:#"Block.json"];
NSURL *documentsURL = [NSURL fileURLWithPath:documentsFilePath];
if ([documentsFilePath length] != 0) {
NSError *error;
// NSURL *url = [NSURL URLWithString:APP_DEFAULT_BLOCKS_URL];//[[NSURL alloc] initWithString:APP_DEFAULT_BLOCKS_URL]
contentOfURL = [NSString stringWithContentsOfURL:documentsURL encoding:NSUTF8StringEncoding error:&error];
if (error)
NSLog(#"Error reading remote json file: %#", error.localizedDescription);
}
if (contentOfURL != (id)[NSNull null] && contentOfURL.length != 0) {
attachment = [[NSItemProvider alloc] initWithItem:contentOfURL typeIdentifier:#"public.json"];
} else {
NSLog(#"URL not defined or accessible - using local JSON");
attachment = [[NSItemProvider alloc] initWithContentsOfURL:[[NSBundle mainBundle] URLForResource:#"blockerList" withExtension:#"json"]];
}
NSExtensionItem *item = [[NSExtensionItem alloc] init];
item.attachments = #[attachment];
[context completeRequestReturningItems:#[item] completionHandler:nil];
}
- (NSString *)grabFilePath:(NSString *)fileName {
NSString *filePath = [[NSString alloc]initWithFormat:#"Documents/%#", fileName];
NSString *documentsFilePath = [NSHomeDirectory()stringByAppendingPathComponent:filePath];
return documentsFilePath;
}

Related

UIDocumentPickerViewController copied files disappear on download to test iPad

I am using UIDocumentPickerViewController to allow the user to select files that will be "attached" and available within the App. The concept is allow the user to send detail via email with the selected file attachments.
As each file is attached, I copy the file from the tmp Inbox (where fileManager puts the imported file) to a directory I create within the App document directory called "fileAttachments".
I list the files in a UITableView and the user can select each entry and preview the content within a QLPreviewController view using the path stored in the file object fileOJ.filePath.
It all works swimmingly well, until a reload of the project down to my test iPad, then all the files seem to disappear. My list of the files is still fine, but there is no file at the path location.
Any help with just what is happenning would be greatly appreciated.
- (IBAction)selectFilesAction:(UIBarButtonItem *)sender {
NSArray *UTIs = [NSArray arrayWithObjects:#"public.data", nil];
[self openFilePicker:UTIs];
}
- (void)openFilePicker:(NSArray *)UTIs {
UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:UTIs inMode:UIDocumentPickerModeImport];
documentPicker.delegate = self;
documentPicker.allowsMultipleSelection = FALSE;
documentPicker.popoverPresentationController.barButtonItem = self.selectFilesButton;
[self presentViewController:documentPicker animated:TRUE completion:nil];
}
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray <NSURL *>*)urls {
NSLog(#"picked URLs %#", urls);
// selecting multiple documents is cool, but requires iOS 11
for (NSURL *documentURL in urls) {
//get file details
NSDictionary *attr = [documentURL resourceValuesForKeys:#[NSURLFileSizeKey,NSURLCreationDateKey] error:nil];
NSLog(#"object: %#", attr);
NSNumber *fileSize = [attr valueForKey:NSURLFileSizeKey];
NSDate *dateFileCreated = [attr valueForKey:NSURLCreationDateKey];
NSDateFormatter *storageDateFormat = [[NSDateFormatter alloc] init];
[storageDateFormat setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSString *createdDateString = [storageDateFormat stringFromDate:dateFileCreated];
MMfile *fileObj = [[MMfile alloc]init];
fileObj.fileName = documentURL.lastPathComponent;
fileObj.meetingID = _meetingID;
fileObj.fileSize = fileSize;
fileObj.fileCreateDate = createdDateString;
//move file to new directory
fileObj.filePath = [self movefile:documentURL.lastPathComponent sourceFilePath:documentURL.path directory:#"fileAttachments"];
//save file details
[self.meetingModel saveFile:fileObj];
//refresh array and reload table
self.fileArray = [self.meetingModel getFiles:self.meetingID];
[self.tableView reloadData];
}
}
- (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller {
NSLog(#"cancelled");
}
-(NSString *)movefile:(NSString *)filename sourceFilePath:(NSString *)sourcePath directory:(NSString *)directoryName{
// Move file from tmp Inbox to the destination directory
BOOL isDir;
NSError *error;
NSFileManager *fileManager= [NSFileManager defaultManager];
//get directory path
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString* directoryPath;
if (paths>0) {
NSString *documentsDirectory = [paths objectAtIndex:0];
directoryPath = [NSString stringWithFormat:#"%#/%#",documentsDirectory,directoryName];
}
if(![fileManager fileExistsAtPath:directoryPath isDirectory:&isDir])
if(![fileManager createDirectoryAtPath:directoryPath withIntermediateDirectories:NO attributes:nil error:NULL])
NSLog(#"Error: Create folder failed %#", directoryPath);
NSString *destinationPath = [NSString stringWithFormat:#"%#/%#",directoryPath,filename];;
BOOL success = [fileManager moveItemAtPath:sourcePath toPath:destinationPath error:&error];
if (success) {
NSLog(#"moved file");
}else{
NSLog(#"error %#",error.description);
}
return destinationPath;
}
Found the issue. When the project is rebuilt and downloaded to the iPad the AppID changes, and as the documents path includes the AppID, so the documents path changes. Key is not to save the file path, only the file name and rebuild the path each instance. After having found the issue, I now see other similar posts I didn't find earlier. Also see Document directory path change when rebuild application

Attempt to rename file in Documents directory has error "file:/..."

Below is the code I have written to change the name of any file stored in an iOS device "Documents" directory.
When renaming the file using this code, the prefix resolves to...
"file:/localhost/private/var/mobile/Applications/.../Documents/"
instead of the correctly formatted...
"file://localhost/private/var/mobile/Applications/.../Documents/"
I am losing a slash, and so the rename method fails!!!
I have rewritten this for both NSString and NSURL formats, and both methods present the identical error. I have tested this using the iOS Simulator and on device, and both tests present the identical error.
I suspect I am overlooking something simple, but cannot figure what it is - any help please?
- (void)alterFileNameOrExtension {
NSError *errorMove = nil;
NSError __autoreleasing *error = nil;
//note below - entity attribute document.dStringURL has a data type NSString
NSString *file = [document.dStringURL lastPathComponent];
NSString *fileName = [file stringByDeletingPathExtension];
NSString *fileExtension = [file pathExtension];
NSString *fileNameNew = nil;
//note below - self.tempFileComponent, self.tempFileName & self.tempFileExtension
//note below - are set in the (IBAction) method textFieldDidEndEditing:
//note below - self.tempFileComponent determines whether the user is attempting to change the file name or the file extension
if (self.tempFileComponent == 1) {
fileNameNew = [[self.tempFileName stringByAppendingPathExtension:fileExtension] stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
} else if (self.tempFileComponent == 2) {
fileNameNew = [fileName stringByAppendingPathExtension:self.tempFileExtension];
} else {
NSLog(#"%# - %# - attempt to determine tempFileComponent has (possible undefined) E~R~R~O~R: %#_", self.className, NSStringFromSelector(_cmd), error.localizedDescription);
}
NSString *filePath = [document.dStringURL stringByDeletingLastPathComponent];
NSString *filePathNew = [filePath stringByAppendingPathComponent:fileNameNew];
BOOL move = [[NSFileManager defaultManager] moveItemAtPath:document.dStringURL toPath:filePathNew error:&errorMove];
if (!move) {
//handle error
} else {
//complete process
}
}
#
With assistance from #Mario, I have adjusted my code and include the working version below for the benefit of others...
#
NSError *errorMove = nil;
NSError __autoreleasing *error = nil;
NSString *file = [document.dStringURL lastPathComponent];
NSString *fileName = [file stringByDeletingPathExtension];
NSString *fileExtension = [file pathExtension];
NSString *fileNameNew = nil;
if (self.tempFileComponent == 1) {
fileNameNew = [self.tempFileName stringByAppendingPathExtension:fileExtension];
} else if (self.tempFileComponent == 2) {
fileNameNew = [fileName stringByAppendingPathExtension:self.tempFileExtension];
} else {
NSLog(#"%# - %# - attempt to determine tempFileComponent has (possible undefined) E~R~R~O~R: %#_", self.className, NSStringFromSelector(_cmd), error.localizedDescription);
}
NSURL *fileURLOld = [NSURL URLWithString:document.dStringURL];
NSURL *fileURLPrefix = [fileURLOld URLByDeletingLastPathComponent];
NSURL *fileURLNew = [fileURLPrefix URLByAppendingPathComponent:fileNameNew];
BOOL move = [[NSFileManager defaultManager] moveItemAtURL:fileURLOld toURL:fileURLNew error:&errorMove];
if (!move) {
//handle error
} else {
//complete process
}
The NSString path manipulation methods like stringByAppendingPathComponent expects file paths not URLs. It will remove double slashes as this is not a valid file path (although it is a valid URL).

Song doesn't play when method called from another class

I'm trying to play a song in my application. When the the code to play a song is put right away in the controller it runs good.
But when i put the code in a class, call the class then call the method to play the song, nothing happens ? If someone have a clue please feel free to help.
here is the code to play a song
-(void)randomSound{
NSLog(#"sound");
NSString * path;
NSError * err;
NSString *name;
NSArray *names = [[NSArray alloc] initWithObjects:#"1up.wav", #"mario02.dsp.wav", #"mario04.dsp.wav", #"mario06.dsp.wav", #"mrf.dsp.wav", nil];
name = [names randomObject];
path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:name];
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
NSURL * url = [NSURL fileURLWithPath:path];
self.snd = [[AVAudioPlayer alloc] initWithContentsOfURL:url
error:&err] ;
if (! self.snd) {
NSLog(#"data named '%#' had error %#", name, [err localizedDescription]);
} else {
NSLog(#"playing");
[self.snd prepareToPlay];
[self.snd play];
}
} else {
NSLog(#"data file '%#' doesn't exist at '%#'", name, path);
}
}
The way i call the method
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"YAHOO"])
{
YahooViewController *YH = [[YahooViewController alloc] init];
[YH randomSound];
}
The random method in case someone would like to know whats in it
-(id)randomObject {
NSUInteger myCount = [self count];
if (myCount)
return [self objectAtIndex:arc4random_uniform(myCount)];
else
return nil;
}
After discussion in comments it was identified the issue was URL encoding.
Check out this question / answer which will show you how to URLEncode a string:
How do I URL encode a string

Unable to create ReaderDocument Vfr-Reader

I searched a lot but can't open PDF with vfr-reader from documents folder.
NSString *filePath = #"/Users/***/Library/Application Support/iPhone Simulator/5.0/Applications/F2B7E9DE-9996-4F05-BC81-2A2889B4F504/Documents/Number1.pdf";
ReaderDocument *document = [ReaderDocument withDocumentFilePath:filePath password:password];
if (document != nil)
{// document comes nil here
ReaderViewController *readerViewController = [[ReaderViewController alloc] initWithReaderDocument:document];
readerViewController.delegate = self; // Set the ReaderViewController delegate to self
[self.navigationController pushViewController:readerViewController animated:YES];
}
I am sure that filepath is exact the pdf file.
In the example code of reader it opens the pdf from main bundle. But I need to open from resources folder.
Thanks
i facing same issue, may be you also have same one.
if you are not using ARC than just write -fobjc-arc to every pdf reader file in build face. that will solve your problem.
You should use [[NSBundle mainBundle] bundlePath] and stringByAppendingPathComponent: instead of hard-coding the string. This is quite horrible and will only ever work on the iOS Simulator.
You should give file name like below code,don't give directly
NSArray *pathss = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPaths = [pathss objectAtIndex:0];
NSString *filePaths = [documentsPaths stringByAppendingPathComponent:[NSString stringWithFormat:#"%#",fileName]];
I understand this is an old post but none the less I ran into a similar problem as #user1392687 and wanted to share how I resolved the issue (I was loading files from various directories not just the Documents folder).
Problem: Load a series of PDF files out of a directory, populate a table view with filenames and supporting meta data, then upon selecting a cell, open the PDF file using VFR Reader.
Solution: The folder within X-Code is a Folder Reference to enable content updates without having to perform the remove/add cycle of a Group Reference. The function below was used to read all contents - URLs - of a specific folder path then remove all/any simlinks contained within the returned file paths. Prior passing the URL into VRF to load the PDF file [url path] was used for a RFC 1808 (unescaped) path.
+ (NSArray *)enumerateContentsOfFolderWithPath:(NSURL *)aFolderPath
{
NSError *error = nil;
NSArray *contentProperties = #[NSURLIsDirectoryKey,
NSURLIsReadableKey,
NSURLCreationDateKey,
NSURLContentAccessDateKey,
NSURLContentModificationDateKey];
NSArray *contents = [[NSFileManager defaultManager] contentsOfDirectoryAtURL:aFolderPath
includingPropertiesForKeys:contentProperties
options:NSDirectoryEnumerationSkipsHiddenFiles
error:&error];
if (error != nil)
DLog(#"Content enumeration error: %#", error);
NSMutableArray *pdfURLs = [NSMutableArray array];
for (NSURL *item in contents)
{
NSURL *fileURL = [NSURL fileURLWithPath: [item path]];
NSURL *noSimlink = [fileURL URLByResolvingSymlinksInPath];
[pdfURLs addObject: noSimlink];
}
return pdfURLs;
}
After populating the table view with the contents of the folder and all supporting metadata, and upon a user touching a row to view the PDF file, the VRF Reader was setup as follows:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Other setup code...
NSURL *item = [pdfURLs objectAtIndex:(NSUInteger) indexPath.row];
[self presentPdfViewerForItem: item];
}
- (void)presentPdfViewerForItem:(NSURL *)aItem
{
NSString *phrase = nil; // Document password (for unlocking most encrypted PDF files)
NSString *filePath = [aItem path];
ReaderDocument *document = [ReaderDocument withDocumentFilePath: filePath password:phrase];
if (document != nil) // Must have a valid ReaderDocument object in order to proceed
{
ReaderViewController *readerViewController = [[ReaderViewController alloc] initWithReaderDocument:document];
readerViewController.delegate = self;
readerViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
readerViewController.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:readerViewController animated:YES completion:nil];
}
}

iOS plist is null

I know there are a multitude of questions about this on SO but I can't see where I am making the mistake and am hoping some extra eyes will help. I've verified the plist is in my bundle and it is also in my docs directory and it contains data. Here's a screen capture of the app package with the plist at top:
I pass the plist in from another class and have verified that it is the correct plist.
Here's my code:
-(id)init {
if (self = [super init]) {
//set up the appTracker
appTracker = [[OAI_AppTracker alloc] init];
//set up a file manager and error container
fileManger=[NSFileManager defaultManager];
//docs directory path
documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
//track event
appTracker.appEvent = #"File Manager initialized";
[appTracker recordEvent];
}
return self;
}
- (NSDictionary* ) readPlist {
NSError* error;
//set up dictionary to hold our app data
NSDictionary* appData;
//set up destination path
NSString* destinationPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#", plistToRead]];
if ([fileManger fileExistsAtPath:destinationPath]){
//read plist
appData = [[NSDictionary alloc] initWithContentsOfFile:destinationPath];
} else {
//file doesn't exist so we have to move it to the doc folder
NSString *sourcePath=[[[NSBundle mainBundle] resourcePath]stringByAppendingPathComponent:plistToWrite];
[fileManger copyItemAtPath:sourcePath toPath:destinationPath error:&error];
//now read the plist
appData = [[NSDictionary alloc] initWithContentsOfFile:destinationPath];
}
NSLog(#"%#", appData);
return appData;
}
My log shows NULL instead of the data in the plist. Appreciate any help as to what I am doing wrong.
To read your plist try something like this:
NSString *plistPath = [[NSBundle mainBundle] pathForResource:#"PlistFileName" ofType:#"plist"];
NSDictionary *plistData = [[NSDictionary alloc] initWithContentsOfFile:plistPath];

Resources