I have a .GPX file contains routing info of a hiking trip which I want to load into my app. Everything is ok if I load it from remote URL (https://dl.dropboxusercontent.com/u/45741304/appsettings/Phu_si_Lung_05_01_14.gpx) but I can't load this same file from app bundle (already in "Copy bundle resources" and had correct target membership).
Here's my code for loading this file from remote URL:
var xmlParser: XMLParser!
func startParsingFileFromURL(urlString: String) {
guard let url = URL(string: urlString) else {
print("Can't load URL: \(urlString)")
return
}
self.xmlParser = XMLParser(contentsOf: url)
self.xmlParser.delegate = self
let result = self.xmlParser.parse()
print("parse from URL result: \(result)")
if result == false {
print(xmlParser.parserError?.localizedDescription)
}
}
and from the main bundle:
func startParsingFile(fileName: String, fileType: String) {
guard let urlPath = Bundle.main.path(forResource: fileName, ofType: fileType) else {
print("Can't load file \(fileName).\(fileType)")
return
}
guard let url:URL = URL(string: urlPath) else {
print("Error on create URL to read file")
return
}
self.xmlParser = XMLParser(contentsOf: url)
self.xmlParser.delegate = self
let result = self.xmlParser.parse()
print("parse from file result: \(result)")
if result == false {
print(xmlParser.parserError?.localizedDescription)
}
}
Error on load from app bundle:
parse from file result: false
Optional("The operation couldn’t be completed. (Cocoa error -1.)")
You are saying:
guard let urlPath = Bundle.main.path(forResource: fileName, ofType: fileType) else {
print("Can't load file \(fileName).\(fileType)")
return
}
guard let url:URL = URL(string: urlPath) else {
print("Error on create URL to read file")
return
}
First, it is very silly to turn a string path into a URL. You knew you wanted a URL, so why didn't you start by calling url(forResource:...)?
Second, if you ever do turn a string path into a URL, you must make a file URL.
Related
I have an image that I want it's data to be saved in this fileUri generated by ("react-native-fs"). LibraryDirectoryPath/saved_images/{filename}:
/Users/macbookpro/Library/Developer/CoreSimulator/Devices/9CBD2F1E-7330-418D-81BE-108C064DEA7E/data/Containers/Data/Application/C26348CC-3463-43EF-9B26-B7E31641E2EA/Library/saved_images/6B3A6A3A-8DE3-488B-AF43-A54775545B38.jpg
And below is my implementation:
do {
let url = URL(string: fileUri)
let fileExisted = FileManager().fileExists(atPath: url!.path)
if (fileExisted) {
try decryptedData.write(to: url!)
} else {
let handle = try FileHandle(forWritingTo: url!)
handle.write(data) // data is type Data
handle.closeFile()
}
} catch {
reject("FileError", "Failed to write file", error)
}
I also tried let url = URL(fileURLWithPath: fileUri) with and without file:// prepending to fileUri
do {
let url = URL(fileURLWithPath: fileUri)
let fileExisted = FileManager().fileExists(atPath: url.path)
if (fileExisted) {
try decryptedData.write(to: url)
} else {
let handle = try FileHandle(forWritingTo: url)
handle.write(data)
handle.closeFile()
}
} catch {
reject("FileError", "Failed to write file " + error.localizedDescription, error)
}
it says:
You are using the wrong API.
let url = URL(string: fileUri)
is for strings representing a full – even encoded - URL starting with a scheme like file:// or https://.
On the other hand fileUri is actually a path without a scheme, so you have to use
let url = URL(fileURLWithPath: fileUri)
This returns a non optional URL by adding the file:// scheme.
fileUri should be renamed as filePath.
I have a table with the names of pdf documents. Previously, there were 3 documents and each one has its own ViewController. How can I make it so that with hundreds of documents, I would select one from the table and show it on the View, if I select another document, then on the same View show another document.
while I have such a function, where I substituted the name of the documents in each class and showed it in different representations. But now I need to display everything on one ViewController when selecting any document
import UIKit
import PDFKit
class pdfViewClass {
class func filePDfFunc(nameFile: String, formatFile:String,
nameView:PDFView)
{
if let path = Bundle.main.path(forResource: nameFile,
ofType:formatFile) {
if let pdfDocument = PDFDocument(url: URL(fileURLWithPath:
path)) {
nameView.autoScales = true
nameView.displayDirection = .vertical
nameView.document = pdfDocument
}
}
}
}
You can use Native Apple UIDocumentInteractionController for viewing PDF file.
Create a function like below for View PDF
func viewPdf(urlPath: String, screenTitle: String) {
// open pdf for booking id
guard let url = urlPath.toUrl else {
print("Please pass valid url")
return
}
self.downloadPdf(fileURL: url, screenTitle: screenTitle) { localPdf in
if let url = localPdf {
DispatchQueue.main.sync {
self.openDocument(atURL: url, screenTitle: screenTitle)
}
}
}
}
Function for download PDF
// method for download pdf file
func downloadPdf(fileURL: URL, screenTitle: String, complition: #escaping ((URL?) -> Void)) {
// Create destination URL
if let documentsUrl: URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
let destinationFileUrl = documentsUrl.appendingPathComponent("\(screenTitle).pdf")
if FileManager.default.fileExists(atPath: destinationFileUrl.path) {
try? FileManager.default.removeItem(at: destinationFileUrl)
}
let sessionConfig = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfig)
let request = URLRequest(url: fileURL)
let task = session.downloadTask(with: request) { tempLocalUrl, response, error in
if let tempLocalUrl = tempLocalUrl, error == nil {
// Success
if let statusCode = (response as? HTTPURLResponse)?.statusCode {
print("Successfully downloaded. Status code: \(statusCode)")
}
do {
try FileManager.default.copyItem(at: tempLocalUrl, to: destinationFileUrl)
complition(destinationFileUrl)
} catch let writeError {
print("Error creating a file \(destinationFileUrl) : \(writeError)")
}
} else {
print("Error took place while downloading a file. Error description: \(error?.localizedDescription ?? "N/A")")
}
}
task.resume()
} else {
complition(nil)
}
}
Function for open documents
func openDocument(atURL url: URL, screenTitle: String) {
self.documentInteractionController.url = url
self.documentInteractionController.name = screenTitle
self.documentInteractionController.delegate = self
self.documentInteractionController.presentPreview(animated: true)
}
On tap of tableView pass the specific index URL
viewPdf(urlPath: "http://www.africau.edu/images/default/sample.pdf", screenTitle: "Tesing Document")
You can do it using WKWebView easily. Use WKWebView to load your pdf doc.
the code i used for downloading the book is ..
//Create URL to the source file you want to download
let fileURL = URL(string:myFileURL)
let sessionConfig = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfig)
let request = URLRequest(url:fileURL!)
let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in
if let tempLocalUrl = tempLocalUrl, error == nil {
// Success
if let statusCode = (response as? HTTPURLResponse)?.statusCode {
print("Successfully downloaded. Status code: \(statusCode)")
DispatchQueue.main.async {
self.toast(msg: "Download completed")
self.activityIndicator.stopAnimating()
self.activityIndicator.isHidden = true
}
}
do {
try FileManager.default.copyItem(at: tempLocalUrl, to: destinationFileUrl)
} catch (let writeError) {
print("Error creating a file \(destinationFileUrl) : \(writeError)")
}
} else {
print("Error took place while downloading a file. Error description: %#", error?.localizedDescription);
}
after that i tried to unzip the epub file from the destinationFileUrl using the code
let status = SSZipArchive.unzipFile(atPath: destinationFileUrl , toDestination:destPath, delegate:self)
the status value returns false, so the output folder only contains META-INF folder with no items
How can i unzip the epub correctly
Please refer this -->> Not getting eject file after unzipping downloaded file URL
var filepath = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)[0]
filepath += "/\(UUID().uuidString)"
let url = URL(fileURLWithPath: filepath)
do {
try FileManager.default.createDirectory(at: url, withIntermediateDirectories: true, attributes: nil)
let done = SSZipArchive.unzipFile(atPath: path!, toDestination: url.path)
if done{
let items = try FileManager.default.contentsOfDirectory(atPath: url.path)
print(items)
}
} catch let error as NSError{
print(error)
}
How do I load an image from specified url and save it to an existing local png file ? I'm trying to do it as follow but get an error
The file couldn’t be saved because the specified URL type isn’t supported
let url = URL(string: urlString)
let data = try? Data(contentsOf: url!)
try data?.write(to: URL(string: "icon.png")!)
First of all never use synchronous Data(contentsOf to load data from a server.
The error occurs because the URL has the wrong format
A remote URL must contain a scheme and host (http://server.com...)
An local URL in the file system must be created with URL(fileURLWithPath: and the path must start with a slash.
Use the following code to asynchronously download a file:
extension FileManager {
open func secureCopyItem(at srcURL: URL, to dstURL: URL) -> Bool {
do {
if FileManager.default.fileExists(atPath: dstURL.path) {
try FileManager.default.removeItem(at: dstURL)
}
try FileManager.default.copyItem(at: srcURL, to: dstURL)
} catch (let error) {
print("Cannot copy item at \(srcURL) to \(dstURL): \(error)")
return false
}
return true
}
}
func download() {
let storagePathUrl = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString).appendingPathComponent("file.png")
let fileUrl = "https://server/file.png"
let urlRequest = URLRequest(url: URL(string: fileUrl)!)
let task = URLSession.shared.downloadTask(with: urlRequest) { tempLocalUrl, response, error in
guard error == nil, let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else {
print("Error")
return
}
guard FileManager.default.secureCopyItem(at: tempLocalUrl!, to: storagePathUrl) else {
print("Error")
return
}
}
task.resume()
}
I'm trying to copy some (media) files from one folder to another using FileManager's copyItem(at:path:), but I'm getting the error:
CFURLCopyResourcePropertyForKey failed because it was passed an URL which has no scheme
Error Domain=NSCocoaErrorDomain Code=262 "The file couldn’t be opened because the specified URL type isn’t supported."
I'm using Xcode 9 beta and Swift 4.
let fileManager = FileManager.default
let allowedMediaFiles = ["mp4", "avi"]
func isMediaFile(_ file: URL) -> Bool {
return allowedMediaFiles.contains(file.pathExtension)
}
func getMediaFiles(from folder: URL) -> [URL] {
guard let enumerator = fileManager.enumerator(at: folder, includingPropertiesForKeys: []) else { return [] }
return enumerator.allObjects
.flatMap {$0 as? URL}
.filter { $0.lastPathComponent.first != "." && isMediaFile($0)
}
}
func move(files: [URL], to location: URL) {
do {
for fileURL in files {
try fileManager.copyItem(at: fileURL, to: location)
}
} catch (let error) {
print(error)
}
}
let mediaFilesURL = URL(string: "/Users/xxx/Desktop/Media/")!
let moveToFolder = URL(string: "/Users/xxx/Desktop/NewFolder/")!
let mediaFiles = getMediaFiles(from: mediaFilesURL)
move(files: mediaFiles, to: moveToFolder)
The error occurs because
URL(string: "/Users/xxx/Desktop/Media/")!
creates a URL without a scheme. You can use
URL(string: "file:///Users/xxx/Desktop/Media/")!
or, more simply,
URL(fileURLWithPath: "/Users/xxx/Desktop/Media/")
Note also that in fileManager.copyItem() the destination must
include the file name, and not only the destination
directory:
try fileManager.copyItem(at: fileURL,
to: location.appendingPathComponent(fileURL.lastPathComponent))