-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Alamofire Support #59
Conversation
@RuiAAPeres I am making a pull-request, not because it is done, but because I wanted you to see the direction that I was headed with this (you may want to add your work-in-progress label). Hopefully, I'll have all this done before the end of next week. I'm planning to expand the test coverage of a library I'm writing. Which should exercise this code and push its limits. Once I'm done with that then I expect this will be ready for inclusion upstream. Put another way: I'm dog-fooding this still and I'm not 100% sure its right but it at least indicates the direction it is heading. |
I was wondering if we actually need to implement the delegate, instead of simply returning self instead of nil as the delegate from the Turntable, and simply pass it to satisfy the requirement. Is there an actual use case for it? |
@Sephiroth87 I'm not sure I follow. I think you are asking if Vinyl's To which my short answer would be: there might be a use case for it but this is most certainly not it. The single best reason is that the delegate is supposed to be listening for a network response. Why would Furthermore the goal here is to create a Which is why a library like Alamofire absolutely needs to conform to all those delegate protocols (and does in Not to dodge the question entirely though. The place where I could see Vinyl start to need to implement those protocols is when it provides the capability to record a network response. In that case it could then be a delegate and accept a delegate. In this capacity it might "pass-through" or curry its delegate responses (after it does its own processing) to the actual delegate that is being tested. Just one thought. I hope that answers the question. |
I guess my mistake was assuming In this case clearly it doesn't make sense to have inherit from it. Just keep in mind then that Vinyl will need to record network responses "soon" (#12), but I don't know how it will actually handle it. |
4e5b6fb
to
5052d74
Compare
At this point I'm ready to say it is a stable starting point for Vinyl working with Alamofire. Welcome feedback and review. |
bdff372
to
88313a2
Compare
I've just had a go with this - worked well for me. Thanks a lot! Would be great to get this merged ASAP. |
@tomtaylor this needs to be evaluated. I am unsure about this approach. |
@RuiAAPeres can you provide any suggestions to @RLovelett? At the moment we'd love to use Vinyl (or DVR), but this is the only working integration with Alamofire. |
@tomtaylor I've been using these changes for a few weeks now. Considering it has relatively few API differences with the master of the repo they should be mostly drop-in replacements for one another. Therefore, I feel like this is stable enough that it can be used as a fork in the meantime. If you check out the master branch on my fork I have integrated this PR, #62 and #63. I plan to maintain that fork as long as necessary so that there is a working implementation that supports Alamofire. I hope that helps you have some confidence with moving forward using Vinyl with Alamofire. |
} | ||
|
||
// MARK: - Private methods | ||
|
||
private func playVinyl<URLSessionTask: URLSessionTaskType>(request request: NSURLRequest, fromData bodyData: NSData? = nil, completionHandler: RequestCompletionHandler) throws -> URLSessionTask { | ||
private func playVinyl(request request: NSURLRequest, fromData bodyData: NSData? = nil, completionHandler: RequestCompletionHandler) throws -> URLSessionUploadTask { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really agree with this:
- We use
URLSessionTaskType
specifically to abstract the kind of Task we are working with. - You replaced it with a URLSessionUploadTask, which might not even make sense, depending on the operating we are doing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can add it back if you'd like. Though I don't think it'll buy you the flexibility you seem to think it will.
The only type that will conform to this going forward is URLSessionUploadTask
. So even though it uses generic syntax there is nothing generic about its usage (e.g., protocols for protocols sake).
What is more going forward URLSessionDataTask
and URLSessionUploadTask
, the only two types that ever conformed to URLSessionTask
, are unlikely to be able to conform to the protocol as written. So if they should ever need to conform to some protocol in the future you'd be either adding a new protocol or re-writing the existing one (e.g., the same place you are at now by just removing it in the first place).
In fact, after thinking through this I think the more prudent solution is to move the current implementation of playVinyl
to it's only call-site and remove playVinyl
entirely.
e.g.,
diff --git a/Vinyl/Turntable.swift b/Vinyl/Turntable.swift
index dce17b7..167884e 100644
--- a/Vinyl/Turntable.swift
+++ b/Vinyl/Turntable.swift
@@ -56,21 +56,6 @@ public final class Turntable: NSURLSession {
// MARK: - Private methods
- private func playVinyl(request request: NSURLRequest, fromData bodyData: NSData? = nil, completionHandler: RequestCompletionHandler) throws -> URLSessionUploadTask {
-
- guard let player = player else {
- fatalError("Did you forget to load the Vinyl? <U+1F3B6>")
- }
-
- let completion = try player.playTrack(forRequest: transformRequest(request, bodyData: bodyData))
-
- return URLSessionUploadTask {
- self.operationQueue.addOperationWithBlock {
- completionHandler(completion.data, completion.response, completion.error)
- }
- }
- }
-
private func transformRequest(request: NSURLRequest, bodyData: NSData? = nil) -> NSURLRequest {
guard let bodyData = bodyData else {
return request
@@ -113,9 +98,18 @@ extension Turntable {
}
public override func uploadTaskWithRequest(request: NSURLRequest, fromData bodyData: NSData?, completionHandler: (NSData?, NSURLResponse?, NSError?) -> Void) -> NSURLSessionUploadTask {
+
+ guard let player = player else {
+ fatalError("Did you forget to load the Vinyl? <U+1F3B6>")
+ }
do {
- return try playVinyl(request: request, fromData: bodyData, completionHandler: completionHandler) as URLSessionUploadTask
+ let completion = try player.playTrack(forRequest: transformRequest(request, bodyData: bodyData))
+ return URLSessionUploadTask {
+ self.operationQueue.addOperationWithBlock {
+ completionHandler(completion.data, completion.response, completion.error)
+ }
+ }
}
catch Error.TrackNotFound {
errorHandler.handleTrackNotFound(request, playTracksUniquely: turntableConfiguration.playTracksUniquely)
@RLovelett I left a couple of comments in your PR. cc @Sephiroth87 |
ping @RLovelett @Sephiroth87 |
internal let turntableConfiguration: TurntableConfiguration | ||
internal var player: Player? | ||
internal let operationQueue: NSOperationQueue | ||
private let _delegate: NSURLSessionDelegate? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sessionDelegate instead of _delegate?
I'm not sure I agree with moving all the logic inside of the task, it's job should be just to handle receiving/sending data, but it shouldn't handle anything session related, definitely not its delegate directly. Plus, to add delegate support to upload tasks would require duplicating all this logic again, since URLSessionUploadTask doesn't (and can't) subclass URLSessionDataTask |
tl;dr Alamofire makes extensive use of the
NSURLSessionDelegate
protocol. Vinyl did not support this.What's changing
URLSessionDataTask
to better implement the properties and methods described in the base classNSURLSessionTask
URLSessionDataTask
as described by the documentation inNSURLSessionDataTask
Optional<NSURLSessionDelegate>
as an argument toTurntable
initializersExample Usage