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

942 views
726 views

Published on

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.

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
942
On SlideShare
0
From Embeds
0
Number of Embeds
178
Actions
Shares
0
Downloads
5
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

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

  1. 1. REST ing with the new Yandex.Disk API Clemens Auer Developer
  2. 2. What Is Yandex Disk?
  3. 3. What Is Yandex Disk? - 26 Million registered Disk users. - 6 Billion files. - 14 Million files added per day.
  4. 4. What Is Yandex Disk? How much storage space users get for free? - Basic: 10 GB. - Invites: up to 10 GB. - Partner offers: currently up to 50 GB.
  5. 5. What Is Yandex Disk? For those who need more: Storage 10 GB 100 GB 1 TB per month 30 RUB 150 RUB 900 RUB per year 300 RUB 1500 RUB 9000 RUB
  6. 6. What Is Yandex Disk? Clients - Web: disk.yandex.ru, widgets. - Desktop: Windows, Mac, Linux - Mobile: iOS, Android, WinPhone - 3rd party
  7. 7. What Is Yandex Disk? 3rd party clients. - Official SDKs (JAVA, Obj-C, C#) - WebDAV + extensions - REST API
  8. 8. WebDAV vs. REST API
  9. 9. WebDAV vs. REST API WebDAV REST Upload ✓ ✓ Download ✓ ✓ Create Folder ✓ ✓ Copy ✓ ✓ Move ✓ ✓ Delete ✓ ✓ List ✓ ✓
  10. 10. WebDAV vs. REST API Support for public files WebDAV REST Share ✓ ✓ Unshare ✓ ✓ List Metadata ✗ ✓ Download ✗ ✓ Save to Disk ✗ ✓
  11. 11. WebDAV vs. REST API Working with the trash WebDAV REST List ✗ ✓ Delete ✗ ✓ Restore ✗ ✓
  12. 12. WebDAV vs. REST API What is missing? WebDAV REST Basic Auth ✓ ✗ Free/Used Space ✓ ✗* Hash Upload ✓ ✗ Custom Props ✓ ✗ Userinfo ✓ ✗
  13. 13. Getting Started - Register application - Register dev accounts - Get token for development - Полигон - Code
  14. 14. Register application
  15. 15. Register application
  16. 16. Register application
  17. 17. Register application
  18. 18. Register application
  19. 19. Register dev accounts.
  20. 20. https://oauth.yandex.ru/authorize?response_type=token&client_id= Get token for development
  21. 21. https://oauth.yandex.ru/verification_code?dev=True# access_token=d8edc4f3a698473fbc87634c41b2ca81 &token_type=bearer &state= &expires_in=31536000 Get token for development
  22. 22. Полигон
  23. 23. Getting Started - Register application - Register dev accounts - Get token for development - Полигон - Code
  24. 24. Code example What we try to achieve: 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 }
  25. 25. Code example Basic properties in Disk class 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" ] } }
  26. 26. Code example Complete basic Disk class 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 } }
  27. 27. Code example Disk extension for de-serializing JSON data 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 } }
  28. 28. Code example NSURLSessing extension for doing JSON requests 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 } } } }
  29. 29. Take a peek at the documentation
  30. 30. Code example Disk extension for processing common JSON object 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) } }
  31. 31. Code example Disk extension implementing file upload 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() } }
  32. 32. Take another peek at the documentation
  33. 33. Code example Disk extension implementing delete. 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() } }
  34. 34. Lessons Learned Swift - enum, switch, closures, tuples - Type safety vs. Obj-C weak typing - Volatile: Xcode release notes. - Apple Dev Forums
  35. 35. Lessons Learned REST API - Documentation vs. Полигон - Fast - OAuth - Roadmap ahead
  36. 36. Lessons Learned In general - Test driven development saves time. - Autotest the API version - Report bugs http://feedback2.yandex.ru/disk/api/
  37. 37. References 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
  38. 38. Clemens Auer Developer aucl@yandex.ru aucl@yandex-team.ru Thank you

×