How to display a locally saved PDF | SwiftUI - pdf

I receive a String from a WebApi representing a Base64 PDF.
I implement this method to convert that Base64 String into a PDF and save it on documents.
/**
Saves Base64 to PDF
taken from: https://stackoverflow.com/a/40164036/15860448
*/
func saveBase64StringToPDF(_ base64String: String, fileName: String) -> URL? {
Logger.log(.warning, "Saving PDF...")
guard
var documentsURL = (FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)).last,
let convertedData = Data(base64Encoded: base64String)
else {
//handle error when getting documents URL
Logger.log(.error, "Error creating URL of PDF")
return nil
}
//name your file however you prefer
documentsURL.appendPathComponent("\(fileName).pdf")
do {
try convertedData.write(to: documentsURL)
//if you want to get a quick output of where your
//file was saved from the simulator on your machine
//just print the documentsURL and go there in Finder
Logger.log(.success, "Saved \(fileName) in \(documentsURL)")
return documentsURL
} catch {
//handle write error here
Logger.log(.success, "Error saving")
return nil
}
}
Now my goal is to open that File using the URL returned by saveBase64StringToPDF()
I have this method:
/**
Opens file
*/
func openFile(path: URL) {
if UIApplication.shared.canOpenURL(path) {
UIApplication.shared.open(path, options: [:], completionHandler: nil)
}
else{
Logger.log(.error, "Error opening URL: \(path)")
}
}
But I keep getting this error:
2022-03-03 14:34:39.271338+0100 LotoUp[7021:2647489] -canOpenURL: failed for URL: "file:///var/mobile/Containers/Data/Application/7D2DC4E8-90A7-4741-A730-CE039894FC88/Documents/liquidacion_2022-7_148.pdf" - error: "This app is not allowed to query for scheme file"
Any help?

Related

What happens in Dropbox API for iOS (Swift) if I create a folder that already exists?

The first time I do it, I want the folder created.
The next time, should I check if folder already exists, or just do the create folder and assume nothing happens?
You can do this either way:
Check if the folder exists before attempting to create it:
client.files.getMetadata(path: folderPath).response { response, error in
if let _ = response {
print("Something already exists at path.")
} else if let error = error {
switch error {
case .routeError(let boxed, _, _, _):
switch boxed.unboxed as Files.GetMetadataError {
case .path(let lookupError):
switch lookupError {
case .notFound:
print("Nothing was found at this path. Attempting to create folder...")
client.files.createFolderV2(path: folderPath).response { response, error in
if let response = response {
print("Created folder:")
print(response)
} else if let error = error {
print("Error creating folder: ")
print(error)
}
}
default:
print("Some other error occurred.")
// handle accordingly...
}
}
default:
print("Some other error occurred.")
// handle accordingly...
}
}
}
Always attempt to create the folder, and handle the error that occurs if it already exists:
client.files.createFolderV2(path: folderPath).response { response, error in
if let response = response {
print("Created folder:")
print(response)
} else if let error = error {
print("Error creating folder: ")
print(error)
// handle accordingly...
}
}

Import & Export PDF & Word Doc SwiftUI

