{"action":"created","issue":{"url":"https://api.github.com/repos/Haneke/HanekeSwift/issues/316","repository_url":"https://api.github.com/repos/Haneke/HanekeSwift","labels_url":"https://api.github.com/repos/Haneke/HanekeSwift/issues/316/labels{/name}","comments_url":"https://api.github.com/repos/Haneke/HanekeSwift/issues/316/comments","events_url":"https://api.github.com/repos/Haneke/HanekeSwift/issues/316/events","html_url":"https://github.com/Haneke/HanekeSwift/issues/316","id":156012882,"number":316,"title":"Haneke and caching Facebook graph requests","user":{"login":"simoami","id":2038264,"avatar_url":"https://avatars.githubusercontent.com/u/2038264?v=3","gravatar_id":"","url":"https://api.github.com/users/simoami","html_url":"https://github.com/simoami","followers_url":"https://api.github.com/users/simoami/followers","following_url":"https://api.github.com/users/simoami/following{/other_user}","gists_url":"https://api.github.com/users/simoami/gists{/gist_id}","starred_url":"https://api.github.com/users/simoami/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/simoami/subscriptions","organizations_url":"https://api.github.com/users/simoami/orgs","repos_url":"https://api.github.com/users/simoami/repos","events_url":"https://api.github.com/users/simoami/events{/privacy}","received_events_url":"https://api.github.com/users/simoami/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2016-05-20T17:29:44Z","updated_at":"2016-05-21T03:11:38Z","closed_at":null,"body":"Is there a way to tweak Haneke to cache an async code block under a string key? The reason being that by using the FB sdk, the api requests are wrapped into convenience methods. So there's not url to pass on to Haneke\r\n\r\nIdeally, I'd like to be able to create a custom fetcher to allow me to run any async block and cache its result under a specific key.\r\ne.g. \r\n\r\n```\r\nlet cache = Shared.dataCache\r\n\r\nlet fetcher = AsyncFetcher<JSON>(key: 'facebookProfile') { success, failure in\r\n  // async block goes here\r\n  let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: \"me\", parameters: nil)\r\n  graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in\r\n        if ((error) != nil) {\r\n            failure(error)\r\n        } else {\r\n            let json = JSON(result!)\r\n            let profile = FacebookProfile(json: json)\r\n            success(profile)\r\n        }\r\n  }\r\n}\r\n\r\n// Usage\r\ncache.fetch(fetcher: fetcher).onSuccess { data in\r\n  // my json data is accessible here\r\n}\r\n```\r\n\r\nAny pointers on how to go about implementing the async fetcher would be appreciated. This custom AsyncFetcher sounds like a great addition to Haneke."},"comment":{"url":"https://api.github.com/repos/Haneke/HanekeSwift/issues/comments/220755432","html_url":"https://github.com/Haneke/HanekeSwift/issues/316#issuecomment-220755432","issue_url":"https://api.github.com/repos/Haneke/HanekeSwift/issues/316","id":220755432,"user":{"login":"simoami","id":2038264,"avatar_url":"https://avatars.githubusercontent.com/u/2038264?v=3","gravatar_id":"","url":"https://api.github.com/users/simoami","html_url":"https://github.com/simoami","followers_url":"https://api.github.com/users/simoami/followers","following_url":"https://api.github.com/users/simoami/following{/other_user}","gists_url":"https://api.github.com/users/simoami/gists{/gist_id}","starred_url":"https://api.github.com/users/simoami/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/simoami/subscriptions","organizations_url":"https://api.github.com/users/simoami/orgs","repos_url":"https://api.github.com/users/simoami/repos","events_url":"https://api.github.com/users/simoami/events{/privacy}","received_events_url":"https://api.github.com/users/simoami/received_events","type":"User","site_admin":false},"created_at":"2016-05-21T03:11:38Z","updated_at":"2016-05-21T03:11:38Z","body":"fyi, this is what I came up with:\r\n\r\n```\r\nclass AsyncFetcher<T : DataConvertible> : Fetcher<T> {\r\n    \r\n    // Typealias to define the reusability in declaration of the closures.\r\n    typealias SuccessClosure = (NSData) -> Void\r\n    typealias ErrorClosure = (NSError?) -> Void\r\n\r\n    let completionHandler : (SuccessClosure, ErrorClosure) -> Void\r\n    \r\n    init(key: String, completionHandler: (SuccessClosure, ErrorClosure) -> Void) {\r\n        self.completionHandler = completionHandler\r\n        super.init(key: key)\r\n    }\r\n    \r\n    override func fetch(failure fail : ((NSError?) -> ()), success succeed : (T.Result) -> ()) {\r\n        \r\n        let successBlock: SuccessClosure = { (data) in\r\n            guard let value = T.convertFromData(data) else {\r\n                let description = \"Failed to convert value from returned data\"\r\n                let err = NSError(domain: \"conversion\", code: -1, userInfo:\r\n                    [NSLocalizedDescriptionKey: description])\r\n                fail(err)\r\n                return\r\n            }\r\n            succeed(value)\r\n        }\r\n        \r\n        let failureBlock: ErrorClosure = { (error) in\r\n            fail(error)\r\n        }\r\n        self.completionHandler(successBlock, failureBlock)\r\n    }\r\n    \r\n    override func cancelFetch() {}\r\n}\r\n\r\n```"}}
{"actor":{"display_login":"simoami"}}