Skip to content

Commit 5cd469c

Browse files
committed
Make working with presence channels much clearer by:
* big update to presence channel section of docs * add findPresence function to PusherPresenceChannel class
1 parent 4699a60 commit 5cd469c

File tree

4 files changed

+122
-10
lines changed

4 files changed

+122
-10
lines changed

README.md

Lines changed: 94 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -467,30 +467,30 @@ PusherChannel *myPrivateChannel = [pusher subscribeWithChannelName:@"private-my-
467467
468468
### Presence channels
469469
470-
Presence channels are created in exactly the same way as private channels, except that they reside in the 'presence-' namespace.
470+
Presence channels are channels whose names are prefixed by `presence-`.
471+
472+
The recommended way of subscribing to a presence channel is to use the `subscribeToPresenceChannel` function, as opposed to the standard `subscribe` function. Using the `subscribeToPresenceChannel` function means that you get a `PusherPresenceChannel` object returned, as opposed to a standard `PusherChannel`. This `PusherPresenceChannel` object has some extra, presence-channel-specific functions availalbe to it, such as `members`, `me`, and `findMember`.
471473
472474
#### Swift
473475
```swift
474-
let myPresenceChannel = pusher.subscribe("presence-my-channel")
476+
let myPresenceChannel = pusher.subscribeToPresenceChannel(channelName: "presence-my-channel")
475477
```
476478

477479
#### Objective-C
478480
```objc
479-
PusherChannel *myPresenceChannel = [pusher subscribeWithChannelName:@"presence-my-channel"];
481+
PusherPresenceChannel *myPresenceChannel = [pusher subscribeToPresenceChannelWithChannelName:@"presence-my-channel"];
480482
```
481483
482-
This will give you back a `PusherChannel` object, which will not have access to functions available to `PusherPresenceChannel` objects, such as `members`, `me` etc.
483-
484-
You can of course cast the `PusherChannel` object to a `PusherPresenceChannel` or you can instead use the `subscribeToPresenceChannel` function which will directly return a `PusherPresenceChannel` object. You can do so like this:
484+
As alluded to, you can still subscribe to presence channels using the `subscribe` method, but the channel object you get back won't have access to the presence-channel-specific functions, unless you choose to cast the channel object to a `PusherPresenceChannel`.
485485
486486
#### Swift
487487
```swift
488-
let myPresenceChannel = pusher.subscribeToPresenceChannel(channelName: "presence-my-channel")
488+
let myPresenceChannel = pusher.subscribe("presence-my-channel")
489489
```
490490

491491
#### Objective-C
492492
```objc
493-
PusherPresenceChannel *myPresenceChannel = [pusher subscribeToPresenceChannelWithChannelName:@"presence-my-channel"];
493+
PusherChannel *myPresenceChannel = [pusher subscribeWithChannelName:@"presence-my-channel"];
494494
```
495495
496496
You can also provide functions that will be called when members are either added to or removed from the channel. These are available as parameters to both `subscribe` and `subscribeToPresenceChannel`.
@@ -500,13 +500,98 @@ You can also provide functions that will be called when members are either added
500500
let onMemberChange = { (member: PusherPresenceChannelMember) in
501501
print(member)
502502
}
503-
let chan = pusher.subscribe("presence-channel", onMemberAdded: onMemberChange, onMemberRemoved: onMemberChange)
503+
504+
let chan = pusher.subscribeToPresenceChannel("presence-channel", onMemberAdded: onMemberChange, onMemberRemoved: onMemberChange)
505+
```
506+
507+
#### Objective-C
508+
```objc
509+
void (^onMemberChange)(PusherPresenceChannelMember*) = ^void (PusherPresenceChannelMember *member) {
510+
NSLog(@"%@", member);
511+
};
512+
513+
PusherChannel *myPresenceChannel = [pusher subscribeWithChannelName:@"presence-my-channel" onMemberAdded:onMemberChange onMemberRemoved:onMemberChange];
514+
```
515+
516+
**Note**: The `members` and `myId` properties of `PusherPresenceChannel` objects (and functions that get the value of these properties) will only be set once subscription to the channel has succeeded.
517+
518+
The easiest way to find out when a channel has been successfully susbcribed to is to bind to the event named `pusher:subscription_succeeded` on the channel you're interested in. It would look something like this:
519+
520+
#### Swift
521+
```swift
522+
let pusher = Pusher(key: "YOUR_APP_KEY")
523+
524+
let chan = pusher.subscribeToPresenceChannel("presence-channel")
525+
526+
let _ = chan.bind(eventName: "pusher:subscription_succeeded", callback: { data in
527+
print("Subscribed!")
528+
print("I can now access myId: \(chan.myId)")
529+
print("And here are the channel members: \(chan.members)")
530+
})
531+
```
532+
533+
#### Objective-C
534+
```objc
535+
Pusher *pusher = [[Pusher alloc] initWithAppKey:@"YOUR_APP_KEY"];
536+
PusherPresenceChannel *chan = [pusher subscribeToPresenceChannelWithChannelName:@"presence-channel"];
537+
538+
[chan bindWithEventName:@"pusher:subscription_succeeded" callback: ^void (NSDictionary *data) {
539+
NSLog(@"Subscribed!");
540+
NSLog(@"I can now access myId: %@", chan.myId);
541+
NSLog(@"And here are my channel members: %@", chan.members);
542+
}];
543+
```
544+
545+
You can also be notified of a successfull subscription by using the `subscriptionDidSucceed` delegate method on the `PusherConnection` object.
546+
547+
Here is an example of using the connection delegate:
548+
549+
#### Swift
550+
```swift
551+
class DummyDelegate: PusherConnectionDelegate {
552+
func subscriptionDidSucceed(channelName: String) {
553+
if channelName == "presence-channel" {
554+
if let presChan = pusher.connection.channels.findPresence(channelName) {
555+
// in here you can now have access to the channel's members and myId properties
556+
print(presChan.members)
557+
print(presChan.myId)
558+
}
559+
}
560+
}
561+
}
562+
563+
let pusher = Pusher(key: "YOUR_APP_KEY")
564+
pusher.connection.delegate = DummyDelegate()
565+
let chan = pusher.subscribeToPresenceChannel("presence-channel")
566+
```
567+
568+
#### Objective-C
569+
```objc
570+
@implementation DummyDelegate
571+
572+
- (void)subscriptionDidSucceedWithChannelName:(NSString *)channelName {
573+
if ([channelName isEqual: @"presence-channel"]) {
574+
PusherPresenceChannel *presChan = [self.client.connection.channels findPresenceWithName:@"presence-channel"];
575+
NSLog(@"%@", [presChan members]);
576+
NSLog(@"%@", [presChan myId]);
577+
}
578+
}
579+
580+
@implementation ViewController
581+
582+
- (void)viewDidLoad {
583+
// ...
584+
585+
Pusher *pusher = [[Pusher alloc] initWithAppKey:@"YOUR_APP_KEY"];
586+
pusher.connection.delegate = [[DummyDelegate alloc] init];
587+
PusherChannel *chan = [pusher subscribeToPresenceChannelWithChannelName:@"presence-channel"];
504588
```
505589
506590
Note that both private and presence channels require the user to be authenticated in order to subscribe to the channel. This authentication can either happen inside the library, if you configured your Pusher object with your app's secret, or an authentication request is made to an authentication endpoint that you provide, again when instantiaing your Pusher object.
507591
508592
We recommend that you use an authentication endpoint over including your app's secret in your app in the vast majority of use cases. If you are completely certain that there's no risk to you including your app's secret in your app, for example if your app is just for internal use at your company, then it can make things easier than setting up an authentication endpoint.
509593
594+
510595
## Binding to events
511596
512597
Events can be bound to at 2 levels; globally and per channel. When binding to an event you can choose to save the return value, which is a unique identifier for the event handler that gets created. The only reason to save this is if you're going to want to unbind from the event at a later point in time. There is an example of this below.

Source/PusherChannels.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,16 @@ open class PusherChannels: NSObject {
9797
public func find(name: String) -> PusherChannel? {
9898
return self.channels[name]
9999
}
100+
101+
/**
102+
Return the PusherPresenceChannel with the given channelName from the channels list, if it exists
103+
104+
- parameter name: The name of the presence channel to return
105+
106+
- returns: A PusherPresenceChannel instance, if a channel with the given name existed,
107+
otherwise nil
108+
*/
109+
public func findPresence(name: String) -> PusherPresenceChannel? {
110+
return self.channels[name] as? PusherPresenceChannel
111+
}
100112
}

Tests/PresenceChannelTests.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,21 @@ class PusherPresenceChannelTests: XCTestCase {
8383
XCTAssertEqual(me!.userInfo as! [String: Int], ["friends": 0], "the userInfo should be [\"friends\": 0]")
8484
}
8585

86+
func testFindingAPresenceChannelAsAPusherPresenceChannel() {
87+
pusher.connection.userDataFetcher = { () -> PusherPresenceChannelMember in
88+
return PusherPresenceChannelMember(userId: "123", userInfo: ["friends": 0])
89+
}
90+
91+
pusher.connect()
92+
93+
let _ = pusher.subscribe("presence-channel")
94+
95+
let presChan = pusher.connection.channels.findPresence(name: "presence-channel")
96+
97+
XCTAssertNotNil(presChan, "the presence channel should be found and returned")
98+
XCTAssertEqual(presChan?.me()?.userId, "123", "the userId of the client's member object should be 123")
99+
}
100+
86101
func testOnMemberAddedFunctionGetsCalledWhenANewSubscriptionSucceeds() {
87102
let options = PusherClientOptions(
88103
authMethod: .inline(secret: "secretsecretsecretsecret")

iOS Example Swift/iOS Example Swift/ViewController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class ViewController: UIViewController, PusherConnectionDelegate {
4646

4747
let chan = pusher.subscribe("presence-channel", onMemberAdded: onMemberAdded)
4848

49-
let _ = chan.bind(eventName: "test-event", callback: { (data: Any?) -> Void in
49+
let _ = chan.bind(eventName: "test-event", callback: { data in
5050
print(data)
5151
let _ = self.pusher.subscribe("presence-channel", onMemberAdded: onMemberAdded)
5252

0 commit comments

Comments
 (0)