lukeredpath/libPusher — pull request #108 by fillito (2013-08-03 17:31:37+00:00)
Title: check isConnected before sending Event

We have discussed this issue before on this pull request thread https://github.com/lukeredpath/libPusher/pull/104

I found that I shouldn't call to unsubscribe on applicationDidEnterBackground because the connection to pusher was already closed and this would cause an exception while sending the unsubscribe event.

I avoided to do that, but I've found that connection to pusher may get closed by other different reasons during the application execution. If I try to unsubscribe from a channel and the connection was already closed or interrupted, PTPusher class don't make any check to ensure that the connection is available.
So, in may opinion, this means that PTPusher is breaking the contract with PTPusherConnection and causing an exception.

Here is a crash log where it occurs

Date/Time: 2013-08-02 23:08:00.000 +0200
OS Version: iPhone OS 6.1.3 (10B329)
Report Version: 104

Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x00000000 at 0x00000000
Crashed Thread: 0

Application Specific Information:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Cannot send data unless connected.'

Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 CoreFoundation 0x342a32a3 __exceptionPreprocess + 163
1 libobjc.A.dylib 0x3bf4897f objc_exception_throw + 31
2 CoreFoundation 0x342a315d +[NSException raise:format:] + 1
3 Foundation 0x34b78ab7 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 91
4 Caoba beta 0x00259d5f -[PTPusherConnection send:] (PTPusherConnection.m:89)
5 Caoba beta 0x0025352f -[PTPusher sendEventNamed:data:channel:] (PTPusher.m:259)
6 Caoba beta 0x0025328b -[PTPusher sendEventNamed:data:] (PTPusher.m:243)
7 Caoba beta 0x00252c8f -[PTPusher __unsubscribeFromChannel:] (PTPusher.m:202)
8 Caoba beta 0x00256ac3 -[PTPusherChannel unsubscribe] (PTPusherChannel.m:193)
9 Caoba beta 0x00130e77 -[InteractionsDetailViewController dealloc] (InteractionsDetailViewController.m:1469)
10 libobjc.A.dylib 0x3bf45489 (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 169
11 CoreFoundation 0x341e6441 _CFAutoreleasePoolPop + 17
12 Foundation 0x34b0b01d -[NSAutoreleasePool release] + 121
13 UIKit 0x360ab49f _UIApplicationHandleEvent + 7055
14 GraphicsServices 0x37dae5a3 _PurpleEventCallback + 591
15 CoreFoundation 0x34278683 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
16 CoreFoundation 0x34277f7f __CFRunLoopDoSources0 + 363
17 CoreFoundation 0x34276cb7 __CFRunLoopRun + 647
18 CoreFoundation 0x341e9ebd CFRunLoopRunSpecific + 357
19 CoreFoundation 0x341e9d49 CFRunLoopRunInMode + 105
20 GraphicsServices 0x37dad2eb GSEventRunModal + 75
21 UIKit 0x360ff301 UIApplicationMain + 1121
22 Caoba beta 0x0006672d main (main.m:16)
23 libdyld.dylib 0x3c37fb20 start + 0

I'm not sure if this would be the ideal solution to avoid this problem...

What whould be the best way to do this without checking the connection isConnected property there ?

Thanks !