I have one class with static methods : this class wraps calls to the Twitter API
In a second class, I have some business logic.
Due to the asynchronousness behaviour of some methods in the wrapper class, I have difficulties to design the communication. Here is what I've done :
APIManager.swift
public class APIManager {
class func getPermission(callback : () -> Void) {
let accountStore = ACAccountStore()
let accountType =
ACAccountStore().accountTypeWithAccountTypeIdentifier(ACAccountTypeIdentifierTwitter)
let callbackRequestAccess = { (granted: Bool, error: NSError!) -> Void in
...
if(granted) {
callback()
}
}
accountStore.requestAccessToAccountsWithType(setAccountType,
options: nil, completion: callbackRequestAccess)
}
}
Welcome.swift
public class Welcome {
public func checkPermission() {
APIManager.getPermission(getTweet)
}
public func getTweet() {
...
}
}
I am not sure that this design in right or not. I don't want to have a strong link between those classes, that's why I am using a callback.
Is this a classic design ? Moreover, I don't feel like this behaviour will be easy to test ?
You will greatly improve testability by not using class methods here. Create a TwitterConnection
protocol. Create a SystemTwitterConnection
that conforms to it and manages things through ACAccountStore
. Create a TestTwitterConnection
that returns pre-set responses that you can configure for testing. You could even create a KeychainTwitterConnection
to manage Twitter logins by hand without using ACAccountStore
, or some other implementation if Apple comes out with yet another way to store these accounts.
Pass the appropriate connection to Welcome
when it is created.
If the TwitterConnection
protocol gets large, you should strongly consider splitting it up into smaller protocols, such as TwitterAuthenticator
and TweetFetcher
that handle fewer things (even if a single type actually implements all of those protocols). This can make testing much easier by allowing your test types to implement just a few functions rather than dozens.
The use of closures is probably fine, but you should stick more closely to Cocoa naming conventions. What you're calling a callback
is traditionally called completion
. I'd also follow Cocoa's lead on how to name methods. Rather than getPermission()
, it would be requestAccessWithCompletionHandler()
. This would help the caller understand that it has very similar behavior to requestAccessToAccountsWithType(options:completion:)
. Don't built a new vocabulary for the caller.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With