I am just playing with the new error handling in version 2.0. And I now have the following functions with a throw:
func decodeHTML(HTML: String) throws {
guard let remove : String? = HTML.componentsSeparatedByString("<div id=\"loading\" style=\"display: none;\">")[0] else { throw DecodeError.MatchError }
guard var splitter : [String]? = remove!.componentsSeparatedByString("<div class=\"info\">") else { throw DecodeError.MatchError }
if splitter!.count > 0 { splitter!.removeFirst() }
if splitter!.count > 0 { splitter!.removeLast() }
if splitter!.count > 0 {
for HTMLmessage in splitter! {
guard var splitter2 : [String]? = HTMLmessage.componentsSeparatedByString("</td><td>Besked fra ") else { throw DecodeError.MatchError }
guard let author : String? = (splitter2![1].componentsSeparatedByString("</tr>"))[0] else { throw DecodeError.MatchError }
guard let date : String? = (splitter2![0].componentsSeparatedByString("<td width=\"25%\">"))[1] else { throw DecodeError.MatchError }
guard let title : String? = HTMLmessage.componentsSeparatedByString("\"><b>")[1].componentsSeparatedByString("</b></a></td></tr>")[0] else { throw DecodeError.MatchError }
guard var string : String? = HTMLmessage.componentsSeparatedByString("</a></td></tr><tr><td colspan=2>")[1].componentsSeparatedByString("</td></tr></table></div>")[0] else { throw DecodeError.MatchError }
string = string!.stringByReplacingOccurrencesOfString("</p><p>", withString: "\n")
string = string!.stringByReplacingOccurrencesOfString("<[^>]+>", withString: "", options: .RegularExpressionSearch, range: nil)
self.messages.append(message(author, date, title, string))
}
} else {
throw DecodeError.MatchError
}
}
But I wonder, do I really have to guard everytime something can go wrong? Is there an easier way to throw an error if one of the lines fails?
I cleaned up your function a bit:
extension String {
func split(string: String) -> [String] { return componentsSeparatedByString(string) }
}
extension Array {
var second : Element? { return dropFirst().first }
}
func decodeHTML(HTML: String) throws {
guard let
splitter = HTML
.split("<div id=\"loading\" style=\"display: none;\">").first?
.split("<div class=\"info\">").dropFirst().dropLast()
where !splitter.isEmpty else {
throw DecodeError.MatchError
}
for HTMLmessage in splitter {
let splitter2 = HTMLmessage.split("</td><td>Besked fra ")
guard let
author = splitter2.second?
.split("</tr>").first,
date = splitter2.first?
.split("<td width=\"25%\">").second,
title = HTMLmessage
.split("\"><b>").second?
.split("</b></a></td></tr>").first,
string = HTMLmessage
.split("</a></td></tr><tr><td colspan=2>").second?
.split("</td></tr></table></div>").first?
.stringByReplacingOccurrencesOfString("</p><p>", withString: "\n")
.stringByReplacingOccurrencesOfString("<[^>]+>", withString: "", options: .RegularExpressionSearch, range: nil)
else {
throw DecodeError.MatchError
}
let message = (author, date, title, string)
}
}
You can use dropFirst, dropLast and first to get access to elements safely. You should probably really use a HTML parsing library though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With