//
// MainController.swift
// DRS
//
// Created by Mendenhall on 12/20/16.
// Copyright 2016 Mendenhall. All rights reserved.
//
import UIKit
import Alamofire
// Uncomment lines you would like to use
// If you use the commented value for device_model you MUST use only the slots in lines 25 - 40
let client_id = "YOUR_CLIENT_ID_HERE" //"amzn1.application-oa2-client.2be6672047d7412c8d5fb878d9c2cf48"
let client_secret = "YOUR_CLIENT_SECRET_HERE" //"5564a2ae7500e0674057325eb0ca916fb0998c8984aee83c1426bbe283489970"
let device_model = "YOUR_DEVICE_ID_HERE" //"6d8e5069-2150-45c1-8d33-60a1617b0b03"
let serial = "YOUR_DEVICE_SERIAL_HERE" //"abcd-abcd-abcd-abcd" // This can be anything just make something unique
let slots: [Slot] = [
// Your slots here with this format
// Slot(name: "SLOT_NAME", id: "SLOT_ID"),
Slot(name: "Batteries", id: "4cd07e7d-78fa-4916-9442-1b2476c8bd5a"),
Slot(name: "Cat Food", id: "a743fc5f-dceb-4d43-95e9-3190dc6e816d"),
Slot(name: "Deodorant", id: "10490a67-5d84-43fd-b040-81642455d290"),
Slot(name: "Dog Food", id: "f148029b-33ee-4cbf-a949-cbf78716b12d"),
Slot(name: "Jojoba Oil", id: "f68e8606-4539-4461-bf96-c56660af0aca"),
Slot(name: "Keurig K-Cups", id: "472be77f-8465-4615-85d4-625dad35e2ea"),
Slot(name: "Lemonade", id: "f271c470-d3de-4f85-8aae-7eb128118546"),
Slot(name: "Medicine", id: "0345968b-586e-4d57-a105-e312b6bf4859"),
Slot(name: "Paper Towels", id: "ab57ed15-a41e-4ee8-b935-dba5e234cbbe"),
Slot(name: "Pencils", id: "0ad28ac1-9e92-4c15-ba2a-a5a30a920c7d"),
Slot(name: "Popcorn", id: "a2181e64-aafb-4c45-a1b2-418ae34e4420"),
Slot(name: "Printer Paper", id: "fbabb6d2-6c74-47a9-b8ab-b6fde8c0dbd6"),
Slot(name: "Protein Bars", id: "5935d1f2-cd9a-4207-acda-f350fdc4f183"),
Slot(name: "Toilet Paper", id: "58aaeab3-366e-441a-9121-4fa7c55b206a"),
Slot(name: "Trash Bags", id: "adb1cc1a-6547-42c5-8b16-cc679c5623ea"),
Slot(name: "Water Bottles", id: "99f2ffce-982f-40a9-ad41-f366e3eca95b")
]
let theme_color = UIColor(red: 1, green: 0.6, blue: 0, alpha: 1)
class MainController: UIViewController, SlotViewDelegate {
@IBOutlet var navigation: UINavigationBar!
@IBOutlet var action_item: UIBarButtonItem!
@IBOutlet var helpitem: UIBarButtonItem!
@IBOutlet var scroll: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
let spacer = CALayer()
spacer.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: 20)
spacer.backgroundColor = navigation.barTintColor?.cgColor
self.view.layer.insertSublayer(spacer, at: 0)
let slot_space: CGFloat = 20
let slot_height: CGFloat = 116
let slot_width = self.view.frame.width - slot_space * 2
self.scroll.contentSize = CGSize(width: self.view.frame.width, height: 20 + CGFloat(slots.count) * (slot_height + slot_space))
for i in 0 ..< slots.count {
let slot = slots[i]
let slotview = Bundle.main.loadNibNamed("SlotView", owner: self, options: nil)?.first as! SlotView
slotview.frame = CGRect(x: slot_space, y: slot_space + CGFloat(i) * (slot_height + slot_space), width: slot_width, height: slot_height)
slotview.name.text = slot.name
slotview.number.text = "Slot #\(i + 1)"
slotview.index = i
slotview.delegate = self
self.scroll.addSubview(slotview)
}
let defs = UserDefaults.standard
if let acquired_time = defs.value(forKey: "token_time") {
let now = Date().timeIntervalSinceReferenceDate
let passed = now - (acquired_time as! TimeInterval)
print("Time passed since acquisition of tokens: \(passed)")
}
}
func selected(view: SlotView) {
let slot = slots[view.index]
let alert = UIAlertController(title: "\(slot.name)", message: "Do you want to refill this slot? An order will be placed for the item you have selected for this slot.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Refill", style: .default, handler: { (action) in
let defs = UserDefaults.standard
if let acquired_time = defs.value(forKey: "token_time") {
let now = Date().timeIntervalSinceReferenceDate
let passed = now - (acquired_time as! TimeInterval)
print("Time passed since acquisition of tokens: \(passed)")
if passed > 3600 {
print("Tokens are expired and need to be renewed!")
let refresh_token = defs.value(forKey: "refresh_token") as! String
Alamofire.request("https://api.amazon.com/auth/o2/token", method: .post, parameters: [
"grant_type": "refresh_token",
"refresh_token": refresh_token,
"client_id": client_id,
"client_secret": client_secret,
], encoding: URLEncoding.default, headers: [
"Content-Type": "application/x-www-form-urlencoded"
]).responseJSON(completionHandler: { (response) in
let json = response.result.value as! [String: Any]
print(json)
let access_token = json["access_token"] as! String
let refresh_token = json["refresh_token"] as! String
let defs = UserDefaults.standard
defs.set(access_token, forKey: "access_token")
defs.set(refresh_token, forKey: "refresh_token")
defs.set(Date().timeIntervalSinceReferenceDate, forKey: "token_time")
defs.synchronize()
print("Saved new tokens...")
self.refill(slot)
})
} else {
print("Tokens are valid!")
self.refill(slot)
}
} else {
print("No tokens have been saved.")
}
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
alert.view.tintColor = theme_color
}
@IBAction func help(_ sender: Any) {
site_state = .Help
self.performSegue(withIdentifier: "site", sender: self)
}
@IBAction func login(_ sender: Any) {
let alert = UIAlertController(title: "Actions", message: "You may register this app as a device linked to your Amazon account or change this device's settings.", preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "Login or Register", style: .default, handler: { (action) in
site_state = .Login
self.performSegue(withIdentifier: "site", sender: self)
}))
alert.addAction(UIAlertAction(title: "Manage Device Settings", style: .default, handler: { (action) in
UIApplication.shared.openURL(URL(string: "https://www.amazon.com/mn/dcw/myx.html#/home/devices/1")!)
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
let over = alert.popoverPresentationController
over?.barButtonItem = action_item
over?.permittedArrowDirections = .up
self.present(alert, animated: true, completion: nil)
alert.view.tintColor = theme_color
}
func refill(_ slot: Slot) {
print("Refilling slot: \(slot)")
let access_token = UserDefaults.standard.value(forKey: "access_token") as! String
Alamofire.request("https://dash-replenishment-service-na.amazon.com/replenish/\(slot.id)", method: .post, parameters: nil, encoding: URLEncoding.default, headers: [
"Authorization": "Bearer \(access_token)",
"x-amzn-accept-type": "com.amazon.dash.replenishment.DrsReplenishResult@1.0",
"x-amzn-type-version": "com.amazon.dash.replenishment.DrsReplenishInput@1.0"
]).responseJSON(completionHandler: { (response) in
let json = response.result.value as! [String: Any]
if let errmsg = json["message"] {
let smsg = errmsg as! String
let alert = UIAlertController(title: "Error!", message: smsg, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
alert.view.tintColor = theme_color
}
if let code = json["detailCode"] {
let scode = code as! String
var title = ""
var message = ""
if scode == "ORDER_INPROGRESS" {
title = "Alert"
message = "No order was placed because an order is already in progress. There is an order still out for delivery to you."
} else if scode == "TEST_ORDER_PLACED" {
title = "Success (TEST)"
message = "An order was successfully placed with the test flag. All notifications will proceed normally but you will not be charged and the item will not ship."
} else if scode == "STANDARD_ORDER_PLACED" {
title = "Success"
message = "An order was successfully placed and will be shipped to you."
}
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
alert.view.tintColor = theme_color
print(json)
}
})
}
}
struct Slot {
var name: String
var id: String
}
class NavigationBar: UINavigationBar {
override func draw(_ rect: CGRect) {
super.draw(rect)
let ctx = UIGraphicsGetCurrentContext()
ctx?.setStrokeColor(UIColor(white: 0.67, alpha: 1).cgColor)
ctx?.move(to: CGPoint(x: 0, y: self.frame.height))
ctx?.addLine(to: CGPoint(x: self.frame.width, y: self.frame.height))
ctx?.strokePath()
}
}
extension String {
func encodeURIComponent() -> String {
let set = NSMutableCharacterSet.alphanumeric()
set.addCharacters(in: "-_.!~*'()")
return (self.addingPercentEncoding(withAllowedCharacters: set as CharacterSet))!
}
}
Comments