I am writing a program in Swift that uses Just to fetch a webpage. I am new to Swift and know very little about it. My code is simple:
let r = Just.get("https://www.google.com/")
print(r.statusCode!)
print(r.text)
I would expect to see the contents of the downloaded web page, however, the output is:
200
nil
How can I retrieve the text contents of the response?
The problem is in your URL. If you'll try this, your response won't be nil:
let r = Just.get("https://medium.com/")
print(r.text!)
}
Related
I am an iOS App developer using Swift. I opened Firebase Storage today and proceeded step by step in accordance with the help document. I can already view the txt file I uploaded on web browser with the url: "https://storage.googleapis.com/my_bucket_name/story_001.txt". But I encountered difficulty in accessing the txt file in the App. I think the problem lies in the generation of the reference. Here is my code:
let ref = Storage.storage().reference();
let txt_ref = ref.child("gs://my_bucket_name").child("story_001.txt");
print(txt_ref.fullPath);
txt_ref.getMetadata{ metadata, error in
if let err = error { print("Failed to get metadata."); }
else{ print("Metadata: \(metadata)"); }
}
I get the following output from console:
gs:/my_bucket_name/story_001.txt
Failed to get metadata.
The two slashes after "gs:" become one slash. I think the problem should come from here.
How can I solve it? Thanks in advance.
You may able to use the reference withPath: API like
let ref = Storage.storage().reference(withPath:"my_bucket_name")
let txt_ref = ref.child("story_001.txt")
See additional examples in these integration tests.
In my project UIWebView is being used for display forms and when user input data and submit the form, the javascript method of UIWebView is being used to get resulting string as:
let formstring: String = formWebView.stringByEvaluatingJavaScript(from: "document.getElementById('json').value;") ?? ""
in above formstring I get this as result:
{"personnel":"testName","textarea1":"testxyz","status":"1"}
Now I need to migrate from UIWebview to WKWebview as UIWebview is deprecated now. For this I have implemented the WKWebview and the form is displaying in it. but when I try to get value from javascript I get nothing as:
formWebView.evaluateJavaScript("document.getElementById('json').value;", completionHandler: {(result,error)in
if error != nil{
print(result)
formstring = result as! String
}
})
In above lines 'result' is always nil.
May be I am unable to understand what exactly is going on with UIWebView or I can't find out how to get output from WKWebView. The thing is I need to get form input from javascript in my code.
How to get it?
I have an app which is inconsistently returning 'nil' when using FileHandle to open a file for Read. I'm on OSX (10.13.4), XCode 9.4, Swift 4.1
This OSX app uses the NSOpenPanel() to get a list of files selected by the user. My 'model' class code opens these files to build a collection of data structures The code which does this starts out like this and successfully gets a FileHandle EVERY TIME for any file and is able to read data from the file.
private func getFITHeader(filename: String) {
let file: FileHandle? = FileHandle(forReadingAtPath: filename)
if file == nil {
print("FITFile >>> File open failed for file \(filename)")
}
else {
var databuffer: Data
databuffer = (file?.readData(ofLength: 80))!
:
:
}
The files also contain a block of binary data which I process in another part of the app. While I develop the code for this I'm temporarily hard coding one of the same filenames as works above for test purposes. BUT this code (below) ALWAYS throws an exception 'Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value' when it gets to fileHandle?.seek() - for some reason the attempt to create a FileHandle is always returning 'nil' despite the code being functionally identical to tha above.
#IBAction func btnProcFile(_ sender: Any) {
var data: Data
let filename = "/Users/johncneal/Dropbox/JN Astronomy/Astronomy/Spectroscopy/RSpec_Analyses/Gamma_Cas/20161203/Gamma Cas_065.fit"
let fileHandle: FileHandle? = FileHandle(forReadingAtPath: filename)
fileHandle?.seek(toFileOffset: 2880) //skip past the headers
let dataLenToRead = 1391 * 1039 * 2
data = (fileHandle?.readData(ofLength: dataLenToRead))!
:
:
}
The code in the second function works fine in a Playground (not attaching too much meaning to that) and, wierdly, has also worked when temporarily added to a different project. Probably also worth mentioning the length of the file path doesn't seem to matter - it behaves the same on short paths.
So the question is - why is this behaviour of FileHandle reliably inconsistent?
print()'ing the filenames presented to FileHandle() showed they were identical in each case (see below). So I'm stumped and frustrated by this - any perspectives or workarounds would be appreciated.
/Users/johncneal/Dropbox/JN Astronomy/Astronomy/Spectroscopy/RSpec_Analyses/Gamma_Cas/20161203/Gamma Cas_065.fit
/Users/johncneal/Dropbox/JN Astronomy/Astronomy/Spectroscopy/RSpec_Analyses/Gamma_Cas/20161203/Gamma Cas_065.fit
Found the answer - Sandboxing !!
Darren - coincidentally I did look at the URL based route and discovering it 'throws' put some proper error reporting in the catches. Low and behold they reported I didn't have permissions on the file (which initially surprised me since I'm obviously admin on my Mac's and all the files ar local and under my username.
I bit more research turned up. this article - https://forums.developer.apple.com/thread/96062 which quickly revealed its a sandboxing problem :-) Looks like recent versions of XCode have it turned on in 'Entitlements'. The post also points out that the NSOpenPanel FileOpen dialog returns 'Security scoped urls'. At first I thought this explained why the code in the first function worked but I'm not totally convinced because I was only feeding the url.path property to FileHandle.
However, turning off Sandbox in Entitlements makes everything work just fine. Yes, I know thats not the right thing to do longer term (or if I want this to go to the App Store) so I'll be checking out the right way to do this. At least I can get on now - thanks for the input.
The FileHandle initializers are not well named.
You should use FileHandle(forReadingFrom:URL) instead of FileHandle(forReadingAtPath:String). The former is newer API that throws an error instead of returning nil. You can use the thrown error to see why it is failing, and your variables are guaranteed to be non-nil.
For example:
#IBAction func btnProcFile(_ sender: Any) {
do {
let fileUrl = URL(fileURLWithPath:"/Users/johncneal/Dropbox/JN Astronomy/Astronomy/Spectroscopy/RSpec_Analyses/Gamma_Cas/20161203/Gamma Cas_065.fit")
let fileHandle = try FileHandle(forReadingFrom: fileUrl)
fileHandle.seek(toFileOffset: 2880) //skip past the headers
let dataLenToRead = 1391 * 1039 * 2
let data: Data = fileHandle.readData(ofLength: dataLenToRead)
// etc...
} catch let error as NSError {
print("FITFile >>> File open failed: \(error)")
NSApp.presentError(error)
}
}
I am working against a REST API where you can make a call and then receive a image or pdf. I am using URLSession.shared.dataTask to make the call and when there is a image the call is a success (but it takes quite a long time, more then 5 seconds) and I can show the image in a UIImageView. But when there is a pdf, I don't know how to handle the result. The API returns the image / pdf as a ”filestream”.
When I print the data to the console it prints the size (bytes) and its the same size as in the server so in some way I have the correct data, I just don't know how to view the pdf.
I am using swift 3, iOS 10, xcode 8.
First of all you may want to ask your question into two part. Please edit it and ask the second part again.
There are two parts in this topic
1. Downloading the PDF and save it in File System
2. Get the pdf that saved in File System and read it using UIWebView or UIDocumentInteractionController
So, I will explain for the first one.
The first one can be done if you use REST HTTP client : Alamofire : Elegant HTTP Networking in Swift. So no need to use URLSession for such case and you will have to write so many lines if you do. It's simple and easy. So, I want you to try it. If you need URLSession instead, leave comment.
So how to download pdf using Alamofire :
let destination: DownloadRequest.DownloadFileDestination = { _, _ in
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
//.documentDirectory means it will store in Application Document Folder
let fileURL = documentsURL.appendPathComponent("data.pdf")
return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
}
Alamofire.download(urlString, to: destination).response { response in
print(response)
if response.error == nil, let filePath = response.destinationURL?.path {
// do anything you want with filePath here.
// Here what you have to do Step 2. (Read the file that you downloaded)
}
}
This download procedure doesn't include requesting download link with encoded parameters. It was just simple way.
I have this code in a new playground
import Foundation
let blogsURL: NSURL = NSURL(fileURLWithPath: "/Users/Francis/Documents/Xcode_projects/KM registratie/blogs.json")
let data = NSData(contentsOfURL: blogsURL)
On the second line the playground tells me that it (correctly) initialised the URL referring to file:///Users/Francis/Documents/Xcode_projects/KM%20registratie/blogs.json
and on the third line the playground tells me that data is nil
I already googled around but no question seems to be the exact same problem. I found this "NSData contentsOfURL constructor returns nil", but neither restarting Xcode nor restarting my entire computer fixes the problem.
playgrounds are sandboxed and it seems that there isn't an easy way to reach outside their "box". XML parsing in swift the title of this question is a bit misleading, the answer on it does answer this question
It's answered here:
XML parsing in swift
The problem is that your URL isn't pointing where you think it is. You're trying to open a URL in a subdirectory in your sandbox, and it doesn't exist.
You'll need to open the package contents of your playground (right click on the playground and select "Show Package Contents", add a folder called "Resources", and copy your file directly there.
Then you can get the file from the main bundle:
let url: NSURL! = NSBundle.mainBundle().URLForResource("blogs", withExtension: "json")