I was not able to import or export PDF nor .doc documents to my app. This code below saves selected pdf inside iCloud or phone memory but when I try to view the pdf file it always converts to a document with only text "Hello World".
I guess I need to change allowedContentTypes in .fileImporter and contentType inside .fileExporter but after some research I could not find working example on the web.
#State private var document: MessageDocument = MessageDocument(message: "Hello, World!")
.fileImporter(
isPresented: $isImporting,
allowedContentTypes: [UTType.pdf],
allowsMultipleSelection: false
) { result in
do {
guard let selectedFile: URL = try result.get().first else { return }
//trying to get access to url contents
if (CFURLStartAccessingSecurityScopedResource(selectedFile as CFURL)) {
guard let message = String(data: try Data(contentsOf: selectedFile), encoding: .utf8) else { return }
document.message = message
//done accessing the url
CFURLStopAccessingSecurityScopedResource(selectedFile as CFURL)
}
else {
print("Permission error!")
}
} catch {
// Handle failure.
print(error.localizedDescription)
}
}
.fileExporter(
isPresented: $isExporting,
document: document,
contentType: UTType.data,
defaultFilename: "Message"
) { result in
if case .success = result {
// Handle success.
} else {
// Handle failure.
}
}
}
}
MessageDocument
import SwiftUI
import UniformTypeIdentifiers
struct MessageDocument: FileDocument {
static var readableContentTypes: [UTType] { [.plainText] }
var message: String
init(message: String) {
self.message = message
}
init(configuration: ReadConfiguration) throws {
guard let data = configuration.file.regularFileContents,
let string = String(data: data, encoding: .utf8)
else {
throw CocoaError(.fileReadCorruptFile)
}
message = string
}
func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
return FileWrapper(regularFileWithContents: message.data(using: .utf8)!)
}
}

How to upload and download Video using QuickBlox in Swift

I am uploading image and video to QuickBlox. My upload is successful but when i download the following scenarios occour:
1) In case of image i am able to download image and show (No issues in this)
2) My question is about video with below points
a) I am able upload video successfully
b) How would i be able to recognize the extension of video from server? I need sample code for uploading and downloading video from the QuickBlox. As if i upload .mov file then what should be the filetype and what should be in case of .mp4 and so on. And when i download the file how would i know the correct extension for the file and then how to get the correct file from the server and save it.
When uploading a video, set the type to "video" in the attachment and the corresponding content type, for example "video/mp4":
QBRequest.uploadFile(with: localVideoUrl, fileName: nameVideo, contentType: "video/mp4", isPublic: true,
successBlock: { (response: QBResponse, uploadedBlob: QBCBlob) -> Void in
let attachment = QBChatAttachment()
attachment.id = uploadedBlob.uid
attachment.name = uploadedBlob.name
attachment.type = "video"
attachment["size"] = "\(uploadedBlob.size)"
// send message with attachment
}, statusBlock: { (request : QBRequest?, status : QBRequestStatus?) -> Void in
let progress = CGFloat(Float(status.percentOfCompletion))
// show progress
}
}) { (response : QBResponse) -> Void in
//error handler
}
When you receive a message with attachment and attachment type is "videoā€¯, refer to this example:
let attachment = message.attachments?.first
if attachment.type == "video" {
QBRequest.downloadFile(withUID: attachment.id, successBlock: { (response: QBResponse, fileData: Data) in
let fileData = fileData as NSData
let fileName = ID + "_" + attachment.name
let filePath = NSTemporaryDirectory() + fileName
let fileURL = URL(fileURLWithPath: filePath)
if fileData.write(to: fileURL, atomically: true) == true {
//do what you need with the video - cache, save, play, etc.
} else {
print("failure write")
}
}, statusBlock: { (request: QBRequest, status: QBRequestStatus?) in
let progress = CGFloat(status.percentOfCompletion)
//show progress
}, errorBlock: { (response: QBResponse) in
//error handler
})
}

Objective-C to Swift: Facebook iOS API requestUserInfo method

