How to store pdf from a url in phone memory [closed] - swift

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I have pdf url, I want to know the code how to store that pdf in my phone memory. I want to store that pdf and want to view that pdf from phone. I am using swift 4 and Xcode for coding

Swift 4
Call this function only pass url and after downloading it will be return file url........
func get_file(httpUrl:String)
{
let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let url = URL(string: httpUrl)!
let destinationUrl = documentsUrl.appendingPathComponent(url.lastPathComponent)
let session = URLSession(configuration: URLSessionConfiguration.default, delegate: nil, delegateQueue: nil)
var request = URLRequest(url: url)
request.httpMethod = "GET"
let task = session.dataTask(with: request, completionHandler:
{
data, response, error in
if error == nil
{
if let response = response as? HTTPURLResponse
{
if response.statusCode == 200
{
if let data = data
{
if let _ = try? data.write(to: destinationUrl, options: Data.WritingOptions.atomic)
{
print(destinationUrl.absoluteString)
}
else
{
print(error!)
}
}
else
{
print(error!)
}
}
}
}
else
{
print(error!)
}
})
task.resume()
}
here you caught your file ..
let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let url = URL(string: file_str)!
let destinationUrl = documentsUrl.appendingPathComponent(url.lastPathComponent)

Related

Cocoa: How do I change the download destination? Swift

I’m trying to download a file from a URL, I managed to do that however, the it will download to ~Libray directory. How do I change the directory to the downloads folder? or out of the library directory.
Here is my file downloader…
import Foundation
class FileDownloader {
static func loadFileSync(url: URL, completion: #escaping (String?, Error?) -> Void)
{
let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .allDomainsMask).first!
let destinationUrl = documentsUrl.appendingPathComponent(url.lastPathComponent)
if FileManager().fileExists(atPath: destinationUrl.path)
{
print("File already exists [\(destinationUrl.path)]")
completion(destinationUrl.path, nil)
}
else if let dataFromURL = NSData(contentsOf: url)
{
if dataFromURL.write(to: destinationUrl, atomically: true)
{
print("file saved [\(destinationUrl.path)]")
completion(destinationUrl.path, nil)
}
else
{
print("error saving file")
let error = NSError(domain:"Error saving file", code:1001, userInfo:nil)
completion(destinationUrl.path, error)
}
}
else
{
let error = NSError(domain:"Error downloading file", code:1002, userInfo:nil)
completion(destinationUrl.path, error)
}
}
static func loadFileAsync(url: URL, completion: #escaping (String?, Error?) -> Void)
{
let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let destinationUrl = documentsUrl.appendingPathComponent(url.lastPathComponent)
if FileManager().fileExists(atPath: destinationUrl.path)
{
print("File already exists [\(destinationUrl.path)]")
completion(destinationUrl.path, nil)
}
else
{
let session = URLSession(configuration: URLSessionConfiguration.default, delegate: nil, delegateQueue: nil)
var request = URLRequest(url: url)
request.httpMethod = "GET"
let task = session.dataTask(with: request, completionHandler:
{
data, response, error in
if error == nil
{
if let response = response as? HTTPURLResponse
{
if response.statusCode == 200
{
if let data = data
{
if let _ = try? data.write(to: destinationUrl, options: Data.WritingOptions.atomic)
{
completion(destinationUrl.path, error)
}
else
{
completion(destinationUrl.path, error)
}
}
else
{
completion(destinationUrl.path, error)
}
}
}
}
else
{
completion(destinationUrl.path, error)
}
})
task.resume()
}
}
}
I took a look at the code and I think it has to do something with this
let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .allDomainsMask).first!
let destinationUrl = documentsUrl.appendingPathComponent(url.lastPathComponent)
I have tried chinging the code from documentDirectory to desktopDirectory but that still puts it in the library directory. How do I change it from the library directory to the downloads directory?
You are running a sandboxed app. The Appname/Data/... directories are aliases of the real directories.
Also, you should use userDomainMask instead of allDomainsMask to search for the path in user's home directory. The correct directory you are looking for is downloadsDirectory.
let downloadsUrl = FileManager.default.urls(for: .downloadsDirectory, in: .userDomainMask).first!
let destinationUrl = downloadsUrl.appendingPathComponent(url.lastPathComponent)
There is another SO thread about sandboxed directories:
how to get /Users/username/Downloads path in a sandboxed app?

How to open .pdf URL in Safari browser in swift [duplicate]

This question already has answers here:
Swift - encode URL
(19 answers)
How to use stringByAddingPercentEncodingWithAllowedCharacters() for a URL in Swift 2.0
(6 answers)
Closed 3 years ago.
Here i trying to open URL with .pdf extension in Safari Browser. But code is not working I'm getting nil in URL. But when i tried URL like "www.google.com" it's working fine
Code
let cerificateURl = "https://file-examples.com/wp-content/uploads/2017/10/file-sample_150kB.pdf"
guard let url = URL(string: cerificateURl) else {
return
}
if #available(iOS 10.0, *) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
} else {
UIApplication.shared.openURL(url)
}
Thanks in Advance
Try this one:
guard let url = URL(string: "your web pdf file link here or you can set from local directory path")
else { return }
UIApplication.shared.open(url)
Try This one.
let cerificateURl = "https://file-examples.com/wp-content/uploads/2017/10/file-sample_150kB.pdf"
if let myURL = URL(string: url) {
if let data = try? Data(contentsOf: myURL) {
webView.load(data, mimeType: "application/pdf", characterEncodingName: "", baseURL: myURL
}
}

I am doing a post request where I want to type in a question and with the post request get the most common answer

I have done my Post-request but I am unsure about how to make it possible to send a full question and to get the most common answers back to my app.
I am in such a big need of this code in my program so would love to get some examples on how to make it work
Have tried to right the question into the parameters with a "+" instead of space which resulted into nothing.
#IBAction func GetAnswer(_ sender: Any) {
let myUrl = URL(string: "http://www.google.com/search?q=");
var request = URLRequest(url:myUrl!)
request.httpMethod = "POST"
let postString = questionAsked;
request.httpBody = postString.data(using: String.Encoding.utf8);
let task = URLSession.shared.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in
if error != nil
{
print("error=\(String(describing: error))")
return
}
print("response = \(String(describing: response))")
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = json {
let answer = parseJSON[" Answer "] as? String
self.AnswerView.text = ("Anwer: \(String(describing: answer))")
}
} catch {
print(error)
}
}
task.resume()
}
You do not use google.com/search, please check the api documentation
Paste following in Playground, should give a good start
struct Constants {
static let apiKey = "YOUR_API_KEY"
static let bundleId = "YOUR_IOS_APP_BUNDLE_ID"
static let searchEngineId = "YOUR_SEARCH_ENGINE_ID"
}
func googleSearch(term: String, callback:#escaping ([(title: String, url: String)]?) -> Void) {
let urlString = String(format: "https://www.googleapis.com/customsearch/v1?q=%#&cx=%#&key=%#", term, Constants.searchEngineId, Constants.apiKey)
let encodedUrl = urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
guard let url = URL(string: encodedUrl ?? urlString) else {
print("invalid url \(urlString)")
return
}
let request = NSMutableURLRequest(url: url, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10)
request.httpMethod = "GET"
request.setValue(Constants.bundleId, forHTTPHeaderField: "X-Ios-Bundle-Identifier")
let session = URLSession.shared
let datatask = session.dataTask(with: request as URLRequest) { (data, response, error) in
guard
error == nil,
let data = data,
let json = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String : Any]
else {
// error handing here
callback(nil)
return
}
guard let items = json["items"] as? [[String : Any]], items.count > 0 else {
print("no results")
return
}
callback(items.map { ($0["title"] as! String, $0["formattedUrl"] as! String) })
}
datatask.resume()
}
Usage
googleSearch(term: "George Bush") { results in
print(results ?? [])
}
Create a new search engine using following url
https://cse.google.com/cse/create/new
If you would like search entire web, use following steps
edit your engine using https://cse.google.com/cse/setup/basic?cx=SEARCH_ENGINE_ID
remove any pages listed under Sites to search
turn on Search the entire web

How do I save an image to a png file?

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()
}

Swift / iOS 10 : How to download a VIDEO and store within the app

I'm new to SWIFT/Programming &
I couldn't find an answer on my question, that's why I'm gonna give it a try here:
HOW Do I download a video (mp4) from an URL and store it within the app**
HOW Do I display the video then in a container**
I've already found this topic:
Swift - Downloading video with downloadTaskWithURL
But in my case, I wouldn't want the video to be safed in the camera-roll. Just within the app.
Thanks for any kind of help/hint !
You can use URLSession's dataTask or downloadTask to download any file from url(if it's downloadble)
Here's the way to use dataTask for downloading:
let videoUrl = "Some video url"
let docsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let destinationUrl = docsUrl.appendingPathComponent("MyFileSaveName.mp4")
if(FileManager().fileExists(atPath: destinationUrl.path)){
print("\n\nfile already exists\n\n")
}
else{
//DispatchQueue.global(qos: .background).async {
var request = URLRequest(url: URL(string: videoUrl)!)
request.httpMethod = "GET"
_ = session.dataTask(with: request, completionHandler: { (data, response, error) in
if(error != nil){
print("\n\nsome error occured\n\n")
return
}
if let response = response as? HTTPURLResponse{
if response.statusCode == 200{
DispatchQueue.main.async {
if let data = data{
if let _ = try? data.write(to: destinationUrl, options: Data.WritingOptions.atomic){
print("\n\nurl data written\n\n")
}
else{
print("\n\nerror again\n\n")
}
}//end if let data
}//end dispatch main
}//end if let response.status
}
}).resume()
//}//end dispatch global
}//end outer else
Now to play the saved file:
class MyViewController: UIViewController {
override func viewDidLoad() {
let baseUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let assetUrl = baseUrl.appendingPathComponent("MyFileSaveName.mp4")
let url = assetUrl
print(url)
let avAssest = AVAsset(url: url)
let playerItem = AVPlayerItem(asset: avAssest)
let player = AVPlayer(playerItem: playerItem)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
self.present(playerViewController, animated: true, completion: {
player.play()
})
}
}
However, most sites do not provide a direct dwonloadable link for video. You can get that link by playing the video in a UIWebView and register this following observer to get that link:
NotificationCenter.default.addObserver(self, selector: #selector(videoPlayedInWebView), name: NSNotification.Name(rawValue: "AVPlayerItemBecameCurrentNotification"), object: nil)
#objc func videoPlayedInWebView(aNotification: NSNotification) {
if let playerItem: AVPlayerItem = aNotification.object as? AVPlayerItem{
let asset: AVURLAsset = playerItem.asset as! AVURLAsset
var downloadebaleVideoUrl = asset.url
print(downloadebaleVideoUrl)
}
}
Here "downloadebaleVideoUrl" is the link that will be generated once the video plays in the webview.
If you have any questions, feel free to ask.
Note: This is will work only for sites that have mp4 files. 'HLS' streams won't be downloaded with this method. For that you can refer to this following answer:
https://stackoverflow.com/a/54493233/10758374
Edit: this works only with UIWebView and it won't work with WKWebView.
You need to create a local url, that will be a path in your app's file system and write the video's data into it.
func writeToFile(urlString: String) {
guard let videoUrl = URL(string: urlString) else {
return
}
do {
let videoData = try Data(contentsOf: videoUrl)
let fm = FileManager.default
guard let docUrl = fm.urls(for: .documentDirectory, in: .userDomainMask).first else {
print("Unable to reach the documents folder")
return false
}
let localUrl = docUrl.appendingPathComponent("test.mp4")
try videoData.write(to: localUrl)
} catch {
print("could not save data")
}
}
Keep in mind to always call this function in the background thread.