Velhotes/Vinyl

caught "NSInvalidArgumentException"

RLovelett opened this issue · 7 comments

I'm trying to integrate Alamofire and Vinyl.

In my test case I'm doing:

let turntable = Turntable(vinylName: "vinyl_single", delegateQueue: NSOperationQueue.mainQueue())
print(turntable.delegate)

Which crashes on the print statement with the following exception.

/Users/lovelett/Source/lineup/LineupTests/LineupTests.swift:34: error: -[LineupTests.LineupTests testVinyl] : failed: caught "NSInvalidArgumentException", "-[Vinyl.Turntable delegate]: unrecognized selector sent to instance 0x7fa8c3017380"
(
    0   CoreFoundation                      0x00000001105f80e5 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x000000011006ddeb objc_exception_throw + 48
    2   CoreFoundation                      0x000000011060109d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
    3   CoreFoundation                      0x0000000110547e1a ___forwarding___ + 970
    4   CoreFoundation                      0x00000001105479c8 _CF_forwarding_prep_0 + 120
    5   LineupTests                         0x000000011a4dcd0d _TFC11LineupTests11LineupTests9testVinylfT_T_ + 269
    6   LineupTests                         0x000000011a4dce32 _TToFC11LineupTests11LineupTests9testVinylfT_T_ + 34
    7   CoreFoundation                      0x00000001104e16ec __invoking___ + 140
    8   CoreFoundation                      0x00000001104e153e -[NSInvocation invoke] + 286
    9   XCTest                              0x000000010fb28eab __24-[XCTestCase invokeTest]_block_invoke_2 + 362
    10  XCTest                              0x000000010fb5c34d -[XCTestContext performInScope:] + 190
    11  XCTest                              0x000000010fb28d30 -[XCTestCase invokeTest] + 169
    12  XCTest                              0x000000010fb2935a -[XCTestCase performTest:] + 459
    13  XCTest                              0x000000010fb2636f -[XCTestSuite performTest:] + 396
    14  XCTest                              0x000000010fb2636f -[XCTestSuite performTest:] + 396
    15  XCTest                              0x000000010fb13180 __25-[XCTestDriver _runSuite]_block_invoke + 51
    16  XCTest                              0x000000010fb34ad8 -[XCTestObservationCenter _observeTestExecutionForBlock:] + 640
    17  XCTest                              0x000000010fb130c5 -[XCTestDriver _runSuite] + 453
    18  XCTest                              0x000000010fb13e41 -[XCTestDriver _checkForTestManager] + 259
    19  XCTest                              0x000000010fb5d6b8 _XCTestMain + 628
    20  xctest                              0x000000010fa9d613 xctest + 5651
    21  libdyld.dylib                       0x0000000112ed59e9 start + 1
    22  ???                                 0x0000000000000005 0x0 + 5
)

In case it helps with the trouble-shooting. The entire source can be found here on the vinyl branch.

Suggestions on what I am doing wrong?

Adding this in the Turntable fixes it:

    public override var delegate: NSURLSessionDelegate? {
        return nil
    }

I am just unsure if this is enough to fix your issue.

@RLovelett would you mind trying this #58.

That did fix the crash. Thank you.

Though I suppose I'm a little perplexed by what I am actually supposed to be sending to the Alamofire.Manager constructor.

let turntable = Turntable(vinylName: "vinyl_single", delegateQueue: NSOperationQueue.mainQueue())
print(turntable.delegate)
let manager = Alamofire.Manager(session: turntable, delegate: turntable.delegate)

turntable.delegate does not work because turntable.delegate is of type NSURLSessionDelegate? but the Alamofire.Manager constructor requires Alamofire.Manager.SessionDelegate. What is more the constructor has the requirement guard delegate === session.delegate else { return nil }.

That leads me to believe I need to set the Turntable delegate to be an instance of Alamofire.Manager.SessionDelegate. But I cannot do that either since Turnable.delegate is a get-only property.

Help?

I think it would be ok, if you would just pass a SessionDelegate().

Sure passing SessionDelegate() will compile. However it still will not work.

Allow me to explain.

let turntable = Turntable(vinylName: "vinyl_single")
let manager = Alamofire.Manager(session: turntable, delegate: Alamofire.Manager.SessionDelegate())

It should be noted that this form of the Alamofire.Manager initializer is fail-able. This is important because it checks that session delegate (e.g., turntable.delegate) is the same as the delegate provided as an argument.

Which of course will never be true (i.e., nil != SessionDelegate()) therefore you can never initialize an instance of the Alamofire.Manager this way.

I've started a work around to this issue in a branch. You can see it here.

Basically, it allows you to provide the delegate as an argument to the Turntable constructor.

Anyways we can close this issue. The problem that I initially reported is solved. Once I get a solution for the other problem I'll submit a pull request.

Thanks for the help!

👍 thanks @RLovelett