Pregunta

So I am creating a .csv file and then allowing the user to share it using the UIActivityViewController.

My code to create the csv file will return the NSURL of the file:

- (NSURL *)exportToCSV
{
    NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
    NSString *filePath = [docPath stringByAppendingPathComponent:@"results.csv"];

    if (![[NSFileManager defaultManager] fileExistsAtPath:docPath]) {
        [[NSFileManager defaultManager] createFileAtPath:filePath
                                                contents:nil
                                              attributes:nil];
    }

    NSMutableString *contents = [NSMutableString stringWithCapacity:0];

    //fill contents with data in csv format
    // ...

    NSFileHandle *fileHandle = [NSFileHandle fileHandleForUpdatingAtPath:filePath];
    [fileHandle writeData:[contents dataUsingEncoding:NSUTF8StringEncoding]];
    [fileHandle closeFile];

    return [NSURL fileURLWithPath:filePath];
}

and then my activity uses that NSURL to initiate the UIActivityViewController:

- (IBAction)shareButtonPressed:(id)sender {

    NSArray *activityItems = @[@"results.csv", [self.object exportToCSV]];
    UIActivityViewController *shareScreen = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:nil];

    [self presentViewController:shareScreen animated:YES completion:nil];
}

When I select mail an option, the csv file is not attached. it just has the text "results.csv"

what am I doing wrong?

¿Fue útil?

Solución

The problem would appear to be in your fileExistsAtPath line. You appear to be saying "if the documents directory doesn't exist, then create the file". That's certainly not right.

Personally, I'd lose that stuff and change it to be

- (NSURL *)exportToCSV
{
    NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
    NSString *filePath = [docPath stringByAppendingPathComponent:@"results.csv"];

    NSMutableString *contents = [NSMutableString stringWithCapacity:0];

    //fill contents with data in csv format
    // ...

    NSError *error;

    [contents writeToFile:filePath
               atomically:YES
                 encoding:NSUTF8StringEncoding
                    error:&error];

    // check for the error

    return [NSURL fileURLWithPath:filePath];
}

Otros consejos

I want to share my solution of UIActivityViewController and sharing text as a CSV file. This solution works for sharing via Mail and even Save to Dropbox.

@IBAction func shareCsv(sender: AnyObject) {
    //Your CSV text
    let str = self.descriptionText.text!
    filename = getDocumentsDirectory().stringByAppendingPathComponent("file.csv")

    do {
        try str.writeToFile(filename!, atomically: true, encoding: NSUTF8StringEncoding)

        let fileData = NSURL(fileURLWithPath: filename!)

        let objectsToShare = [fileData]
        let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)

        self.presentViewController(activityVC, animated: true, completion: nil)

    } catch {
        print("cannot write file")
        // failed to write file – bad permissions, bad filename, missing permissions, or more likely it can't be converted to the encoding
    }

}

func getDocumentsDirectory() -> NSString {
    let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
    let documentsDirectory = paths[0]
    return documentsDirectory
}

Hope it helps! :)

This worked for me as a Swift 3 version, works as an attachment in Mail and saves in Dropbox.

var csvDetailsString = ""

for myObject in myObjectsArray {
    csvDetailsString = csvDetailsString.appending(myObject.someText)
    csvDetailsString = csvDetailsString.appending(",")
    csvDetailsString = csvDetailsString.appending("More Stuff")
    csvDetailsString = csvDetailsString.appending("\n")

}

let fileName = "Output"
let docDirectory = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
if let fileURL = docDirectory?.appendingPathComponent(fileName).appendingPathExtension("csv") {
    do {
        try csvDetailsString.write(to: fileURL, atomically: true, encoding: .utf8)

        let objectsToShare = [fileURL]
        let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)

        activityVC.excludedActivityTypes = [UIActivityType.addToReadingList]
        self.present(activityVC, animated: true, completion: nil)

    } catch let error as NSError {
        print("Failed writing to URL: \(fileURL), Error: " + error.localizedDescription)
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top