Created
February 25, 2017 16:44
-
-
Save stulevine/c5fbfdc1fc048a690a0da785e1fba609 to your computer and use it in GitHub Desktop.
Swift 3 - Playground showing KVC with dictionary from Quizlet API call
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
//: Playground - noun: a place where people can play | |
import UIKit | |
import Foundation | |
import PlaygroundSupport | |
class IndexCardView: UIView { | |
let topSpacing: CGFloat = 80.0 | |
var lineColor = UIColor.clear | |
var lineWidth: CGFloat = 1.0 | |
var topLineColor = UIColor.clear | |
var topLineWidth: CGFloat = 2.0 | |
var withLines = true | |
var lineSpacing: CGFloat = 35.0 | |
init(frame: CGRect, | |
lineSpacing: CGFloat = 35.0, | |
withLines: Bool = true, | |
backgroundColor: UIColor = UIColor(red: 0.9999, green: 0.9956, blue: 0.9749, alpha: 1.0), | |
lineColor: UIColor = UIColor(red: 0.3964, green: 0.6393, blue: 0.9988, alpha: 0.5), | |
topLineColor:UIColor = UIColor(red: 0.8338, green: 0.3722, blue: 0.3937, alpha: 0.5)) { | |
super.init(frame: frame) | |
self.backgroundColor = backgroundColor | |
self.topLineColor = topLineColor | |
self.lineColor = lineColor | |
self.withLines = withLines | |
self.lineSpacing = lineSpacing | |
} | |
required init?(coder aDecoder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
override func draw(_ rect: CGRect) { | |
let context = UIGraphicsGetCurrentContext() | |
// top red line | |
context?.beginPath() | |
context?.setStrokeColor(topLineColor.cgColor) | |
context?.setLineWidth(topLineWidth) | |
context?.move(to: CGPoint(x: 0.0, y: topSpacing)) | |
context?.addLine(to: CGPoint(x: rect.width, y: topSpacing)) | |
context?.strokePath() | |
// add blue lines if we want them | |
if withLines { | |
let deltaY: CGFloat = lineSpacing; | |
let numberOfLines: Int = Int((rect.height - topSpacing) / deltaY) | |
context?.beginPath() | |
context?.setStrokeColor(lineColor.cgColor) | |
context?.setLineWidth(lineWidth) | |
for i in 1...numberOfLines { | |
let Y = CGFloat(i) * deltaY; | |
context?.move(to: CGPoint(x: 0.0, y: topSpacing + Y)) | |
context?.addLine(to: CGPoint(x: rect.width, y: topSpacing + Y)) | |
} | |
context?.strokePath() | |
} | |
} | |
} | |
/* Example of JSON Quizlet Set Object | |
{ | |
"id": 6009523, | |
"url": "http:\/\/quizlet.com\/6009523\/french-animals-30-flash-cards\/", | |
"title": "french animals 3.0", | |
"created_by": "catchdave", | |
"term_count": 13, | |
"created_date": 1310497102, | |
"modified_date": 1310497363, | |
"has_images": true, | |
"subjects": ["french", "animals"] | |
} | |
*/ | |
class TableVC: UITableViewController { | |
enum JSONError: String, Error { | |
case NoData = "ERROR: no data" | |
case ConversionFailed = "ERROR: conversion from JSON failed" | |
} | |
let windowFrame = CGRect(x: 0.0, y: 0.0, width: 375, height: 667) | |
//let data = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "tenty"] | |
var data = [QuizletSet]() | |
let baseURL = "https://api.quizlet.com/2.0" | |
// you need this to make a call to the Quizlet API | |
// It's easy to sign up at https://quizlet.com/ | |
let clientID = "client_id=<replace-with-your-quizlet-client-id>" | |
let searchSets = "/search/sets?per_page=25&q=" | |
let getSet = "/sets" | |
override init(style: UITableViewStyle) { | |
super.init(style: style) | |
view.frame = windowFrame | |
view.backgroundColor = UIColor ( red: 0.5006, green: 0.8424, blue: 0.9991, alpha: 0.592982297687861 ) | |
self.tableView.register(MyTableViewCell.self, forCellReuseIdentifier: "ri") | |
} | |
required init?(coder aDecoder: NSCoder) { | |
super.init(coder: aDecoder) | |
} | |
override func viewDidLoad() { | |
self.navigationItem.title = "Table Play" | |
searchQuizlet("algorithms") | |
} | |
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { | |
return data.count | |
} | |
override func numberOfSections(in tableView: UITableView) -> Int { | |
return 1 | |
} | |
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { | |
let cell = self.tableView.dequeueReusableCell(withIdentifier: "ri", for: indexPath) | |
cell.textLabel?.text = data[indexPath.row].title | |
cell.detailTextLabel?.text = String(indexPath.row) | |
return cell | |
} | |
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { | |
let cardVC = CardViewController(nibName: nil, bundle: nil) | |
cardVC.labelText = data[indexPath.row].url | |
cardVC.view | |
cardVC.qSet = data[indexPath.row] | |
self.navigationController?.pushViewController(cardVC, animated: true) | |
} | |
func searchQuizlet(_ searchText: String) { | |
let urlPath = baseURL + searchSets + searchText + "&\(clientID)" | |
print(urlPath) | |
guard let endpoint = URL(string: urlPath) else { | |
print("Error creating endpoint") | |
return | |
} | |
let request = URLRequest(url:endpoint) | |
let config = URLSessionConfiguration.default | |
let session = URLSession(configuration: config) | |
let dataTask = session.dataTask(with: request) { (data, response, error) in | |
do { | |
print("\(data)") | |
guard let data = data else { | |
throw JSONError.NoData | |
} | |
guard let json = try JSONSerialization.jsonObject(with: data, options: [.allowFragments]) as? NSDictionary else { | |
throw JSONError.ConversionFailed | |
} | |
print("\(json)") | |
var setData = [QuizletSet]() | |
var record: QuizletSet! | |
if let sets = json["sets"] as? [AnyObject] { | |
//print(json) | |
for qSet in sets { | |
if let setDict = qSet as? [String: AnyObject] { | |
record = QuizletSet(withJsonDict: setDict) | |
setData.append(record) | |
} | |
} | |
OperationQueue.main.addOperation { | |
self.data = setData | |
self.tableView.reloadData() | |
} | |
} | |
} | |
catch { | |
print("error: \(error.localizedDescription)") | |
} | |
} | |
dataTask.resume() | |
} | |
} | |
class QuizletSet: NSObject { | |
static let keyMap: [String: String] = ["id": "idNumber", | |
"url": "url", | |
"title": "title", | |
"created_by": "createdBy", | |
"term_count": "termCountNumber", | |
"created_date": "createdDate", | |
"modified_date": "modifiedDate", | |
"has_images": "hasImagesNumber", | |
"subjects": "subjects"] | |
var idNumber: NSNumber? | |
var id: Int? { | |
return idNumber?.intValue | |
} | |
var url: String? | |
var title: String? | |
var createdBy: String? | |
var termCountNumber: NSNumber? | |
var termCount: Int? { | |
return self.termCountNumber?.intValue | |
} | |
var createdDate: Date? | |
var modifiedDate: Date? | |
var hasImagesNumber: NSNumber = false | |
var hasImages: Bool { | |
return hasImagesNumber.boolValue | |
} | |
var subjects: [String]? | |
init(withJsonDict dict: [String: AnyObject?]) { | |
super.init() | |
for (key, value) in dict { | |
print("\(key) = \(value)") | |
if let mKey = QuizletSet.keyMap[key] { | |
if key.lowercased().contains("date") { | |
let date = Date(timeIntervalSince1970: Double(value as! Int)) | |
self.setValue(date, forKey: mKey) | |
} | |
else { | |
self.setValue(value as Any, forKey: mKey) | |
} | |
} | |
} | |
} | |
} | |
class CardViewController: UIViewController { | |
var labelText: String? | |
var label: UILabel? | |
var qSet: QuizletSet? | |
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { | |
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) | |
let frame = UIApplication.shared.keyWindow?.frame | |
self.view = IndexCardView(frame: frame!) | |
self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(tappedCancelButton)) | |
self.navigationItem.title = "A Card" | |
label = UILabel(frame: CGRect(x: 0, y: (self.view.frame.height-25)/2, width: self.view.frame.width, height: 50)) | |
label!.textColor = UIColor.black | |
label!.textAlignment = .center | |
label!.numberOfLines = 0 | |
self.view.addSubview(label!) | |
} | |
required init?(coder aDecoder: NSCoder) { | |
super.init(coder: aDecoder) | |
} | |
override func viewWillAppear(_ animated: Bool) { | |
super.viewWillAppear(animated) | |
label!.text = self.labelText | |
} | |
func tappedCancelButton(_ sender: UIBarButtonItem) { | |
self.navigationController?.popViewController(animated: true) | |
} | |
} | |
class MyTableViewCell: UITableViewCell { | |
required init?(coder aDecoder: NSCoder) { | |
super.init(coder: aDecoder) | |
} | |
override init(style: UITableViewCellStyle, reuseIdentifier: String?) { | |
super.init(style: .subtitle, reuseIdentifier: reuseIdentifier) | |
} | |
} | |
let vc = TableVC(style: .plain) | |
let navVC = UINavigationController(rootViewController: vc) | |
PlaygroundPage.current.liveView = navVC | |
PlaygroundPage.current.needsIndefiniteExecution |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment