Last active
February 3, 2018 22:59
-
-
Save rnapier/8afbf9d549180423919f to your computer and use it in GitHub Desktop.
Yeah, @krzyzanowskim is probably right. What problem were we solving?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
// All the complexity needed to avoid this code probably isn't worth it in the majority of cases. | |
// Particularly note that the data model doesn't 100% line up with the JSON (some keys have | |
// slightly different names for instance). A system flexible enough to handle that (say, something | |
// like Go's json.Marshal) would be nice, but this code, while slightly tedious, isn't really bad. | |
// Basically I'm saying that a richer JSON<->Swift system built into stdlib would be nice, but the | |
// bar is pretty high to go pulling in a helper library. | |
// | |
// That said, compare the Go code below, and I think it really is much simpler, and scales much better | |
// to non-trivial cases. So something like this in Swift stdlib would I think have a lot of value. | |
typealias JSONObject = [String:AnyObject] | |
enum Error: ErrorType { | |
case InvalidJSON(AnyObject) | |
} | |
struct Revision { | |
let contentFormat: String | |
let contentModel: String | |
let content: String | |
} | |
extension Revision { | |
init(json: JSONObject) throws { | |
guard | |
let contentFormat = json["contentformat"] as? String, | |
let contentModel = json["contentmodel"] as? String, | |
let content = json["*"] as? String | |
else { throw Error.InvalidJSON(json) } | |
self.init( | |
contentFormat: contentFormat, | |
contentModel: contentModel, | |
content: content) | |
} | |
} | |
struct Page { | |
let pageid: Int | |
let ns: Int | |
let title: String | |
let revisions: [Revision] | |
} | |
extension Page { | |
init(json: JSONObject) throws { | |
guard | |
let pageid = json["pageid"] as? Int, | |
let ns = json["ns"] as? Int, | |
let title = json["title"] as? String, | |
let revisions = json["revisions"] as? [JSONObject] | |
else { throw Error.InvalidJSON(json) } | |
self.init( | |
pageid: pageid, | |
ns: ns, | |
title: title, | |
revisions: try revisions.map(Revision.init) | |
) | |
} | |
} | |
func parse(json: AnyObject) throws -> [Page] { | |
guard | |
let dict = json as? JSONObject, | |
let query = dict["query"] as? JSONObject, | |
let pages = query["pages"] as? [String: JSONObject] | |
else { throw Error.InvalidJSON(json) } | |
return try pages.values.map(Page.init) | |
} | |
func searchURLForString(text: String) -> NSURL { | |
let encodedText = text.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())! | |
return NSURL(string: "https://en.wikipedia.org/w/api.php?action=query&prop=revisions&rvprop=content&format=json&titles=\(encodedText)")! | |
} | |
let searchString = "Main Page" | |
let url = searchURLForString(searchString) | |
let req = NSURLRequest(URL: searchURLForString(searchString)) | |
let data = NSData(contentsOfURL: url)! | |
let json = try NSJSONSerialization.JSONObjectWithData(data, options: []) | |
print(try parse(json)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// That said, here it is in Go, and it really is much simpler (if not actually much shorter) | |
package main | |
import ( | |
"net/url" | |
"net/http" | |
"log" | |
"encoding/json" | |
"io" | |
"fmt" | |
) | |
type Revision struct { | |
ContentFormat string `json:"contentformat"` | |
ContentModel string `json:"contentmodel"` | |
Content string `json:"*"` | |
} | |
type Page struct { | |
PageID int `json:"pageid"` | |
NS int `json:"ns"` | |
Title string `json:"title"` | |
Revisions []Revision `json:"revisions"` | |
} | |
type query struct { | |
Pages map[string]Page `json:"pages"` | |
} | |
type message struct { | |
Query query `json:"query"` | |
} | |
func searchURLForString(text string) string { | |
encodedText := url.QueryEscape(text) | |
return "https://en.wikipedia.org/w/api.php?action=query&prop=revisions&rvprop=content&format=json&titles=" + encodedText | |
} | |
func main() { | |
searchString := "Main Page" | |
url := searchURLForString(searchString) | |
resp, err := http.Get(url) | |
if err != nil { | |
log.Fatal(err) | |
} | |
defer resp.Body.Close() | |
dec := json.NewDecoder(resp.Body) | |
var m message | |
if err := dec.Decode(&m); err != nil { | |
log.Fatal(err) | |
} | |
for _, page := range m.Query.Pages { | |
fmt.Printf("%#v\n", page) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment