From corinnekrych at gmail.com Thu Feb 25 10:55:56 2016 From: corinnekrych at gmail.com (Corinne Krych) Date: Thu, 25 Feb 2016 11:55:56 +0100 Subject: [feedhenry-dev] Let's talk about Swift: async completion closure Message-ID: As we start writing the FH Swift SDK, I'd like to discuss the Swift syntax of our API. In this thread, I'd like to focus on how to express async completion. Let's see in detail the syntax of FH.init and FH.cloud. *S0: Swift consuming ObjC sdk* *Motivation:* Swift app consuming our ObjC fh-io-ask will use the automatic conversion. Default syntax helloworls-ios template [1]. *API looks like:* > public class func initWithSuccess(sucornil: ((FHResponse!) -> Void)!, > andFailure failornil: ((FHResponse!) -> Void)!) > public class func performCloudRequest(path: String!, withMethod > requestMethod: String!, andHeaders headers: [NSObject : AnyObject]!, > andArgs arguments: [NSObject : AnyObject]!, andSuccess sucornil: > ((FHResponse!) -> Void)!, andFailure failornil: ((FHResponse!) -> Void)!) Note the extensive usage of implicit umwrap (the ! mark). As ObjC does not have Optional. Let's see how we can improve it. *S1: More iOS standard lib: one completion block/closure* *Motivation:* One completion close to looks like iOS standard lib. For example, if you look at [NSURLSession API documentation]( https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSURLSession_class/#//apple_ref/occ/instm/NSURLSession/dataTaskWithRequest:completionHandler:), you can see the usage of `completionHandler`. *API looks like:* > public class func `init`(completionHandler: (Response, NSError?) -> Void ) > -> Void > public class func performCloudRequest(path: String, method: String, > headers: [String:String]?, args: [String: String]?, config: Config = > Config(), completionHandler: (Response, NSError?) -> Void) -> Void Note the back tick around init as init is a reserved keyword in Swift. *API usage:* > FH.setup(config, completionHandler: { (resp: Response, err: NSError?) -> > Void in > if (err != nil) { > FH.performCloudRequest("/hello", method: "POST", headers: nil, args: > nil, config: config, completionHandler: {(resp: Response, err: NSError?) -> > Void in > // Do something > }) > } else { > // Error in FH.init > } > }) *Pro:* Easy to use, close to ObjC API *Con:* Error code used, no usage os error handling *S2: More Swift 2: Using Error handling for async, closure wrapper* *Motivation:* Make use of try/catch instead of NSError to looks more Swift2. Refer to this excellent article: http://alisoftware.github.io/swift/async/error/2016/02/06/async-errors/#hacking-it or more on wrapper closure on http://appventure.me/2015/06/19/swift-try-catch-asynchronous-closures/ *API looks like:* > public class func `init`(completionHandler: (() throws -> Response) -> > Void) -> Void > public class func performCloudRequest(path: String, method: String, > headers: [String:String]?, args: [String: String]?, config: Config = > Config(), completionHandler: (() throws -> Response) -> Void) -> Void *API usage:* > FH.setup(config, completionHandler: { (inner: () throws -> Response) -> > Void in > do { > let result = try inner() > FH.performCloudRequest("/hello", method: "POST", headers: nil, > args: nil, config: config, completionHandler: { (inner: () throws -> > Response) -> Void in > do { > let result = try inner() > } catch _ {} > }) > } catch _ {} > }) *Pro:* You do/catch your async method call. *Con:* * Not very elegant syntax * Wrapper closure feels awkward. *S3: More trendy: going "Monad"* *Motivation:* Going one step further, we create an enum container Result wich hold "future" values *API loos like:* > public class func `init`(completionHandler: Result -> Void) -> > Void > public class func performCloudRequest(path: String, method: String, > headers: [String:String]?, args: [String: String]?, config: Config = > Config(), completionHandler: Result -> Void) -> Void *API usage:* > FH.setup(config, completionHandler: { (result: Result) -> Void in > do { > let response = try result.resolve() > FH.performCloudRequest("/hello", method: "POST", headers: nil, > args: nil, config: config, completionHandler: { (result: Result) > -> Void in > do { > let result = try result.resolve() > } catch _ {/*ERROR */} > }) > } catch _ {/*ERROR */} > }) *Pro:* Modern syntax close to promise/future *Con:* A bit far from the other Java/JS/C# syntax *Conclusion* After trying S2, I have to say it's quite awkward, I'd rather stick to S1. S3 is really nice but does not fit with other languages API. On aside note, I'd also recommand that we should shorten method name ie: `performCloudRequest:method:headers:args:completionHandler:` will become `cloud:method:headers:args:completionHandler:` to stick closer to JavaScript syntax. In my opinion, S1 is easy route making the ObjC/Swift transition easy. This is my point of view, but I'd love to hear from you. -------------- next part -------------- An HTML attachment was scrubbed... URL: From supittma at redhat.com Thu Feb 25 14:43:42 2016 From: supittma at redhat.com (Summers Pittman) Date: Thu, 25 Feb 2016 09:43:42 -0500 Subject: [feedhenry-dev] Let's talk about Swift: async completion closure In-Reply-To: References: Message-ID: On Thu, Feb 25, 2016 at 5:55 AM, Corinne Krych wrote: > As we start writing the FH Swift SDK, I'd like to discuss the Swift syntax > of our API. In this thread, I'd like to focus on how to express async > completion. Let's see in detail the syntax of FH.init and FH.cloud. > > *S0: Swift consuming ObjC sdk* > > *Motivation:* > Swift app consuming our ObjC fh-io-ask will use the automatic conversion. > Default syntax helloworls-ios template [1]. > > *API looks like:* > >> public class func initWithSuccess(sucornil: ((FHResponse!) -> Void)!, >> andFailure failornil: ((FHResponse!) -> Void)!) >> public class func performCloudRequest(path: String!, withMethod >> requestMethod: String!, andHeaders headers: [NSObject : AnyObject]!, >> andArgs arguments: [NSObject : AnyObject]!, andSuccess sucornil: >> ((FHResponse!) -> Void)!, andFailure failornil: ((FHResponse!) -> Void)!) > > > Note the extensive usage of implicit umwrap (the ! mark). As ObjC does not > have Optional. > Let's see how we can improve it. > > *S1: More iOS standard lib: one completion block/closure* > > *Motivation:* > One completion close to looks like iOS standard lib. For example, if you > look at [NSURLSession API documentation]( > https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSURLSession_class/#//apple_ref/occ/instm/NSURLSession/dataTaskWithRequest:completionHandler:), > you can see the usage of `completionHandler`. > > *API looks like:* > >> public class func `init`(completionHandler: (Response, NSError?) -> Void >> ) -> Void >> public class func performCloudRequest(path: String, method: String, >> headers: [String:String]?, args: [String: String]?, config: Config = >> Config(), completionHandler: (Response, NSError?) -> Void) -> Void > > > Note the back tick around init as init is a reserved keyword in Swift. > > *API usage:* > >> FH.setup(config, completionHandler: { (resp: Response, err: NSError?) -> >> Void in >> if (err != nil) { >> FH.performCloudRequest("/hello", method: "POST", headers: nil, >> args: nil, config: config, completionHandler: {(resp: Response, err: >> NSError?) -> Void in >> // Do something >> }) >> } else { >> // Error in FH.init >> } >> }) > > > *Pro:* > Easy to use, close to ObjC API > *Con:* > Error code used, no usage os error handling > > *S2: More Swift 2: Using Error handling for async, closure wrapper* > > *Motivation:* > Make use of try/catch instead of NSError to looks more Swift2. > Refer to this excellent article: > http://alisoftware.github.io/swift/async/error/2016/02/06/async-errors/#hacking-it > or more on wrapper closure on > http://appventure.me/2015/06/19/swift-try-catch-asynchronous-closures/ > > *API looks like:* > >> public class func `init`(completionHandler: (() throws -> Response) -> >> Void) -> Void >> public class func performCloudRequest(path: String, method: String, >> headers: [String:String]?, args: [String: String]?, config: Config = >> Config(), completionHandler: (() throws -> Response) -> Void) -> Void > > > *API usage:* > >> FH.setup(config, completionHandler: { (inner: () throws -> Response) -> >> Void in >> do { >> let result = try inner() >> FH.performCloudRequest("/hello", method: "POST", headers: nil, >> args: nil, config: config, completionHandler: { (inner: () throws -> >> Response) -> Void in >> do { >> let result = try inner() >> } catch _ {} >> }) >> } catch _ {} >> }) > > > *Pro:* > You do/catch your async method call. > > *Con:* > * Not very elegant syntax > * Wrapper closure feels awkward. > > *S3: More trendy: going "Monad"* > > *Motivation:* > Going one step further, we create an enum container Result wich hold > "future" values > > *API loos like:* > >> public class func `init`(completionHandler: Result -> Void) -> >> Void >> public class func performCloudRequest(path: String, method: String, >> headers: [String:String]?, args: [String: String]?, config: Config = >> Config(), completionHandler: Result -> Void) -> Void > > > *API usage:* > >> FH.setup(config, completionHandler: { (result: Result) -> Void >> in >> do { >> let response = try result.resolve() >> FH.performCloudRequest("/hello", method: "POST", headers: nil, >> args: nil, config: config, completionHandler: { (result: Result) >> -> Void in >> do { >> let result = try result.resolve() >> } catch _ {/*ERROR */} >> }) >> } catch _ {/*ERROR */} >> }) > > > *Pro:* > Modern syntax close to promise/future > > *Con:* > A bit far from the other Java/JS/C# syntax > > *Conclusion* > > After trying S2, I have to say it's quite awkward, I'd rather stick to S1. > S3 is really nice but does not fit with other languages API. > On aside note, I'd also recommand that we should shorten method name ie: > `performCloudRequest:method:headers:args:completionHandler:` will become > `cloud:method:headers:args:completionHandler:` to stick closer to > JavaScript syntax. > > In my opinion, S1 is easy route making the ObjC/Swift transition easy. > This is my point of view, but I'd love to hear from you. > > Might I suggest using events instead? Sorry for the Java but I'm thinking something like this : public class SplashScreen extends AppCompatActivity { FHClient client = new FHClient(); @Override protected void onStart() { super.onStart(); fhClient.registerEventHandler(this) if (!fhClient.isInit()) { fhClient.init(); } } public void onInit(InitSuccessful event) { //Client is initted } public void onInitError(final InitFailed event) { //some kind of init failure. } } I'm borrowing patterns that Google Play uses in Android proper, and I would like to see the Android SDK also adopt an event driven model (perhaps using an event bus mechanism) > _______________________________________________ > feedhenry-dev mailing list > feedhenry-dev at redhat.com > https://www.redhat.com/mailman/listinfo/feedhenry-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From corinnekrych at gmail.com Thu Feb 25 16:11:09 2016 From: corinnekrych at gmail.com (Corinne Krych) Date: Thu, 25 Feb 2016 17:11:09 +0100 Subject: [feedhenry-dev] Let's talk about Swift: async completion closure In-Reply-To: References: Message-ID: @summers That would go even deeper in FRP. We should list it as: S4: More reactive way I don't have code snippet for it but i'll do some. btw all the other code snippets comes have an "trial" implementation [1]. pro: Rx way fits for asynch data stream con: A bit far from the other Java/JS/C# existing syntax For the initial Swift SDK, I'd stick to S1 to be in sync with other language SDK. But I see where you're coming from Summers and I like the discussion. Let me come back to you with some Swifty code snippets. ++ Corinne On 25 February 2016 at 15:43, Summers Pittman wrote: > > > On Thu, Feb 25, 2016 at 5:55 AM, Corinne Krych > wrote: > >> As we start writing the FH Swift SDK, I'd like to discuss the Swift >> syntax of our API. In this thread, I'd like to focus on how to express >> async completion. Let's see in detail the syntax of FH.init and FH.cloud. >> >> *S0: Swift consuming ObjC sdk* >> >> *Motivation:* >> Swift app consuming our ObjC fh-io-ask will use the automatic conversion. >> Default syntax helloworls-ios template [1]. >> >> *API looks like:* >> >>> public class func initWithSuccess(sucornil: ((FHResponse!) -> Void)!, >>> andFailure failornil: ((FHResponse!) -> Void)!) >>> public class func performCloudRequest(path: String!, withMethod >>> requestMethod: String!, andHeaders headers: [NSObject : AnyObject]!, >>> andArgs arguments: [NSObject : AnyObject]!, andSuccess sucornil: >>> ((FHResponse!) -> Void)!, andFailure failornil: ((FHResponse!) -> Void)!) >> >> >> Note the extensive usage of implicit umwrap (the ! mark). As ObjC does >> not have Optional. >> Let's see how we can improve it. >> >> *S1: More iOS standard lib: one completion block/closure* >> >> *Motivation:* >> One completion close to looks like iOS standard lib. For example, if you >> look at [NSURLSession API documentation]( >> https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSURLSession_class/#//apple_ref/occ/instm/NSURLSession/dataTaskWithRequest:completionHandler:), >> you can see the usage of `completionHandler`. >> >> *API looks like:* >> >>> public class func `init`(completionHandler: (Response, NSError?) -> Void >>> ) -> Void >>> public class func performCloudRequest(path: String, method: String, >>> headers: [String:String]?, args: [String: String]?, config: Config = >>> Config(), completionHandler: (Response, NSError?) -> Void) -> Void >> >> >> Note the back tick around init as init is a reserved keyword in Swift. >> >> *API usage:* >> >>> FH.setup(config, completionHandler: { (resp: Response, err: NSError?) -> >>> Void in >>> if (err != nil) { >>> FH.performCloudRequest("/hello", method: "POST", headers: nil, >>> args: nil, config: config, completionHandler: {(resp: Response, err: >>> NSError?) -> Void in >>> // Do something >>> }) >>> } else { >>> // Error in FH.init >>> } >>> }) >> >> >> *Pro:* >> Easy to use, close to ObjC API >> *Con:* >> Error code used, no usage os error handling >> >> *S2: More Swift 2: Using Error handling for async, closure wrapper* >> >> *Motivation:* >> Make use of try/catch instead of NSError to looks more Swift2. >> Refer to this excellent article: >> http://alisoftware.github.io/swift/async/error/2016/02/06/async-errors/#hacking-it >> or more on wrapper closure on >> http://appventure.me/2015/06/19/swift-try-catch-asynchronous-closures/ >> >> *API looks like:* >> >>> public class func `init`(completionHandler: (() throws -> Response) -> >>> Void) -> Void >>> public class func performCloudRequest(path: String, method: String, >>> headers: [String:String]?, args: [String: String]?, config: Config = >>> Config(), completionHandler: (() throws -> Response) -> Void) -> Void >> >> >> *API usage:* >> >>> FH.setup(config, completionHandler: { (inner: () throws -> Response) -> >>> Void in >>> do { >>> let result = try inner() >>> FH.performCloudRequest("/hello", method: "POST", headers: nil, >>> args: nil, config: config, completionHandler: { (inner: () throws -> >>> Response) -> Void in >>> do { >>> let result = try inner() >>> } catch _ {} >>> }) >>> } catch _ {} >>> }) >> >> >> *Pro:* >> You do/catch your async method call. >> >> *Con:* >> * Not very elegant syntax >> * Wrapper closure feels awkward. >> >> *S3: More trendy: going "Monad"* >> >> *Motivation:* >> Going one step further, we create an enum container Result wich hold >> "future" values >> >> *API loos like:* >> >>> public class func `init`(completionHandler: Result -> Void) -> >>> Void >>> public class func performCloudRequest(path: String, method: String, >>> headers: [String:String]?, args: [String: String]?, config: Config = >>> Config(), completionHandler: Result -> Void) -> Void >> >> >> *API usage:* >> >>> FH.setup(config, completionHandler: { (result: Result) -> Void >>> in >>> do { >>> let response = try result.resolve() >>> FH.performCloudRequest("/hello", method: "POST", headers: nil, >>> args: nil, config: config, completionHandler: { (result: Result) >>> -> Void in >>> do { >>> let result = try result.resolve() >>> } catch _ {/*ERROR */} >>> }) >>> } catch _ {/*ERROR */} >>> }) >> >> >> *Pro:* >> Modern syntax close to promise/future >> >> *Con:* >> A bit far from the other Java/JS/C# syntax >> >> *Conclusion* >> >> After trying S2, I have to say it's quite awkward, I'd rather stick to S1. >> S3 is really nice but does not fit with other languages API. >> On aside note, I'd also recommand that we should shorten method name ie: >> `performCloudRequest:method:headers:args:completionHandler:` will become >> `cloud:method:headers:args:completionHandler:` to stick closer to >> JavaScript syntax. >> >> In my opinion, S1 is easy route making the ObjC/Swift transition easy. >> This is my point of view, but I'd love to hear from you. >> >> > Might I suggest using events instead? > > Sorry for the Java but I'm thinking something like this : > > public class SplashScreen extends AppCompatActivity { > > FHClient client = new FHClient(); > > @Override > protected void onStart() { > super.onStart(); > fhClient.registerEventHandler(this) > if (!fhClient.isInit()) { > fhClient.init(); > } > } > > public void onInit(InitSuccessful event) { > //Client is initted > } > public void onInitError(final InitFailed event) { > //some kind of init failure. > } > } > > > I'm borrowing patterns that Google Play uses in Android proper, and I > would like to see the Android SDK also adopt an event driven model (perhaps > using an event bus mechanism) > > >> _______________________________________________ >> feedhenry-dev mailing list >> feedhenry-dev at redhat.com >> https://www.redhat.com/mailman/listinfo/feedhenry-dev >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mracz at redhat.com Fri Feb 26 11:23:56 2016 From: mracz at redhat.com (=?UTF-8?B?TcOhdMOpIFLDoWN6?=) Date: Fri, 26 Feb 2016 11:23:56 +0000 Subject: [feedhenry-dev] Let's talk about Swift: async completion closure Message-ID: Hi Corinne, Somewhat unrelated, I always wondered why the ObjC API followed the JS API so closely with blocks, instead of a more idiomatic syntax based on protocols and delegates could possibly be more obvious for the end-users, similar to how NSURLConnection is used. (I see there is an FHResponseDelegate already, but it is only used internally by FHAct.) If we changed the ObjC API that way, would it narrow down the choices for the best syntax for the Swift API? The client code would look very much like Summers' Java example, and a few indentation levels could be spared, compared to using blocks. Kind regards, M?t? On Thu, Feb 25, 2016 at 5:00 PM, wrote: > > @summers That would go even deeper in FRP. > We should list it as: > S4: More reactive way > I don't have code snippet for it but i'll do some. > btw all the other code snippets comes have an "trial" implementation [1]. > pro: > Rx way fits for asynch data stream > con: > A bit far from the other Java/JS/C# existing syntax > > For the initial Swift SDK, I'd stick to S1 to be in sync with other > language SDK. > But I see where you're coming from Summers and I like the discussion. Let > me come back to you with some Swifty code snippets. > ++ > Corinne > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From corinnekrych at gmail.com Fri Feb 26 14:00:54 2016 From: corinnekrych at gmail.com (Corinne Krych) Date: Fri, 26 Feb 2016 15:00:54 +0100 Subject: [feedhenry-dev] Let's talk about Swift: async completion closure In-Reply-To: References: Message-ID: On 26 February 2016 at 12:23, M?t? R?cz wrote: > Hi Corinne, > > Somewhat unrelated, I always wondered why the ObjC API followed the JS API > so closely with blocks, instead of a more idiomatic syntax based on > protocols and delegates could possibly be more obvious for the end-users, > similar to how NSURLConnection is used. (I see there is an > FHResponseDelegate already, but it is only used internally by FHAct.) > As FHAct as been deprecated for quite a while, this would be out of Swift SDK 4.x and therefore there will be no Delegate any more. Indeed it will narrow down the usage. > If we changed the ObjC API that way, would it narrow down the choices for > the best syntax for the Swift API? The client code would look very much > like Summers' Java example, and a few indentation levels could be spared, > compared to using blocks. > > Kind regards, > M?t? > > On Thu, Feb 25, 2016 at 5:00 PM, wrote: > >> >> @summers That would go even deeper in FRP. >> We should list it as: >> S4: More reactive way >> I don't have code snippet for it but i'll do some. >> btw all the other code snippets comes have an "trial" implementation [1]. >> pro: >> Rx way fits for asynch data stream >> con: >> A bit far from the other Java/JS/C# existing syntax >> >> For the initial Swift SDK, I'd stick to S1 to be in sync with other >> language SDK. >> But I see where you're coming from Summers and I like the discussion. Let >> me come back to you with some Swifty code snippets. >> ++ >> Corinne >> >> > > _______________________________________________ > feedhenry-dev mailing list > feedhenry-dev at redhat.com > https://www.redhat.com/mailman/listinfo/feedhenry-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From corinnekrych at gmail.com Fri Feb 26 15:05:26 2016 From: corinnekrych at gmail.com (Corinne Krych) Date: Fri, 26 Feb 2016 16:05:26 +0100 Subject: [feedhenry-dev] Let's talk about Swift: async completion closure In-Reply-To: References: Message-ID: Hi M?t? [posting to the mailing list, to carry on the discussion together] Delegates trend to be tagged "old-school" because there were the initial way to deal with async calls. Blocks get introduced much later in 2010 with iOS4. Actually depending on your use case you'll use either. NSURLSession is a perfect example, it got both. You use blocks completion handler if you're not interested in progression whereas you'll implement `NSURLSessionDataDelegate` ans use its delegate method `URLSession:dataTask:didReceiveData:`. See [1] for some blog posts on the subject. For FeedHenry SDK, given that we work with static methods (we could start another discussion on that topic) blocks offer a nicer syntax and much convenient usage. With Swift coming on, block become closures. And this is the good news: closures/functions/methods got a unified syntax, so nice and easy you will love. With closure and the power of Swift FP feature, you can get to fancier API discussion see S2, S3. Lest to answer, your question about more iOS over JavaScript feel for our API, this is exactly why I'm in favor of merging `onSuccess` and `onFailure` blocks into one `completionHandler` see S1 syntax as it's closer to iOS libraries usage. I hope it's answer your questions. I love the discussion :) ++ Corinne [1] block vs delegate post: http://blog.stablekernel.com/blocks-or-delegates/ http://www.abdus.me/ios-programming-tips/blocks-vs-delegates-ios-comparison/ On 26 February 2016 at 15:08, M?t? R?cz wrote: > Hi Corinne, > > Thanks for quick response. My main question is, do we prefer blocks over > delegates? And is it only because we want to have a uniform-ish API in JS, > iOS and Android, or is there some deeper reason, such as delegates are > old-school and blocks are the new way? I'm not in the loop with iOS dev > anymore, so I'm not sure what the trends are these days, but it always felt > like we're abusing blocks in this case. :) > I also understand we can't/won't just change the API from one version to > the next, so my q is more theoretical than practical. > > Kind regards, > M?t? > > On Fri, Feb 26, 2016 at 2:00 PM, Corinne Krych > wrote: > >> >> >> On 26 February 2016 at 12:23, M?t? R?cz wrote: >> >>> Hi Corinne, >>> >>> Somewhat unrelated, I always wondered why the ObjC API followed the JS >>> API so closely with blocks, instead of a more idiomatic syntax based on >>> protocols and delegates could possibly be more obvious for the end-users, >>> similar to how NSURLConnection is used. (I see there is an >>> FHResponseDelegate already, but it is only used internally by FHAct.) >>> >> >> As FHAct as been deprecated for quite a while, this would be out of Swift >> SDK 4.x and therefore there will be no Delegate any more. >> Indeed it will narrow down the usage. >> >> >>> If we changed the ObjC API that way, would it narrow down the choices >>> for the best syntax for the Swift API? The client code would look very much >>> like Summers' Java example, and a few indentation levels could be spared, >>> compared to using blocks. >>> >>> Kind regards, >>> M?t? >>> >>> On Thu, Feb 25, 2016 at 5:00 PM, >>> wrote: >>> >>>> >>>> @summers That would go even deeper in FRP. >>>> We should list it as: >>>> S4: More reactive way >>>> I don't have code snippet for it but i'll do some. >>>> btw all the other code snippets comes have an "trial" implementation >>>> [1]. >>>> pro: >>>> Rx way fits for asynch data stream >>>> con: >>>> A bit far from the other Java/JS/C# existing syntax >>>> >>>> For the initial Swift SDK, I'd stick to S1 to be in sync with other >>>> language SDK. >>>> But I see where you're coming from Summers and I like the discussion. >>>> Let >>>> me come back to you with some Swifty code snippets. >>>> ++ >>>> Corinne >>>> >>>> >>> >>> _______________________________________________ >>> feedhenry-dev mailing list >>> feedhenry-dev at redhat.com >>> https://www.redhat.com/mailman/listinfo/feedhenry-dev >>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: