I have a url like this:
http://*****.ru/cgi-bin/****/****/cgi.exe?LNG=&C21COM=2&I21DBN=EKU_XML&P21DBN=EKU&Z21ID=1482179537193C7C43181117E030&Image_file_name=%5CFULL%5FTEXT%5CELBIB%5CNarodnye%5Fprazdniki%2Epdf&IMAGE_FILE_DOWNLOAD=1&SECUR=LOG&RIGHT=ALL
this url for downloading *.PDF file.
I use this function for download file
//method to be called to download
func download(url: URL)
{
self.url = url
//download identifier can be customized. I used the "ulr.absoluteString"
let sessionConfig = URLSessionConfiguration.background(withIdentifier: url.absoluteString)
let session = Foundation.URLSession(configuration: sessionConfig, delegate: self, delegateQueue: nil)
let task = session.downloadTask(with: url)
task.resume()
}
After calling this function, I get cgi.exe file, not pdf file. Why it's happen?
From your URL I can assume, that you are starting your cgi.exe with parameters to generate your pdf file. I think, that you need to send a request to your cgi.exe to generate file and place in response proper link to generated .pdf file. And then start your downloading operations with this URL.
Hope it helps
Related
In one of my iOS app, I'm trying to upload a file on WEBDAV repository and this is how I'm preparing things for UPLOAD -
func createUploadRequest(url: String) -> URLRequest? {
if let url = URL(string: url) {
var request = URLRequest(url:url)
request.httpMethod = "PUT"
request.setValue("1", forHTTPHeaderField: "Depth")
request.setValue("application/xml", forHTTPHeaderField: "Content-Type")
return request
}
return nil
}
#IBAction func upload() {
if let request = createUploadRequest(url: url) {
let sessionConfiguration: URLSessionConfiguration = URLSessionConfiguration.background(withIdentifier: "sessionIdentifier")
self.session = URLSession(configuration: sessionConfiguration, delegate: self, delegateQueue: nil)
uploadTask = self.session?.uploadTask(with: request as URLRequest, fromFile: self.fileUrl!)
self.uploadTask?.resume()
}
}
When upload is in progress and I cancel the uploadtask as follows
#IBAction func cancelUpload() {
self.uploadTask?.cancel()
}
The upload process gets canceled but the problem here is the file is getting corrupted on WEBDAV Server, which is being uploaded and uploadtask is canceled in between.
Strangely this is working fine in iOS 9 and upload process getting canceled properly without file being corrupted but iOS version 12 and above file getting corrupted.
I didn't check the behaviour on iOS 10 or 11 though.
Please help me get this issue resolved. Thank you in advance.
Please note that this bug persists with/without lock on WEBDAV resource
Whenever I try to use .addAttachmentURL, it does not attach anything. The ViewController is presented with nothing within the body of the text. The URL is a path to the pdf data (I don't know if that makes a difference) in my file defaults. Is there any way I can send a PDF through text like this? I have not found anything by looking through documentation or StackOverflow. Also, I haven't implemented it yet, but I was wondering if there was a way to also attach PNGs to this message I am sending along with the PDF.
func getFileManager() -> NSString {
let filePath = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString)
return filePath
}
func displayMessageInterface() {
let composeVC = MFMessageComposeViewController()
composeVC.messageComposeDelegate = self
// Configure the fields of the interface.
composeVC.recipients = ["000000000"]
var url = URL(string: self.getFileManager() as String)!
url.appendPathComponent("my_report.pdf")
composeVC.addAttachmentURL(url, withAlternateFilename:
"this file")
// Present the view controller modally.
if MFMessageComposeViewController.canSendText() {
self.present(composeVC, animated: true, completion: nil)
} else {
print("Can't send messages.")
}
}
You are using the wrong URL initializer. URL(string:) initializer expects a scheme, in this case file://. You need to use URL(fileURLWithPath:) initializer or simply get the document directory URL using FileManager urls method:
extension URL {
static let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
}
let url = URL.documentDirectory.appendingPathComponent("my_report.pdf")
I am not sure what you mean when you say "The URL is a path to the pdf data in my file defaults". If you have included your file in your project Bundle you need to use its url(forResource:) method.
let url = Bundle.main.url(forResource: "my_report", withExtension: "pdf")!
I am downloading mp4 clips from a M3U8 manifest which can have around 700 clips. Everything works fine to download them but what would be the best to check individual downloads are finished? When all the clips are downloaded, I merge them into one but I need to know when all my clips have been downloaded first.
This is the code snippet I use to download the video clip.
func download(video: String){
DispatchQueue.global(qos: .background).async {
if let url = URL(string: "http://SERVER/storage/sessions/SESSIONID/mp4_segments/\(video)"),
let urlData = NSData(contentsOf: url) {
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0];
let fileName = video
let filePath = "\(documentsPath)/SegmentVideos/\(fileName)"
urlData.write(toFile: filePath, atomically: true)
}
}
}
This is the code snippet that reads the M3U8 file and splits it so I can grab the video clip's name.
func checkM3U8forClips(){
guard let url = url else {return}
do {
let contents = try String(contentsOf: url)
let splitContent = contents.components(separatedBy: "\n")
for split in splitContent {
if split.hasSuffix("mp4") {
download(video: split)
}
}
} catch {
print("error with mp4 segments: \(error.localizedDescription)")
}
}
One reason you are in a quandary is that this code is wrong:
if let url = URL(string: "http://SERVER/storage/sessions/SESSIONID/mp4_segments/\(video)"),
let urlData = NSData(contentsOf: url) {
You must never use NSData(contentsOf:) to do networking. If you want to network, then network: use URLSession and a proper data task or download task. Now you get the callbacks you need; if you do it in the full form you get a full set of delegate callbacks that tell you exactly when a download has succeeded and completed (or failed).
As for your overall question, i.e. how can I know when multiple asynchronous operations have all finished, that is what things like DispatchGroup, or operation dependencies, or the new Combine framework are for.
I am having trouble loading a local HTML file. Here is my code. please help.
let URL = NSBundle.mainBundle().pathForResource("index2", ofType: "html")
let request = NSURLRequest(URL: url!)
Webview.loadRequest(request)
by use the following code. I have manage to load the html file but it doesn't load up the CSS!
let htmlFile = NSBundle.mainBundle().pathForResource("index1", ofType: "html")
let html = try? String(contentsOfFile: htmlFile!, encoding: NSUTF8StringEncoding)
GSFWebView.loadHTMLString(html!, baseURL: nil)
Simply write this code inside your ViewDidLoad i have added url of this page as example, just replace it with yours. On storyboard you don't need to do anything, if you have any extra view added on you view controller as container for website then replace self.view in my code with your view.
let myWebView:UIWebView = UIWebView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
//add your url on line below
myWebView.loadRequest(URLRequest(url: URL(string: "https://stackoverflow.com/questions/26647447/load-local-html-into-uiwebview-using-swift")!))
self.view.addSubview(myWebView)
And if you want to load page from local file, you can do it by defining url this way.
Swift 2
let url = NSBundle.mainBundle().URLForResource("webFileName", withExtension:"html")
Swift 3
let url = Bundle.main.url(forResource: "webFileName", withExtension: "html")
I only had to add this code to the viewDidLoad method:
1- First of all, you have to get the local URL from the Bundle. (previously, I added the index.html file to the project, copying when asked)
2- Then you have to create the request URL to be loaded from the webView.
3- After all, add the new webView created as a subView from the main view.
That worked for me.
if let url = Bundle.main.url(forResource: "index", withExtension: "html"){// 1st step
webView.loadFileURL(url, allowingReadAccessTo: url)
let request = URLRequest(url: url as URL) // 2nd step
webView.load(request)
self.view.addSubview(self.webView) // 3rd step
}
I search solution to send a mail with attachment.
I have this code but the file is not attached...
if let url = URL(string: "mailto:\(email)?subject=report&body=see_attachment&attachment=/Users/myname/Desktop/report.txt") {
NSWorkspace.shared().open(url)
}
I have see it maybe work with MessageUI, but I can't import this framework I don't know why. I get this error message : No such module 'MessageUI'
I checked in General > Linked Frameworks and Libraries, but there are not MessageUI...
Anyone have a solution to add file in mail?
Thanks
It seems that attachment in mailto: URLs are not supported on macOS (not always at least...details seems sketchy dependent on where you look on the internet :))
What you can use instead I found out from this blog post, is an instance of NSSharingService documented here
Here is an example demonstrating how to use it.
And in your case you could do something like:
let email = "your email here"
let path = "/Users/myname/Desktop/report.txt"
let fileURL = URL(fileURLWithPath: path)
let sharingService = NSSharingService(named: NSSharingServiceNameComposeEmail)
sharingService?.recipients = [email] //could be more than one
sharingService?.subject = "subject"
let items: [Any] = ["see attachment", fileURL] //the interesting part, here you add body text as well as URL for the document you'd like to share
sharingService?.perform(withItems: items)
Update
So #Spire mentioned in a comment below that this won't attach a file.
It seems there is a gotcha to be aware of.
For this to work you need to look into your App Capabilities.
You can either:
disable App Sandbox
enable read access for the folders from where you would like to fetch content.
I've attached a couple of screenshots.
Here is how this looks if I have disabled App Sandbox under Capabilities
And here is an image where I have enabled App Sandbox and allowed my app to read content in my Downloads folder
If I do the above, I can access my file called document.txt, located in my Downloads folder, using this URL
let path = "/Users/thatsme/Downloads/document.txt"
let fileURL = URL(fileURLWithPath: path)
And attach that to a mail
Hope that helps you.
import MessageUI
class ViewController: UIViewController,MFMailComposeViewControllerDelegate {
func sendMail() {
if( MFMailComposeViewController.canSendMail()){
print("Can send email.")
let mailComposer = MFMailComposeViewController()
mailComposer.mailComposeDelegate = self
//Set to recipients
mailComposer.setToRecipients(["yakupad#yandex.com"])
//Set the subject
mailComposer.setSubject("email with document pdf")
//set mail body
mailComposer.setMessageBody("This is what they sound like.", isHTML: true)
let pathPDF = "\(NSTemporaryDirectory())contract.pdf"
if let fileData = NSData(contentsOfFile: pathPDF)
{
print("File data loaded.")
mailComposer.addAttachmentData(fileData as Data, mimeType: "application/pdf", fileName: "contract.pdf")
}
//this will compose and present mail to user
self.present(mailComposer, animated: true, completion: nil)
}
else
{
print("email is not supported")
}
func mailComposeController(_ didFinishWithcontroller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?)
{
self.dismiss(animated: true, completion: nil)
}
}
First of all you should import import MessageUI. For this add framework to the project.
Example:
After investigate MFMailComposeViewControllerDelegate for knowing when you end sending email.
Example of the creating of the email:
if( MFMailComposeViewController.canSendMail() ) {
println("Can send email.")
let mailComposer = MFMailComposeViewController()
mailComposer.mailComposeDelegate = self
//Set the subject and message of the email
mailComposer.setSubject("Have you heard a swift?")
mailComposer.setMessageBody("This is what they sound like.", isHTML: false)
if let filePath = NSBundle.mainBundle().pathForResource("swifts", ofType: "wav") {
println("File path loaded.")
if let fileData = NSData(contentsOfFile: filePath) {
println("File data loaded.")
mailComposer.addAttachmentData(fileData, mimeType: "audio/wav", fileName: "swifts")
}
}
self.presentViewController(mailComposer, animated: true, completion: nil)
}
Working example is presented by this link.