Read a text file with NSURL in Swift - macos

I want to read and display the content of a text file that is located at an URL.
I am coding a Mac App for Yosemite and I need to use Swift but I stuck on this.
Here is my code:
let messageURL = NSURL(string: "http://localhost:8888/text.txt")
let sharedSession = NSURLSession.sharedSession()
let downloadTask: NSURLSessionDownloadTask = sharedSession.downloadTaskWithURL(messageURL!, completionHandler: { (location: NSURL!, response: NSURLResponse!, error: NSError!) -> Void in
var urlContents = NSString(contentsOfURL: location, encoding: NSUTF8StringEncoding, error: nil)
println((urlContents))
})
I tried to do it with NSString.stringWithContentsOfURL but it seems to be deprecated on OS X 10.10.
The text file located at on the server has only one line (UTF8).
Any clue? Thanks

Did you call downloadTask.resume()?
let messageURL = NSURL(string: "http://localhost:8888/text.txt")
let sharedSession = NSURLSession.sharedSession()
let downloadTask: NSURLSessionDownloadTask = sharedSession.downloadTaskWithURL(messageURL!,
completionHandler: {
(location: NSURL!, response: NSURLResponse!, error: NSError!) -> Void in
var urlContents = NSString(contentsOfURL: location, encoding: NSUTF8StringEncoding, error: nil)
println(urlContents)
})
downloadTask.resume() // Call it and you should be able to see the text.txt content

Related

I want to load image Using method of NSURLConnectionDelegate and NSURLConnectionDataDelegate

I want to load images into connectionDidFinishLoading method and the method func connection(_connection: NSURLConnection, didReceive: Data) is not getting called
class ImageDownload: UIImageView,NSURLConnectionDelegate,NSURLConnectionDataDelegate
{
var imageSaved:UIImage!
var imageDownloaded:UIImage!
var connection2:NSURLConnection = NSURLConnection()
var data: NSMutableData = NSMutableData()
var urlstring:String = ""
var fileURL:URL!
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) as NSArray
var pathPlist:String!
func downloadImage()
{
let imgdownload :String = "http://image.tmdb.org/t/p/w500" + urlstring
// let urlnew: NSURL = NSURL(string: imgdownload)!
//print(urlnew,"url")
let url: NSURL = NSURL(string: imgdownload)!
let request1: NSMutableURLRequest = NSMutableURLRequest(url: url as URL)
// let request2: NSMutableURLRequest = NSMutableURLRequest(url: urlnew as URL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 60.0)
connection2 = NSURLConnection(request: request1 as URLRequest, delegate: self, startImmediately: false)!
connection2.start()
}
func setURL(url:String) -> Void
{
print(url,"url")
urlstring = url
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
fileURL = documentsDirectory.appendingPathComponent(url)
print(fileURL,"fileurl")
if FileManager.default.fileExists(atPath: fileURL.path)
{
let image = UIImage(contentsOfFile: fileURL.path)
print("file exists")
self.image = image
}
else
{
downloadImage()
//let imgdownload :String = "http://image.tmdb.org/t/p/w500" + url
// let request = URL(string: imgdownload)
// let myUrl = NSURL(string: imgdownload)
//print("image loaded")
// self.image = self.imageSaved
}
}
func connection(_ connection: NSURLConnection, didReceive response: URLResponse)
{
print("in didReceive response\n")
self.data = NSMutableData()
}
func connection(_connection: NSURLConnection, didReceive: Data)
{
print("in didReceive data\n")
self.data.append(data as Data)
print(data,"image data is")
}
func connection(_ connection: NSURLConnection, didFailWithError error: Error)
{
print("connection error = \(error)")
}
func connectionDidFinishLoading(_ connection: NSURLConnection)
{
}
}*
I'm not familiar with the Swift syntax for NSURLConnection, so there's a nonzero chance I'm missing something subtle with the delegate method names, but off the top of my head, I see a couple of bigger problems:
Why are you using NSURLConnection in Swift? Every version of iOS that supports Swift also has NSURLSession. Just use the shared session, and your behavior will be almost identical to NSURLConnection.
You're using HTTP URLs. In all recent versions of iOS, you have to add special bits to your Info.plist if you want your app to be able to access HTTP URLs. I do not recommend doing that. Just use HTTPS.
You can get free TLS certs for HTTPS from Let's Encrypt. My guess is that as soon as you set that up and switch to an HTTPS URL, your problems will go away even with the existing code. But you should still be using NSURLSession.

Xcode Swift 3 NSURLSession.sharedSession

Im trying to update my basic weather app i made with swift 2 to swift 3 this is my code:
func getWeather(city: String) {
let path = "http://api.openweathermap.org/data/2.5/weather?q=London,uk&appid=095711373620570aa92ee530246dc8af"
let url = NSURL(string: path)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url!) { (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
print(">>>> \(data)")
}
and NSURLSession.sharedSession(5th line) and NSURLResponse(6th line) print out an error
Don't annotate types in the completion handler signature and use the Swift 3 native structures:
func getWeather(city: String) {
let path = "http://api.openweathermap.org/data/2.5/weather?q=London,uk&appid=095711373620570aa92ee530246dc8af"
let url = URL(string: path)
let session = URLSession.shared
let task = session.dataTask(with:url!) { (data, response, error) -> Void in
print(">>>> \(data)")
}
Swift 3 update
URLSession.shared.dataTask()

geocoder.geocodeAddressString no longer works with swift update today

https://developer.apple.com/library/prerelease/mac/releasenotes/General/APIDiffsMacOSX10_11/Swift/CoreLocation.html
shows that there were a couple of changes
func geocodeAddressString(_ addressString: String!, completionHandler completionHandler: CLGeocodeCompletionHandler!)
to:
func geocodeAddressString(_ addressString: String, completionHandler completionHandler: CLGeocodeCompletionHandler)
my code was:
var geocoder = CLGeocoder()
geocoder.geocodeAddressString("\(event!.street), \(event!.city), \(event!.country)", completionHandler: {(placemarks: [AnyObject]!, error: NSError!) -> Void in
if let placemark = placemarks?[0] as? CLPlacemark {
self.event!.lat = placemark.location!.coordinate.latitude
self.event!.long = placemark.location!.coordinate.longitude
self.event!.getMiles(self.currentLocation!.location!.coordinate.latitude, clong: self.currentLocation!.location!.coordinate.longitude)
var mile = self.event!.miles != nil ? NSString(format: "%.1f miles", self.event!.miles!) : "Location services off"
self.milesButton.setTitle(mile as String, forState: .Normal)
}
})
tried:
var geocoder = CLGeocoder()
let address = "\(event!.street), \(event!.city), \(event!.country)"
geocoder.geocodeAddressString(address, completionHandler: {(placemarks: [CLPlacemark]) in
let placemark = placemarks[0]
self.event!.lat = placemark.location!.coordinate.latitude
self.event!.long = placemark.location!.coordinate.longitude
self.event!.getMiles(self.currentLocation!.location!.coordinate.latitude, clong: self.currentLocation!.location!.coordinate.longitude)
var mile = self.event!.miles != nil ? NSString(format: "%.1f miles", self.event!.miles!) : "Location services off"
self.milesButton.setTitle(mile as String, forState: .Normal)
})
it just keeps saying that its not allowed. tried a few different combinations. this is do to the latest update to xcode / swift
thanks in advance
In Swift 2:
geocoder.geocodeAddressString(address, completionHandler: {(placemarks: [CLPlacemark]?, error: NSError?) -> Void in
})
In Swift 3, replace NSError? with Error?:
geocoder.geocodeAddressString(address, completionHandler: {(placemarks: [CLPlacemark]?, error: Error?) -> Void in
})
Or, easier, just let it infer the correct types for you:
geocoder.geocodeAddressString(address) { placemarks, error in
}
Use geocodeAddressString this way:
geocoder.geocodeAddressString(address, completionHandler: {(placemarks: [CLPlacemark]?, error: NSError?) -> Void in
})
And it will work fine.
geocoder.geocodeAddressString(address, completionHandler: {(placemarks: [CLPlacemark]?, error: NSError?) -> Void in
})
Just change NSError to Error and will it work
This no longer works....
geocoder.geocodeAddressString(address, completionHandler: {(placemarks: [CLPlacemark]?, error: NSError?) -> Void in
print("Test")
} as! CLGeocodeCompletionHandler)
throws an EXC error

Swift 2.0 NSURLConnection sendSynchronousRequest

I am using the code below to check for an internet connection. It was working correctly but after the Swift 2.0 update I now see an error on the line var data = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: nil) as NSData? saying extra argument 'error' in call.
class func isConnectedToNetwork()->Bool{
var Status:Bool = false
let url = NSURL(string: "http://google.com/")
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "HEAD"
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData
request.timeoutInterval = 10.0
var response: NSURLResponse?
var data = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: nil) as NSData?
if let httpResponse = response as? NSHTTPURLResponse {
if httpResponse.statusCode == 200 {
Status = true
}
}
return Status
}
Do you have any ideas what I should change it to?
Thanks
If you look at apples documentation (https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/#//apple_ref/occ/clm/NSURLConnection/sendSynchronousRequest:returningResponse:error:) you'll see that the definition changed to this:
class func sendSynchronousRequest(_ request: NSURLRequest,
returningResponse response: AutoreleasingUnsafeMutablePointer<NSURLResponse?>) throws -> NSData
They have removed the error parameter and the method throws now an ErrorType, if the request fails. So this should work:
do {
let data = try NSURLConnection.sendSynchronousRequest(request, returningResponse: &response)
} catch (let e) {
print(e)
}
However you shouldn't use this method: It's deprecated in favor of NSURLSession since iOS 9 and OS X 10.11.

Get data from HTTP Request - Swift

Today I'm trying to get some data from a webpage.
It keeps crashing saying "Exc Bad Access", any suggestion ?
class CodeViewController: NSObject {
#IBOutlet var output_box : NSTextField
#IBOutlet var url_textField : NSTextField
var output : NSString = "Unable to load data"
func downloadHTML (path: String) -> String {
var url = NSURL(string: "\(path)")
var request = NSURLRequest(URL: url)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {(response, data, error) in
self.output = NSString(data: data, encoding: NSUTF8StringEncoding)
//EXC_BAD_ACCESS when trying to set self.output new value
}
return output
}
#IBAction func retrive(sender: AnyObject!) {
println(downloadHTML(url_textField.stringValue))
}
}
I suspect that "url_textField.stringValue" is nil at the point that you pass it in. Trying it with a fixed string works. But note also that the function will return before the async request completes, and so your code will always print "Unable to load". If you add a line that assigns the output to your output_box in the completion handler, you will see the the text box update once the request completes...
The code I tried, which works, is...
class CodeViewController: NSObject {
var output : NSString = "Unable to load data"
func downloadHTML (path: String) -> String {
var url = NSURL(string: "\(path)")
var request = NSURLRequest(URL: url)
let completionBlock: (NSURLResponse!, NSData!, NSError!) -> Void = {response, data, error in
self.output = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Asynch completed \(self.output)")
}
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(), completionHandler: completionBlock)
return output
}
}
var c: CodeViewController? = nil
c = CodeViewController()
c!.downloadHTML("http://www.google.com")
println("Immediate \(c!.output)")
and its output is:
Immediate Unable to load data
Asynch completed <!doctype html><html ...

Resources