Hi I am trying to figure out how to rewrite this in swift:
- (IBAction)requestUserInfo:(id)sender
{
// We will request the user's public picture and the user's birthday
// These are the permissions we need:
NSArray *permissionsNeeded = #[#"public_profile", #"user_birthday", #"email"];
// Request the permissions the user currently has
[FBRequestConnection startWithGraphPath:#"/me/permissions" completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error){
// Parse the list of existing permissions and extract them for easier use
NSMutableArray *currentPermissions = [[NSMutableArray alloc] init];
NSLog(#"The fucking class is: %#", [result class]);
NSArray *returnedPermissions = (NSArray *)[result data];
for (NSDictionary *perm in returnedPermissions) {
if ([[perm objectForKey:#"status"] isEqualToString:#"granted"]) {
[currentPermissions addObject:[perm objectForKey:#"permission"]];
}
} // cut cut here
}
EDIT:
I was having trouble trying to get the required data out of the FBGraphObject but figured it out after some further inspection. I have posted the swift version below so that people can just cut and paste it and get on with using swift. Hope it saves someone some time.
Here:
#IBAction func requestUserInfo(sender: AnyObject){
// These are the permissions we need:
var permissionsNeeded = ["public_profile", "user_birthday", "email"]
// Request the permissions the user currently has
FBRequestConnection.startWithGraphPath("/me/permissions", completionHandler: {(connection, result, error) -> Void in
if error == nil{
// Parse the list of existing permissions and extract them for easier use
var theResult = result as? [String:[AnyObject]]
var currentPermissions = [String]()
let returnedPermissions = theResult?["data"] as [[String:String]]
for perm in returnedPermissions {
if perm["status"] == "granted" {
currentPermissions.append(perm["permission"]!)
}
}
// Build the list of requested permissions by starting with the permissions
// needed and then removing any current permissions
println("Needed: \(permissionsNeeded)")
println("Current: \(currentPermissions)")
var requestPermissions = NSMutableArray(array: permissionsNeeded, copyItems: true)
requestPermissions.removeObjectsInArray(currentPermissions)
println("Asking: \(requestPermissions)")
// TODO PUT A POPUP HERE TO TELL WHAT PERMISSIONS WE NEED!
// If we have permissions to request
if requestPermissions.count > 0 {
// Ask for the missing permissions
FBSession.activeSession().requestNewReadPermissions(requestPermissions, completionHandler: {(session, error) -> Void in
if (error == nil) {
// Permission granted, we can request the user information
self.makeRequestForUserData()
} else {
// An error occurred, we need to handle the error
// Check out our error handling guide: https://developers.facebook.com/docs/ios/errors/
println("error: \(error?.description)")
}
})
} else {
// Permissions are present
// We can request the user information
self.makeRequestForUserData()
}
} else {
// An error occurred, we need to handle the error
// Check out our error handling guide: https://developers.facebook.com/docs/ios/errors/
println("error: \(error?.description)")
}
})
}
private func makeRequestForUserData() {
FBRequestConnection.startForMeWithCompletionHandler({(connection, result, error) -> Void in
if (error == nil) {
// Success! Include your code to handle the results here
println("user info: \(result)")
} else {
// An error occurred, we need to handle the error
// Check out our error handling guide: https://developers.facebook.com/docs/ios/errors/
println("error: \(error?.description)")
}
})
}
// Show an alert message
func showMessage(text : NSString, title : NSString){
var alert = UIAlertController(title: title, message: text, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
UIApplication.sharedApplication().delegate?.window!?.rootViewController?.presentViewController(alert, animated: true, completion: nil)
}

Problems with download link in phonegap android pdf

Someone know how to download an file (pdf) using phonegap for android
I already looked a lot of tutorial but any of them work for me.
THank you.
You will need to make use of the FileTransfer object here: http://docs.phonegap.com/en/3.3.0/cordova_file_file.md.html#FileTransfer.
With this, you will need to call the download method - passing in the file URI, destination and success/error callbacks.
I.e., if I want to download a PDF, you could do so as follows:
var win = function(r) {
console.log("Should not be called.");
}
var fail = function(error) {
// error.code == FileTransferError.ABORT_ERR
alert("An error has occurred: Code = " + error.code);
console.log("upload error source " + error.source);
console.log("upload error target " + error.target);
}
var ft = new FileTransfer();
ft.download(
'http://www.mydomain.com/mypdfdoc.pdf',
myURI, // you can obtain this via a window.requestFileSystem(...)
function (fileEntry) {
// do something with fileEntry
},
function (error) {
// handle error appropriately
});