Upload
others
View
3
Download
0
Embed Size (px)
Citation preview
CommunicationsMobile Application Development in iOS
School of EECS
Washington State University
Instructor: Larry Holder
Mobile Application Development in iOS 1
Outline• Already seen– Cloud Kit, Remote notifications, Placemarks via
Geocoder
• Safari Services and Web Kit
• HTTP requests
• APIs
• Other communications services
Mobile Application Development in iOS 2
Safari Services
• Full browser functionality within app
• Import SafariServices
• Create URL
• Create SFSafariViewController (URL)
• Execute present (ViewController)
Mobile Application Development in iOS 3
Safari Services
Mobile Application Development in iOS 4
import SafariServices
class ViewController: UIViewController {
let urlString = "http://www.eecs.wsu.edu/~holder/courses/MAD/"
@IBAction func safariTapped(_ sender: UIButton) {let url = URL(string: urlString)let safariVC = SFSafariViewController(url: url!)present(safariVC, animated: true, completion: nil)
}}
WebKit• Import WebKit
• WKWebView vs. UIWebView
– UIWebView deprecated; only choice before iOS 8
– WKWebView only programmatically for iOS 8-10
• Storyboard version works for iOS 11+
– Use WKWebView
Mobile Application Development in iOS 5
Web Security• App Transport Security
– Only HTTPS by default
• App Transport Security Settings
– Allow Arbitrary Loads
– Exception Domains• Dictionary for each domain
– NSIncludesSubdomains
– NSExceptionAllowsInsecureHTTPLoads
Mobile Application Development in iOS 6
Web Kit View
Mobile Application Development in iOS 7
import WebKit
class ViewController: UIViewController {
let urlString = "http://www.eecs.wsu.edu/~holder/courses/MAD/"
@IBOutlet weak var webView: WKWebView!
func loadWebView() {let url = URL(string: urlString)let request = URLRequest(url: url!)webView.load(request)
}}
HTTP Requests
• Create data task for URLSession.shared instance
– URLSession.shared.dataTask(with: URL) // calls delegates
– URLSession.shared.dataTask(with: URLRequest) // calls delegates
– URLSession.shared.dataTask(with: URL, completionHandler:
@escaping (Data?, URLResponse?, Error?) -> Void)
– URLSession.shared.dataTask(with: URLRequest, completionHandler:
@escaping (Data?, URLResponse?, Error?) -> Void)
• Call resume() on data task
Mobile Application Development in iOS 8
HTTP Requests• Delegates– URLSessionDelegate
– URLSessionTaskDelegate
– URLSessionDataDelegate
– URLSessionDownloadDelegate
– URLSessionStreamDelegate
• Methods– didReceive, didFinish, …
Mobile Application Development in iOS 9
HTTP Requests
Mobile Application Development in iOS 10
func getDateFromServer() {let url = URL(string: "http://www.eecs.wsu.edu/~holder/tmp/date.php")let dataTask = URLSession.shared.dataTask(with: url!,
completionHandler: handleResponse)dataTask.resume()
}
HTTP Requests
Mobile Application Development in iOS 11
func handleResponse (data: Data?, response: URLResponse?, error: Error?) {if let err = error {
print("error: \(err.localizedDescription)")} else {
let httpResponse = response as! HTTPURLResponselet statusCode = httpResponse.statusCodeif statusCode != 200 {
let msg = HTTPURLResponse.localizedString(forStatusCode:statusCode)
print("HTTP \(statusCode) error: \(msg)")} else {
// response okay, do something with datalet dataStr = String(data: data!, encoding: .utf8)print("data = \(dataStr!)")
}}
}
HTTP Requests: Server Side
Mobile Application Development in iOS 12
<?php
// date.php – return current date and local time in JSON format
date_default_timezone_set("America/Los_Angeles");$myDate = date("Y-m-d");$myTime = date("H:i:s");$json = '{"date":"' . $myDate . '","time":"' . $myTime . '"}';print $json;
?>
Handling JSON Responses• If JSON data, then use JSONSerialization
Mobile Application Development in iOS 13
func handleResponse (data: Data?, response: URLResponse?, error: Error?) {...// response okay, do something with dataif let jsonObj = try? JSONSerialization.jsonObject(with: data!) {
let jsonDict = jsonObj as! [String: Any]let dateStr = jsonDict["date"] as! Stringlet timeStr = jsonDict["time"] as! Stringprint("\(dateStr) \(timeStr)")
} else {print("error: invalid JSON data")
}}
Better error handling?
Handling Responses• If need to change view, dispatch to main thread
Mobile Application Development in iOS 14
func handleResponse (data: Data?, response: URLResponse?, error: Error?) {...DispatchQueue.main.async {
self.dateLabel.text = "\(dateStr) \(timeStr)"}
}
HTTP POST Requests
Mobile Application Development in iOS 15
func checkLogin(_ username: String, _ password: String) {let jsonDict: [String: Any] = ["username": username, "password": password]let jsonData = try! JSONSerialization.data(withJSONObject: jsonDict)let url = URL(string: "https://www.eecs.wsu.edu/~holder/tmp/login.php")var request = URLRequest(url: url!)request.httpMethod = "POST"request.httpBody = jsonData!request.setValue("application/json", forHTTPHeaderField: "Content-Type")let dataTask = URLSession.shared.dataTask(with: request,
completionHandler: handleLoginResponse)dataTask.resume()
}
Note: Some websites redirect requests to alternate servers and POST data may not be delivered.
HTTP POST Requests: Server Side
Mobile Application Development in iOS 16
<?php// login - Return user ID for given username and password.
$json = file_get_contents('php://input');$obj = json_decode($json);$username = $obj->username;$password = $obj->password;$users = array ( array("Mario", "peach", 1), array("Bowser", "junior", 2),
array("Yoshi", "dragon", 3) );$userId = 0;for ($userIndex = 0; $userIndex < count($users); $userIndex++) {
if (($users[$userIndex][0] == $username) and($users[$userIndex][1] == $password)) {$userId = $users[$userIndex][2];break;
}}$response = array();$response["userid"] = strval($userId);print json_encode($response);?>
HTTP POST Requests:Handling Response
Mobile Application Development in iOS 17
func handleLoginResponse (data: Data?, response: URLResponse?, error: Error?) {if let err = error {
print("error: \(err.localizedDescription)")} else {
let httpResponse = response as! HTTPURLResponselet statusCode = httpResponse.statusCodeif statusCode != 200 {
let msg = HTTPURLResponse.localizedString(forStatusCode: statusCode)print("HTTP \(statusCode) error: \(msg)")
} else {// Process JSON response (no error handling; yikes!)let jsonObj = try! JSONSerialization.jsonObject(with: data!)let jsonDict = jsonObj as! [String: Any]let userId = jsonDict["userid"] as! Stringprint("userid = \(userId)")
}}
}
Application Programming Interfaces (APIs)
• News
– newsapi.org
• Weather
– www.wunderground.com/weather/api
• And many more (20,000+)
– www.programmableweb.com
Mobile Application Development in iOS 18
API Requests
Mobile Application Development in iOS 19
func getNews() {let url = URL(string:
"https://newsapi.org/v1/articles?source=the-verge&apiKey=\(newsAPIKey)")let dataTask = URLSession.shared.dataTask(with: url!,
completionHandler: handleNewsResponse)dataTask.resume()
}
Handle API Responses
Mobile Application Development in iOS 20
func handleNewsResponse (data: Data?, response: URLResponse?, error: Error?) {...let jsonObj = try! JSONSerialization.jsonObject(with: data!)let jsonDict1 = jsonObj as! [String: AnyObject]let articleArray = jsonDict1["articles"] as! [AnyObject]let jsonDict2 = articleArray[0] as! [String: AnyObject]let titleStr = jsonDict2["title"] as! Stringlet urlToImage = jsonDict2["urlToImage"] as! Stringself.loadNewsImage(urlToImage)DispatchQueue.main.async {
self.newsTitleLabel.text = titleStr}
}func loadNewsImage(_ urlString: String) {
let url = URL(string: urlString)let dataTask = URLSession.shared.dataTask(with: url!,
completionHandler: {(data, response, error) -> Void inlet image = UIImage(data: data!)DispatchQueue.main.async {
self.newsImageView.image = image}
})dataTask.resume()
}
Other Communications Services
• Network Services
– WiFi, Bluetooth
• GameKit
– Peer-to-peer for multi-player and voice
• Sockets
Mobile Application Development in iOS 21
Resources
• Safari Services
– developer.apple.com/documentation/safariservices
• Web Kit
– developer.apple.com/documentation/webkit
• URLSession
– developer.apple.com/documentation/foundation/urlsession
Mobile Application Development in iOS 22