How do I handle "special" characters (like section) in NSString - swift

In the code below, I have removed all other processing in the block.
I am getting an error "fatal error: unexpectedly found nil while unwrapping an Optional value." The error occurs on the line
let webContent = NSString(data: urlContent, encoding: NSUTF8StringEncoding)!
I have determined that the problem is that there is a section symbol in the page. A hex dump of data shows an A7 (so It's not an html tag). If I remove the symbol from the page, the problem goes away. (Unfortunately, I don't have control of the 'live' pages)
How do I keep this error from happening?
let attemptedURL = NSURL(string: "http://www.ilnb.uscourts.gov/sites/all/ajax/calendar.php?mobile=true&judge=\(hearJudge)&start=\(hearDate)&print=true")
print(attemptedURL)
if let url = attemptedURL {
// Create a task to run the web content through
let task = NSURLSession.sharedSession().dataTaskWithURL(url) { (data, response, error) -> Void in
if let urlContent = data {
var contThis = true
let webContent = NSString(data: urlContent, encoding: NSUTF8StringEncoding)!
Thank you in advance.

Related

Initiating string with content of file (Swift)

Swift newbie here. I am trying load a text file into a string using the following code:
var uncondString: String
if let tempstring = try? String(contentsOf: url, encoding: .utf8) {
uncondString = tempstring
}
print("\(uncondString)")
The print statement, however, throws error "Variable 'uncondString' used before being initialized"
I guess this is trivial for more experienced users but any help is appreciated.
If the statement try? fails, it returns nil, and the if let statement is not executed when nil is returned
After all, this code is not a code that unconditionally succeeds in initialization, so a warning is displayed.
var uncondString: String
if let tempstring = try? String(contentsOf: url, encoding: .utf8) {
uncondString = tempstring
print(uncondString)
}
or
let uncondString: String? = try? String(contentsOf: url, encoding: .utf8)
if let uncondStr = uncondString {
print(uncondStr)
}

A few questions on NSURLSession (request data) in Swift 2

I have been following this tutorial to learn Swift and I have a few questions on the way they do things.
Specifically here:
let paramString = "data=Hello"
request.HTTPBody = paramString.dataUsingEncoding(NSUTF8StringEncoding)
let task = session.dataTaskWithRequest(request) {
(data, response, error) in
guard let _:NSData = data, let _:NSURLResponse = response where error == nil else {
print("Error")
return
}
let dataString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print(dataString)
}
Why is (data, response, error) in always used in NSURLSessions? What does this line of code mean? Also, why does he have a guard statement underneath?
The whole section of code is here:
func dataRequest() {
let urlToRequest: String = " http://www.kaleidosblog.com/tutorial/nsurlsession_tutorial.php"
let url: NSURL = NSURL(string: urlToRequest)!
let session = NSURLSession.sharedSession()
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData
let paramString = "data=Hello"
request.HTTPBody = paramString.dataUsingEncoding(NSUTF8StringEncoding)
let task = session.dataTaskWithRequest(request) {
(data, response, error) in
guard let _:NSData = data, let _:NSURLResponse = response where error == nil else {
print("Error")
return
}
let dataString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print(dataString)
}
task.resume()
}
With NSURLSession you make asynchronous calls, meaning that you make / start a network request and your program continues running - it doesn't stop waiting for response. Then, when your response is ready a completion block gets called / executed. So you need a way to access the data that's coming to you with this response. This data is accessible to you with (data, response, error) properties. This are just the names of those properties, so that you know how to use them. You could have different names, but it would be confusing to anyone else.
You use the guard statement because you can't be sure that you actually have the data or the response. It could be nil if an error occurred (timeout, ...). In such case (if there's an error) you just print "Error" to the console and call return, which makes you leave the completion block without executing the lines let dataString = NSString(data: data!, encoding: NSUTF8StringEncoding) and print(dataString). Of course, if you have the data and the response and error == nil you skip the else block of the guard statement and you just execute you last two lines of code in the block.

Blocking the main queue

I want flag to change as 'false' but it stays 'true'. How can I block my main queue ? Could you please explain with code ?
var flag = true;
var url = NSURL(string: "http://www.google.com")
var task = NSURLSession.sharedSession().dataTaskWithURL(url!){
(data,response,error) in
var urlContent = NSString(data: data, encoding: NSUTF8StringEncoding)
flag = false
}
task.resume()
println(flag)
If you want to make a synchronous request, one that blocks the current thread, you should just use NSURLConnection's sendSynchronousRequest:returningResponse:error: instead. There is no reason to create a download task if you want to block until it is done.
let request = NSURLRequest(URL: url!)
var response: NSURLResponse?
var error: NSError?
if let data = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: &error) {
let urlContent = NSString(data: data, encoding: NSUTF8StringEncoding)
}
else {
// handle error
}
However, blocking the main thread waiting for a network request is a really bad idea. The user will certainly notice the freeze in the app and be frustrated. I would strongly advise you to find a way of achieving this without having to block the main thread.

using Swift to get contents of URL using session.dataTaskWithRequest() - data doesn't convert to NSString

Why would my code below successfully return with data, with a statusCode of 200 but fail to convert the returned NSData to an NSString?
var session: NSURLSession
func init() {
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
session = NSURLSession(configuration: config)
}
func getStatic(url:NSURL) {
let request = NSMutableURLRequest(URL: url)
let dataTask = session.dataTaskWithRequest(request) {(data, response, error) in
if error != nil {
// handle error
} else {
// data has a length of 2523 - the contents at the url
if let httpRes = response as? NSHTTPURLResponse {
// httpRes is 200
let html = NSString(data:data, encoding:NSUTF8StringEncoding)
// **** html is nil ****
}
}
}
dataTask.resume()
}
The code is indeed correct.
The URL I was trying to load had non-UTF8 characters and so the encoding attempted by NSString(data:data, encoding:NSUTF8StringEncoding) failed.
Removing none UTF8 characters fixed the problem.
Or selecting an appropriate encoding, NSISOLatin1StringEncoding for my content, also worked.
It looks like it should be fine, to me at least. I'm just dabbling in Swift, but I've done my enclosures (not sure if thats the right name) slightly changed like below. Did you try converting data to NSString prior to your if let httpRes = response as? NSHTTPURLResponse line? Maybe the data variable doesn't actually have the html in it. I have code written almost exactly the same with the changes below that I'm able to successfully convert data to a NSString.
let dataTask = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
if error != nil {
// handle error
} else {
if let httpRes = response as? NSHTTPURLResponse {
let html = NSString(data:data, encoding:NSUTF8StringEncoding)
}
}
})
Hope it somehow helps.

Reading a short text file to a string in swift

I need to read the contents of a short text file in my Swift program. I did this:
var err: NSError?
let bundle = NSBundle.mainBundle()
let path = bundle.pathForResource("cards", ofType: "ini")
let content = String(contentsOfFile: path!, encoding: NSUTF8StringEncoding, error: nil)
My problem is that I can't use the error reporting. If I change that last line to this:
let content = String(contentsOfFile: path!, encoding: NSUTF8StringEncoding, error: err)
The compiler complains "Extra argument 'contentsOfFile' in call". That makes zero sense to me, maybe someone else can figure it out?
Following the new error handling introduced into iOS 9/Swift 2, a solution for this that works for me is:
let fileLocation = NSBundle.mainBundle().pathForResource("filename", ofType: "txt")!
let text : String
do
{
text = try String(contentsOfFile: fileLocation)
}
catch
{
text = ""
}
text will contain the file contents or be empty in the case of an error.
At a first glance I'd say that you have to pass the err variable by reference:
let content = String(contentsOfFile: path!, encoding: NSUTF8StringEncoding, error: &err)
I was able to resolve the error by using it in this way :
let content = String.stringWithContentsOfFile(path!, encoding: NSUTF8StringEncoding, error: nil)
or if wanted to use error reporting then
var err: NSError?
let content = String.stringWithContentsOfFile(path!, encoding: NSUTF8StringEncoding, error: &err)