Top Banner
39

RESTing with the new Yandex.Disk API, Clemens Аuer

Jan 15, 2015

Download

Technology

Yandex

A first-hand report on experiences writing a Swift SDK on top of Yandex.Disk’s REST API. The presentation will begin with a short introduction to the Yandex.Disk service, including a comparison of the various APIs and SDKs available for integrating third-party products with Yandex.Disk, and then move on to focus on the necessary steps taken, and the experiences gathered while implementing a REST API-based SDK in Swift.
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: RESTing with the new Yandex.Disk API, Clemens Аuer
Page 2: RESTing with the new Yandex.Disk API, Clemens Аuer

Clemens Auer

REST ing with the new Yandex.Disk API

Developer

Page 3: RESTing with the new Yandex.Disk API, Clemens Аuer

What Is Yandex Disk?

Page 4: RESTing with the new Yandex.Disk API, Clemens Аuer

- 26 Million registered Disk users.

- 6 Billion files.

- 14 Million files added per day.

What Is Yandex Disk?

Page 5: RESTing with the new Yandex.Disk API, Clemens Аuer

How much storage space users get for free?

- Basic: 10 GB.

- Invites: up to 10 GB.

- Partner offers: currently up to 50 GB.

What Is Yandex Disk?

Page 6: RESTing with the new Yandex.Disk API, Clemens Аuer

For those who need more:

What Is Yandex Disk?

Storage 10 GB 100 GB 1 TB

per month 30 RUB 150 RUB 900 RUB

per year 300 RUB 1500 RUB 9000 RUB

Page 7: RESTing with the new Yandex.Disk API, Clemens Аuer

Clients

- Web: disk.yandex.ru, widgets.

- Desktop: Windows, Mac, Linux

- Mobile: iOS, Android, WinPhone

- 3rd party

What Is Yandex Disk?

Page 8: RESTing with the new Yandex.Disk API, Clemens Аuer

3rd party clients.

- Official SDKs (JAVA, Obj-C, C#)

- WebDAV + extensions

- REST API

What Is Yandex Disk?

Page 9: RESTing with the new Yandex.Disk API, Clemens Аuer

WebDAV vs. REST API

Page 10: RESTing with the new Yandex.Disk API, Clemens Аuer

WebDAV vs. REST API

WebDAV RESTUpload ✓ ✓

Download ✓ ✓Create Folder ✓ ✓

Copy ✓ ✓Move ✓ ✓Delete ✓ ✓

List ✓ ✓

Page 11: RESTing with the new Yandex.Disk API, Clemens Аuer

Support for public files

WebDAV vs. REST API

WebDAV RESTShare ✓ ✓

Unshare ✓ ✓List Metadata ✗ ✓

Download ✗ ✓Save to Disk ✗ ✓

Page 12: RESTing with the new Yandex.Disk API, Clemens Аuer

Working with the trash

WebDAV vs. REST API

WebDAV RESTList ✗ ✓

Delete ✗ ✓Restore ✗ ✓

Page 13: RESTing with the new Yandex.Disk API, Clemens Аuer

What is missing?

WebDAV vs. REST API

WebDAV RESTBasic Auth ✓ ✗

Free/Used Space ✓ ✗*Hash Upload ✓ ✗

Custom Props ✓ ✗

Userinfo ✓ ✗

Page 14: RESTing with the new Yandex.Disk API, Clemens Аuer

- Register application

- Register dev accounts

- Get token for development

- Полигон

- Code

Getting Started

Page 15: RESTing with the new Yandex.Disk API, Clemens Аuer

Register application

Page 16: RESTing with the new Yandex.Disk API, Clemens Аuer

Register application

Page 17: RESTing with the new Yandex.Disk API, Clemens Аuer

Register application

Page 18: RESTing with the new Yandex.Disk API, Clemens Аuer

Register application

Page 19: RESTing with the new Yandex.Disk API, Clemens Аuer

Register application

Page 20: RESTing with the new Yandex.Disk API, Clemens Аuer

Register dev accounts.

Page 21: RESTing with the new Yandex.Disk API, Clemens Аuer

Get token for development

https://oauth.yandex.ru/authorize?response_type=token&client_id=

Page 22: RESTing with the new Yandex.Disk API, Clemens Аuer

Get token for development

https://oauth.yandex.ru/verification_code?dev=True# access_token=d8edc4f3a698473fbc87634c41b2ca81 &token_type=bearer &state= &expires_in=31536000

Page 23: RESTing with the new Yandex.Disk API, Clemens Аuer

Полигон

Page 24: RESTing with the new Yandex.Disk API, Clemens Аuer

- Register application

- Register dev accounts

- Get token for development

- Полигон

- Code

Getting Started

Page 25: RESTing with the new Yandex.Disk API, Clemens Аuer

import Foundation !public class Disk { … } !let disk = Disk(token: "d8edc4f3a698473fbc87634c41b2ca81") var fileURL : NSURL !disk.uploadURL(fileURL, toPath: fileURL.lastPathComponent, overwrite: true) { // handle errors } !disk.deletePath(fileURL.lastPathComponent, permanently: false) { // handle response }

Code example

What we try to achieve:

Page 26: RESTing with the new Yandex.Disk API, Clemens Аuer

public class Disk { public let token : String public let baseURL = "https://cloud-api.yandex.net:443" ! var additionalHTTPHeaders : [String:String] { return [ "Accept" : "application/json", "Authorization" : "OAuth \(token)", "User-Agent" : "Mobile Camp Demo" ] } }

Code example

Basic properties in Disk class

Page 27: RESTing with the new Yandex.Disk API, Clemens Аuer

public class Disk { public let token : String public let baseURL = "https://cloud-api.yandex.net:443" ! var additionalHTTPHeaders : [String:String] { return [ "Accept" : "application/json", "Authorization" : "OAuth \(token)", "User-Agent" : "Mobile Camp Demo" ] } ! public lazy var session : NSURLSession = { let config = NSURLSessionConfiguration.defaultSessionConfiguration() config.HTTPAdditionalHeaders = self.additionalHTTPHeaders ! return NSURLSession(configuration: config) }() ! public init(token:String) { self.token = token } }

Code example

Complete basic Disk class

Page 28: RESTing with the new Yandex.Disk API, Clemens Аuer

extension Disk { class func JSONDictionaryWithData(data:NSData!, onError:(NSError!)->Void) -> NSDictionary? { ! var error: NSError? let root = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &error) as? NSDictionary ! if root == nil { onError(NSError(…)) return nil } ! return root } }

Code example

Disk extension for de-serializing JSON data

Page 29: RESTing with the new Yandex.Disk API, Clemens Аuer

extension NSURLSession { func jsonTaskWithMethod(method:String, url: NSURL!, onError: ((NSError!) -> Void)!, onCompletion: ((NSDictionary, NSHTTPURLResponse) -> Void)!) -> NSURLSessionDataTask! { ! let request = NSMutableURLRequest(URL: url) request.HTTPMethod = method ! return dataTaskWithRequest(request) { (data, response, error) -> Void in ! let jsonRoot = Disk.JSONDictionaryWithData(data, onError: onError) ! if let jsonRoot = jsonRoot { switch response.statusCode { case 400...599: return onError(…) default: return onCompletion(jsonRoot, response) } } else { return // handler already called from JSONDictionaryWithData } } } }

Code example

NSURLSessing extension for doing JSON requests

Page 30: RESTing with the new Yandex.Disk API, Clemens Аuer

Take a peek at the documentation

Page 31: RESTing with the new Yandex.Disk API, Clemens Аuer

extension Disk { class func hrefMethodTemplatedWithDictionary(dict:NSDictionary?) -> (href:String, method:String, templated:Bool) { var href = "" var method = "" var templated = false ! if let json = dict { if let str = json["href"] as? String { href = str } if let str = json["method"] as? String { method = str } if let nr = json["templated"] as? NSNumber { templated = nr.boolValue } } ! return (href, method, templated) } }

Code example

Disk extension for processing common JSON object

Page 32: RESTing with the new Yandex.Disk API, Clemens Аuer

extension Disk { public func uploadURL(fileURL:NSURL, toPath path:String, overwrite:Bool?, handler:(NSError!) -> Void) -> Void { ! var url = "\(baseURL)/v1/disk/resources/upload?path=\(path.urlEncoded())" ! if let overwrite = overwrite { url += "&overwrite=\(overwrite)" } let error = { handler($0) } ! session.jsonTaskWithMethod("GET", url: NSURL(string: url), onError: error) { (jsonRoot, response)->Void in ! let (href, method, templated) = Disk.hrefMethodTemplatedWithDictionary(jsonRoot) ! let request = NSMutableURLRequest(URL: NSURL(string: href)) request.HTTPMethod = method ! self.session.uploadTaskWithRequest(request, fromFile: fileURL) { (data, response, trasferError)->Void in ! return error(trasferError) }.resume() }.resume() } }

Code example

Disk extension implementing file upload

Page 33: RESTing with the new Yandex.Disk API, Clemens Аuer

Take another peek at the documentation

Page 34: RESTing with the new Yandex.Disk API, Clemens Аuer

public enum DeletionResult { case Done case InProcess(href:String, method:String, templated:Bool) case Failed(NSError!) } !extension Disk { public func deletePath(path:String, permanently:Bool?, handler:(result:DeletionResult) -> Void) -> Void { var url = "\(baseURL)/v1/disk/resources?path=\(path.urlEncoded())" ! if let permanently = permanently { url += "&permanently=\(permanently)" } let error = { handler(result: .Failed($0)) } ! session.jsonTaskWithMethod("DELETE", url: NSURL(string: url), onError: error) { (jsonRoot, response)->Void in switch response.statusCode { case 202: return handler(result: .InProcess(Disk.hrefMethodTemplatedWithDictionary(jsonRoot))) case 204: return handler(result: .Done) default: return error(NSError(…)) } }.resume() } }

Code example

Disk extension implementing delete.

Page 35: RESTing with the new Yandex.Disk API, Clemens Аuer

Swift

- enum, switch, closures, tuples

- Type safety vs. Obj-C weak typing

- Volatile: Xcode release notes.

- Apple Dev Forums

Lessons Learned

Page 36: RESTing with the new Yandex.Disk API, Clemens Аuer

REST API

- Documentation vs. Полигон

- Fast

- OAuth

- Roadmap ahead

Lessons Learned

Page 37: RESTing with the new Yandex.Disk API, Clemens Аuer

In general

- Test driven development saves time.

- Autotest the API version

- Report bugs

http://feedback2.yandex.ru/disk/api/

Lessons Learned

Page 38: RESTing with the new Yandex.Disk API, Clemens Аuer

https://oauth.yandex.ru

https://oauth.yandex.ru/client/new

http://api.yandex.ru/disk/

http://api.yandex.ru/login/

https://yadi.sk/d/5b9BoUjtZvJhp

References

Page 39: RESTing with the new Yandex.Disk API, Clemens Аuer

Clemens Auer

Developer

[email protected]@yandex-team.ru

Thank you