Ultimate Goal: upload pdf to AWS S3 server
Where i am now:
I've been developing on IOS for over a month now and one thing it lacks is access to a simple file management system. Coming off of Android I could simply open a view which would let me access the downloads, photos, Google Drive, etc. On Android its simple, I choose the PDF I want to upload and that's it. On IOS I have yet to find a way to access PDF's or files. Only thing that works so far is viewing photos and videos and choosing one of them to upload.
is there a way to access a PDF on an IPad/IPhone to upload to an AWS S3 server?
My code so far:
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
documentsDirectory = [paths objectAtIndex:0];
filePathsArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:documentsDirectory error:nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
NSArray *filePathsArray;
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section
{
if ([filePathsArray count] > 0){
return [filePathsArray count];
}else{
return 1;
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MainCell"];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"MainCell"];
}
cell.textLabel.text = [documentsDirectory stringByAppendingPathComponent:[filePathsArray objectAtIndex:indexPath.row]];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *pdfPicked = cell.textLabel.text;
NSLog(#"PDF is: %#", pdfPicked);
}
#end
This code will look through the files in the documents folder and display the file path of each file in a UITableView. If i add a PDF to the documents folder then i can see it on the table view but apparently you cannot access the documents folder on an actual IPhone or IPad.
you can use document picker to pick documents from icloud and outside app's sandbox.
you can get reference of document picker here DocumentPicker
for document picker demo you can click on github
Related
Hi guys I am new to Objective C. I want to make an app where it can read a csv file locally and display the data in a specific column in the tableview.
1)Read csv locally
2)Display csv data (let's say fifth column "ItemName") in the tableview
Thanks for any advice.
- (void)viewDidLoad {
[super viewDidLoad];
NSString *strPath = [[NSBundle mainBundle] pathForResource:#"issues" ofType:#"csv"];
NSString *strFile = [NSString stringWithContentsOfFile:strPath encoding:NSUTF8StringEncoding error:nil];
if (!strFile) {
NSLog(#"Error reading file.");
}
issues = [[NSArray alloc] init];
issues = [strFile componentsSeparatedByString:#","];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return[issues count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *simpleTableIdentifier = #"SimpleTableCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [issues objectAtIndex:indexPath.row];
return cell;
}
The way you do the parsing is only making columns of the whole file. First you need to separate by line-breaks (probably '\n'), then you can separate each line by ',' and each time take the 5th element and add it to an NSMutableArray (issues).
[strFile componentsSeparatedByString:#","] is not really CSV-parsing, there are more complex libraries available for that on cocoapods. If you need error-handling, etc. you better go with a library.
This question already has an answer here:
How To Reload Dictionaries On Tableview By Segment Button Click Using Objective C?
(1 answer)
Closed 7 years ago.
I am trying to create Plist dictionary data's read and load into tableview. Here, I am maintaining two segment control button and single tableview. Whenever I selected segment control button one I need to load first plist dictionary data then button two to load second one. I need to differentiate two data set and based on button click It should reload.
My Code:
// to read data
NSArray *pathse = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = pathse.firstObject;
NSString *plistPath = [documentsPath stringByAppendingPathComponent:#"port.plist"];
savedUrl = [[NSMutableDictionary alloc] initWithContentsOfFile: plistPath];
- (IBAction)Click_Segmentbutton:(id)sender {
switch (segment_Button.selectedSegmentIndex) {
case 0:{
break;}
case 1:{
break;}
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
NSIndexPath *indexPath;
if (indexPath.section == 0)
{
return [[savedUrl objectForKey:#"boysinfo"] count];
}
else
{
return [[savedUrl objectForKey:#"girlsinfo"] count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//Here I need to get whenever click the tableview cell selected cell all details
}
As per my understanding to your question, below is code for your purpose.
//Global
NSMutableDictionary *savedPlistDictionary;
- (void)viewDidLoad {
//Read the plist and save in plistDictionary.
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPathString = paths.firstObject;
NSString *plistNameString = #"second.plist"; //Second plist file
NSString *plistPathString = [documentsPath stringByAppendingPathComponent:plistNameString];
plistDictionary = [[NSMutableDictionary alloc] initWithContentsOfFile: plistPathString];
}
//Function to fetch the plist file based on index (segment selected)
- (void)saveDataWithSelectedIndex:(int)index {
if (index == 1){
savedPlistDictionary = [plistDictionary objectForKey:#"boysinfo"];
}
else {
savedPlistDictionary = [plistDictionary objectForKey:#"girlsinfo"];
}
}
- (IBAction)Click_Segmentbutton:(id)sender {
//Pass the selected index segment to function and savedPlistDictionary will be updated accordingly
switch (segment_Button.selectedSegmentIndex) {
case 0:{
[self saveDataWithSelectedIndex:0];
break;}
case 1:{
[self saveDataWithSelectedIndex:1];
break;}
}
[self.tableView reloadData]; //Reload the tableView
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [savedPlistDictionary count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//Here parse the data and load cells
}
One of the developer is implementing a phonegap project supporting cross platform(ios & android). Things are going weird whenever there ain't any plugin available for ios. I am exhausted with a requirement that has come up, we save pdf files generated in app to documents directory. In android, when choose file is clicked, a file explorer opens up for choosing file from desired location. I had to write a custom plugin for ios, as things are sandboxed in ios...only way a user can choose is files saved in app documents directory. I am trying to fetch the documents(pdf files) from the directory and populate them in table view. Actually I followed this link on Git repository for saving pdf file. The link follows a traditional way of saving in documents directory, but I don't see the file getting saved with extension '.pdf',surprisingly the pdf files are visible with extensions in temp directory embedded in unique folders. Moreover it wipes off the file from documents directory after the user opens the file in appropriate reader s/w.
When I tried to retrieve the files from temporary directory using the below code:
NSString *docPath = NSTemporaryDirectory();
self.filesArray = [[[NSFileManager defaultManager] contentsOfDirectoryAtPath:docPath error:NULL] mutableCopy];
for (NSString *file in _filesArray) {
NSString *actualFile = [NSString stringWithFormat:#"/%#",file];
docPath = [docPath stringByAppendingString:actualFile];
}
[_filePathsArray addObject:docPath];
As expected its returning only directories (I mean the folders).... and the pdf files are hidden in those subdirectories. I need to extract these files and show up in table view. Here is the sample code of the plugin I created:
- (NSMutableDictionary *)callbackIds {
if (_callbackIds == nil) {
_callbackIds = [[NSMutableDictionary alloc] init];
}
return _callbackIds;
}
-(void)open:(CDVInvokedUrlCommand *)command
{
[self.callbackIds setValue:command.callbackId forKey:#"open"];
CGFloat width = [UIScreen mainScreen].bounds.size.width;
CGFloat height = [UIScreen mainScreen].bounds.size.height;
self.listOfFiles = [[UITableView alloc] initWithFrame:CGRectMake(230, 210, width/1.8, height/1.8) style:UITableViewStylePlain];
self.listOfFiles.dataSource = self;
self.listOfFiles.delegate = self;
self.listOfFiles.scrollEnabled = YES;
self.listOfFiles.rowHeight = tableHeight;
[self.viewController.view addSubview:_listOfFiles];
}
#pragma mark - TableViewDataSource
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
self.filePathsArray = [[NSMutableArray alloc]init];
self.filesArray = [[NSMutableArray alloc]init];
NSString *docPath = NSTemporaryDirectory();
self.filesArray = [[[NSFileManager defaultManager] contentsOfDirectoryAtPath:docPath error:NULL] mutableCopy];
for (NSString *file in _filesArray) {
NSString *actualFile = [NSString stringWithFormat:#"/%#",file];
docPath = [docPath stringByAppendingString:actualFile];
}
[_filePathsArray addObject:docPath];
return _filesArray.count;
}
#pragma mark - TableViewDelegate
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = [NSString stringWithFormat:#"S%1dR%1d",indexPath.section,indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.textLabel.text = [_filesArray objectAtIndex:indexPath.row];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
// Send result back to the javascript plugin
NSString *resultingPath = [self.filePathsArray objectAtIndex:indexPath.row];
[self returnPluginResult:resultingPath toCallback:#"open" withError:NO];
[_listOfFiles removeFromSuperview];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return #"Choose File";
}
#pragma mark - Plugin Callback
- (void)returnPluginResult:(NSString *)result toCallback:(NSString *)callback withError:(BOOL)error
{
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:result];
if (!error) {
[self writeJavascript:[pluginResult toSuccessCallbackString:[self.callbackIds valueForKey:callback]]];
}
else {
[self writeJavascript:[pluginResult toErrorCallbackString:[self.callbackIds valueForKey:callback]]];
}
}
Someone please guide me with a solution or subsequent helpful links. I tried every samples of code over humongous googling and nothing seemed to solve my problem.
Thanks everyone in advance :)
The link I followed for storing the pdf is actually removing the file from documents directory upon storage. Truncating the removal code solved the issue for me. Hope this helps someone, thanks :)
This question already has answers here:
Objective-C: how to add a new cell for each filename in UiTableView?
(2 answers)
Closed 9 years ago.
Bellow I have some code that retrieves files from the documents directory where my application is stored on the idevice. It then successfully retrieves that path to the file which is a mp4 because that is what I am storing. And does this by displaying the filename in a cell of the UiTableView I have created . However the code only displays one file in one cell. But I want to list multiple files individually in there own cell so eventually the user can individually select that cell depending on the video file they want.
Here is the code that retrieves and displays the file directory of the file but does not list more then one file in the table:
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
filePathsArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:documentsDirectory error:nil];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
if(!filePathsArray) // if data loading has been completed, return the number of rows ELSE return 1
{
if ([filePathsArray count] > 0)
return [filePathsArray count];
else
return 1;
}
return 1;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MainCell"];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"MainCell"];
}
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
filePathsArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:documentsDirectory error:nil];
cell.textLabel.text = [filePathsArray[indexPath.row] lastPathComponent];
return cell;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
if(!filePathsArray)
{
if ([filePathsArray count] > 0)
return [filePathsArray count];
else
return 1;
}
return 1;
}
Should read:
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [filePathsArray count];
}
You should be returning [filePathsArray count]; from your numberOfRowsInSection method under normal circumstances. Right now you're actually returning 1 from that method in all cases. I'm not sure what exactly you're trying to do with the logic at the top of your numberOfRowsInSection method, but I think you should start by just replacing the whole body of the method with return [filePathsArray count];.
One more thing: You have a comment in there "if data loading has completed," but all the work in the code you posted is going synchronously on the main thread. By the time your viewDidLoad method has completed your filePathsArray is initialized. You don't need to do anything tricky to account for a case where filePathsArray is still nil, unless you're worried about the table view loading data before the view controller's view has actually loaded. But that would be very weird.
Why are you initializing filePathsArray over and over again first under viewDidLoad and then under tableview.
This is how I would write the code.
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
//initializing array and getting values the first time when page loads.
filePathsArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:documentsDirectory error:nil];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
//return whatever the count of this array is. no need to do any if! checks
return [filePathsArray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MainCell"];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"MainCell"];
}
cell.textLabel.text = [filePathsArray[indexPath.row] lastPathComponent];
return cell;
}
I am trying to load a plist from my project, this was working until I accidentally deleted my plist. the plist has 5 arrays, with 2 elements apiece. I know that I the program is trying to access beyond the range of the array, but what I don't know is where this index is set? Here is the code that it bombs on: this code is executed twice successfully,then for some reason it tries to access it a third time and bombs on the first line,why?
It throws this exception:
NSRangeException -[_NSCFARRAY objectAtIndex] index(2) beyond bounds (2)
please help, this is for a final project due on Monday and now I feel like I have to start over again.
NSString *nameOfAccount = [account objectAtIndex:indexPath.row];
cell.textLabel.text = nameOfAccount;
NSString *accountNumber = [number objectAtIndex:indexPath.row];
cell.detailTextLabel.text = accountNumber;
Since you are displaying the data in same cell, you can include both name and number of account into a dictionary or a custom model object which will hold both info.
In your plist this might be the structure, array of dictionary objects
When you are displaying the info. For the dataSource create an array say accounts.
#define kAccountName #"Name"
#define kAccountNumber #"Number"
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *filePath = [[NSBundle mainBundle]pathForResource:#"Accounts" ofType:#"plist"];
self.accounts = [NSArray arrayWithContentsOfFile:filePath];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.accounts count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSDictionary *account = self.accounts[indexPath.row];
cell.textLabel.text = account[kAccountName];
cell.detailTextLabel.text = account[kAccountNumber];
// Configure the cell...
return cell;
}
Source code