This code is an implementation reference for using the Graph API on Swift native. It follows the two steps illustrated in the "Using Graph" page. The code demonstrates how to make a request in Swift and display the resulting component using WKWebView.
import UIKit
//function to get a token
func getToken(_ completion: @escaping (_ success: Bool, _ data: String?) -> Void) {
var urlComponents = URLComponents(string: "https://api-staging.tryterra.co/graphs/token")!
urlComponents.queryItems = [
URLQueryItem(name: "user_id", value: "Your user_id"),
]
let url = urlComponents.url
var request = URLRequest(url: url!)
request.httpMethod = "GET"
request.allHTTPHeaderFields = [
"dev-id": "Your dev-id",
"x-api-key": "Your x-api-key"
]
let task = URLSession.shared.dataTask(with: request as URLRequest) { data, response, error in
if let data = data {
//Because the return message is {“token”: …”} parsing the actual token.
//Ideally this should be done in backend to secure your API key.
let outputTemp = String(data: data, encoding: String.Encoding.utf8) as String?
let outputTemp2 = String((outputTemp?.dropFirst(14))!)
let outputStr = String((outputTemp2.dropLast(4)))
completion(true, outputStr)
} else if let error = error {
print("HTTP Request Failed \(error)")
completion(false, nil)
}
}
task.resume()
}
//function to get html component
func fetchData(graphType: String,
charttype: String = "line",
timeperiod: String,
start_date: String,
y_min: String = "0",
y_max: String = "200",
_ completion: @escaping (_ success: Bool, _ data: String?) -> Void) {
getToken{ successtoken, dataToken in
var urlComponents = URLComponents(string: "https://api-staging.tryterra.co/graphs/render")!
urlComponents.queryItems = [
URLQueryItem(name: "type", value: graphType),
URLQueryItem(name: "charttype", value: charttype),
URLQueryItem(name: "timepperiod", value: timeperiod),
URLQueryItem(name: "start_date", value: start_date),
URLQueryItem(name: "token", value: dataToken),
URLQueryItem(name: "y_min", value: y_min),
URLQueryItem(name: "y_max", value: y_max)
]
let url = urlComponents.url
var request = URLRequest(url: url!)
request.httpMethod = "GET"
request.allHTTPHeaderFields = [
"dev-id": "Your dev-id",
]
let task = URLSession.shared.dataTask(with: request as URLRequest) { data, response, error in
if let data = data {
let outputStr = String(data: data, encoding: String.Encoding.utf8) as String?
completion(true, outputStr)
} else if let error = error {
print("HTTP Request Failed \(error)")
completion(false, nil)
}
}
task.resume()
}
}
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
var webView: WKWebView!
override func loadView() {
webView = WKWebView()
webView.navigationDelegate = self
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
fetchData(graphType: "SLEEP_REM_SUMMARY", timeperiod: "TWO_WEEK", start_date:"2023-03-11") { success, data in
if success {
self.webView.loadHTMLString(data!, baseURL: nil)
} else {
print("Network request failed")
}
}
}
}
Modified ViewController for receiving data currently selected by user from JavaScript inside webView component using WKScriptMessageHandler.
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate, WKScriptMessageHandler {
var webView: WKWebView!
override func loadView() {
webView = WKWebView()
webView.navigationDelegate = self
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
// Create content controller to recieve from webView, name should be "observer"
let contentController = self.webView.configuration.userContentController
contentController.add(self, name: "observer")
fetchData(graphType: "SLEEP_REM_SUMMARY", timeperiod: "WEEK", start_date:"2023-03-21") { success, data in
if success {
self.webView.loadHTMLString(data!, baseURL: nil)
} else {
print("Network request failed")
}
}
}
// Function for handling data recieved from javaScript inside webView
//Data sent by javaScrip is the value of the graph at the point selected by the user
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
let msg = message.body
print(msg)
}
}
Below is an example showing two copies of the above ViewController displaying different graphs.