Decode base64 string to PDF


#1

How can we decode base64 string and convert it into PDF file and view it in iOS …?

NSData *data = … // from your converted Base64 string
NSString *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@“test.pdf”];
[data writeToFile:path atomically:YES]


#2

Below is obj-c translated to JS. I believe however that you can write to the file system using the fs component that is provided with {N}.

const base64String = "";
const data = NSData.dataFromBase64String(base64String);
const documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true).objectAtIndex(0);
const path = documentsDirectory.stringByAppendingPathComponent("test.pdf");

data.writeToFileAtomically(path, true);

#3

@NordlingArt :
Do you have any example with fs component that handles base64 content and save file in PDF format and able to view it. ?


#4

@pap the last 3 lines of the code can be replaced by the FS API as described in the official docs.

const documents = fs.knownFolders.documents();
const path = fs.path.join(documents.path, "test.pdf");
const pdfFile = fs.File.fromPath(path);

pdfFile.writeText(data).then(function () { .... }, function (error) { });

#5

Hello @pap5508, @Pete.K
I’m having the same problem, using NativeScript + Angular.
I’m getting a PDF which consists of scanned papers, and when I get it and try to save it after doing base64.decode() I get a file which is 30% larger than the data itself, and it can’t be read by PDF.

So, I was wondering if this solved your problem on an iOS app, and how did you access NSData because TypeScript compiler tells me NSData cannot be found.

Here’s my relevant code:

let basePath = fs.knownFolders.documents();
this.folder = basePath;
this.file = this.folder.getFile(file.name + file.extension);
this.jobsService.getFile(file.rowGUID).subscribe(fileData => {
    let rawdata = base64.decode(fileData.fileContent);
    let filename = fileData.name + fileData.extension;
    let path = fs.path.join(fs.knownFolders.documents().path, filename);
    this.file.writeText(rawdata)
        .then(file => {
            if(fileData && fs.File.exists(path)) {
                utilModule.ios.openFile(path);
            } else {
                dialogs.alert("file doesn't exist");
            }
        }).catch( err => console.log(err))
});

How to base64 encode a string in NativeScript
#6

Okay, I found out how to access native APIs, however NSData doesn’t have a static method dataFromBase64String.
Does it work for you guys?


#7

Here’s my working solution:

basePath = fs.knownFolders.documents();
this.folder = basePath;//.getFolder("Documents");
this.file = this.folder.getFile(file.name + file.extension); // create a file with name...
this.jobsService.getFile(file.rowGUID).subscribe(fileData => {                        
    const rawdata = NSData.alloc().initWithBase64EncodedStringOptions(fileData.fileContent, 1); 
    let filename: string = fileData.name + fileData.extension;
    let path: string = fs.path.join(fs.knownFolders.documents().path, filename);
    rawdata.writeToFileAtomically(path, false);            
    if(fileData && fs.File.exists(path)) {
        let opened = utilModule.ios.openFile(path);                        
        console.log(opened ? 'Opened' : 'Not opened');
    } else {
        var dialogs = require("ui/dialogs");
        dialogs.alert("File doesn't exist");
    }           
});

#8

please, show to me the jobsService


#9
import { Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { BackendService } from './backend.service';
import { Injectable } from '@angular/core';
import { Response } from "@angular/http";
import { JwtHttp } from '../utils/ngx-jwt-refresh';


@Injectable()
export class JobsService {

    journals: Array<any>;
    docs: Array<any>;
    isLoading: Observable<boolean>;
    
    constructor (private jwtHttp: JwtHttp, private router: Router){
        this.isLoading = this.jwtHttp.iStatus$;
    }
    
    search(term){                       
        return this.jwtHttp
            .post(
                BackendService.apiUrl + "api/job/search", 
                { searchString: term }
            )
            .map(response => response.json())
            .map(jobs => {
                jobs.forEach(job => {                    
                    switch(job.jobStatusDescription) {
                        case 'Pending': job.color = '#fe9a2e'; break;
                        case 'No Job': job.color = '#2e2e2e'; break; 
                        case 'In Progress': job.color = '#f4fa58'; break; 
                        case 'Complete': job.color = '#9ff781'; break;
                        case 'Closed': job.color = '#a4a4a4'; break;
                        case 'Collections': job.color = '#81bef7'; break;
                        default: job.color = '#ffffff'
                    }                    
                });                
                return jobs;
            }) 
            //.catch(this.handleErrors);
            .catch(response => {
                if (response.status == 401) {                    
                    this.router.navigate(['login']);
                    return Observable.throw(response);
                }
            })
    }

    getJob(id: number) {
        return this.jwtHttp
            .get(BackendService.apiUrl + "api/job/get/" + id)
            .map(response => {
                let job = response.json();
                BackendService.add_recent_job(response.json());
                return job;
            })            
            .catch(this.handleErrors);
    }

    getJournals(id: number){
        return this.jwtHttp
            .get(BackendService.apiUrl + 'api/job/getJournalEntries/' + id)
            .map(response => response.json())            
            .catch(this.handleErrors);
    }

    newJournal(id: number, text: string) {
        return this.jwtHttp
            .post(BackendService.apiUrl + 'api/job/AddJournalEntry', { jobId: id, journalText: text});
    }

    getDocs(id: number) {
        return this.jwtHttp
            .get(BackendService.apiUrl + 'api/job/GetDocumentsList/' + id)
            .map(response => response.json())            
            .catch(this.handleErrors);
    }

    getFile(id: string) {
        return this.jwtHttp
            .get(BackendService.apiUrl + 'api/job/GetDocumentContentBase64/' + id)
            .map(response => response.json())           
            .catch(this.handleErrors);
    }

    handleErrors(error: Response) {
        //console.log(JSON.stringify(error/*.json()*/));
        //return Observable.throw(error);
        console.error('server error: ', error);
        if (error instanceof Response) {
            let errMessage = '';
            try {
                errMessage = error.json().error;
            } catch (err) {
                errMessage = error.statusText;
            }
            if (error.status == 401) {                
                this.router.navigate(['login']);
                return Observable.throw(errMessage);               
            }
            return Observable.throw(errMessage);            
        }
        return Observable.throw(error || '.Net server error');
    
    } 

    uploadDocument(docdata) {
        return this.jwtHttp
            .post(BackendService.apiUrl + 'api/job/UploadDocument', docdata);
    }
}

#10

thank you very much. Your guide is very useful.


#11

Hi Milosstanic,

I tried your code to decode base64 to pdf but it doesn’t work. Which package you used to decode? where is your base64 come from? (do you use this one: https://www.npmjs.com/package/Base64)

NSData is unknown when you run on Android platform. It works wel with IOS platform