Skip to content

Commit 3a6a722

Browse files
Tutorial changes
1 parent f4314df commit 3a6a722

File tree

3 files changed

+26
-161
lines changed

3 files changed

+26
-161
lines changed

Getting Started Swift Chat/Views/ContentView.swift

Lines changed: 22 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -57,29 +57,19 @@ struct ContentView: View {
5757

5858
func applicationBroughtToForeground(viewModel: ChatViewModel)
5959
{
60-
// Subscribe
61-
viewModel.pubnub?.subscribe(to: [groupChatChannel], withPresence: true)
60+
// TUTORIAL: STEP 2B CODE GOES HERE (1/2)
61+
62+
// TUTORIAL: STEP 2D CODE IS ALREADY PRESENT HERE AS CONTAINS GLUE CODE
6263

63-
// Applications receive various types of information from PubNub through a 'listener'
64-
// This application dynamically registers an listener when it is in the foreground
6564
viewModel.listener = SubscriptionListener()
6665
viewModel.listener?.didReceiveSubscription = {
6766
event in
6867
switch event {
6968
case let .messageReceived(message):
69+
70+
// TUTORIAL: STEP 2E CODE GOES HERE
7071

71-
let messageText: String = message.payload.stringOptional ?? ""
72-
let sender: String = message.publisher ?? ""
73-
74-
var newMsg = Message(message: messageText, senderDeviceId: sender, timetoken: String(message.published))
75-
let dateFormatter = DateFormatter()
76-
dateFormatter.timeStyle = DateFormatter.Style.medium
77-
dateFormatter.dateStyle = DateFormatter.Style.medium
78-
dateFormatter.timeZone = .current
79-
let secsSince1970: Double = message.published.timetokenDate.timeIntervalSince1970
80-
newMsg.humanReadableTime = dateFormatter.string(from: Date(timeIntervalSince1970: secsSince1970))
81-
82-
viewModel.messages.append(newMsg)
72+
break;
8373

8474
// Status events are commonly used to notify the application that a previous PubNub call has succeeded
8575
// Not all PubNub calls return their status in this manner but is used in this app to ensure
@@ -101,69 +91,18 @@ struct ContentView: View {
10191
}
10292
}
10393

104-
// When the application is first loaded, it is common to load any recent chat messages
105-
// so the user can get caught up with conversations they missed.
106-
// Every application will handle this differently but here we just load the most recent
107-
// messages
108-
viewModel.pubnub?.fetchMessageHistory(for: [groupChatChannel], includeMeta: true, includeUUID: true, page: PubNubBoundedPageBase(limit: 8)) { result in
109-
switch result {
110-
case let .success(response):
111-
if let myChannelMessages = response.messagesByChannel[groupChatChannel] {
112-
myChannelMessages.forEach { historicalMessage in
113-
// Recreate the message and add it to the viewModel for display.
114-
var newMsg = Message()
115-
newMsg.message = historicalMessage.payload.stringOptional ?? "Not found"
116-
newMsg.senderDeviceId = historicalMessage.publisher?.stringOptional ?? "Unknown"
117-
newMsg.timetoken = String(historicalMessage.published)
118-
let dateFormatter = DateFormatter()
119-
dateFormatter.timeStyle = DateFormatter.Style.medium
120-
dateFormatter.dateStyle = DateFormatter.Style.medium
121-
dateFormatter.timeZone = .current
122-
let secsSince1970: Double = historicalMessage.published.timetokenDate.timeIntervalSince1970
123-
newMsg.humanReadableTime = dateFormatter.string(from: Date(timeIntervalSince1970: secsSince1970))
124-
viewModel.messages.append(newMsg)
125-
126-
lookupMemberName(deviceId: newMsg.senderDeviceId)
127-
}
128-
}
129-
case let .failure(error):
130-
print("Failed to retrieve history: \(error.localizedDescription)")
131-
}
132-
}
94+
// TUTORIAL: STEP 2G CODE GOES HERE
95+
13396
}
13497

13598
// Be notified that a 'presence' event has occurred. I.e. somebody has left or joined
13699
// the channel. This is similar to the earlier hereNow call but this API will only be
137100
// invoked when presence information changes, meaning you do NOT have to call hereNow
138101
// periodically. More info: https://www.pubnub.com/docs/sdks/swift/api-reference/presence
139102
case let .presenceChanged(presence):
140-
// A note about ANNOUNCE_MAX:
141-
// There is a server setting, ANNOUNCE_MAX, that you can configure on your keyset. This
142-
// defaults to 20 users and after this number of attendees join each channel, presence
143-
// events are only sent periodically every x seconds, where x is also configured on the keyset.
144-
// More info: https://www.pubnub.com/docs/presence/presence-events#interval-mode
145-
// Since this application needs to know which UUIDs have joined or left since the last update,
146-
// YOU NEED TO SET 'Presence Deltas' to true on the keyset, if you have more than ANNOUNCE_MAX
147-
// users, using this app.
148-
for action in presence.actions {
149-
switch action {
150-
case let .join(uuids):
151-
uuids.forEach { deviceId in
152-
addMember(deviceId: deviceId)
153-
}
154-
break;
155-
case let .leave(uuids):
156-
uuids.forEach { deviceId in
157-
removeMember(deviceId: deviceId)
158-
}
159-
break;
160-
case .timeout(_):
161-
print("Presence - timeout")
162-
break;
163-
case let .stateChange(uuid, state):
164-
print("\(uuid) changed their presence state to \(state) at \(presence.timetoken)")
165-
}
166-
}
103+
104+
// TUTORIAL: STEP 2F CODE GOES HERE (1/2)
105+
break;
167106
case let .subscribeError(error):
168107
print("Subscription Error \(error)")
169108
default:
@@ -185,19 +124,9 @@ struct ContentView: View {
185124
viewModel.objectsListener?.didReceiveObjectMetadataEvent = { event in
186125
switch event {
187126
case .setUUID(let metadata):
188-
let changedId: String = metadata.metadataId;
189-
for change in metadata.changes {
190-
switch change {
191-
case let .stringOptional(_, value):
192-
let changedValue: String = value?.stringOptional ?? changedId
193-
replaceMemberName (
194-
deviceId: changedId, newName: changedValue
195-
)
196-
case .customOptional(_, _):
197-
// No action
198-
break;
199-
}
200-
}
127+
128+
// TUTORIAL: STEP 2I CODE GOES HERE (2/2)
129+
201130
break;
202131
default:
203132
break
@@ -216,24 +145,7 @@ struct ContentView: View {
216145
// I am definitely here(!)
217146
addMember(deviceId: viewModel.deviceId ?? "defaultId")
218147

219-
// PubNub has an API to determine who is in the room. Use this call sparingly since
220-
// you are only ever likely to need to know EVERYONE in the room when the UI is first
221-
// created.
222-
viewModel.pubnub?.hereNow(on: [groupChatChannel], includeUUIDs: true) {result in
223-
switch result {
224-
case let .success(presenceByChannel):
225-
if let myChannelPresence = presenceByChannel[groupChatChannel] {
226-
// The API will return an array of occupants in the channel, defined by
227-
// their ID. This application will need to look up the friendly name
228-
// defined for each of these IDs (later)
229-
myChannelPresence.occupants.forEach { member in
230-
addMember(deviceId: member)
231-
}
232-
}
233-
case let .failure(error):
234-
print("Failed hereNow Response: \(error)")
235-
}
236-
}
148+
// TUTORIAL: STEP 2F CODE GOES HERE (2/2)
237149

238150
}
239151

@@ -243,7 +155,9 @@ struct ContentView: View {
243155
// when the app goes into the background. This is good to show the principles
244156
// of presence but you don't need to do this in a production app if it
245157
// does not fit your use case.
246-
viewModel.pubnub?.unsubscribe(from: [groupChatChannel]);
158+
159+
// TUTORIAL: STEP 2B CODE GOES HERE (2/2)
160+
247161
viewModel.listener?.cancel()
248162
viewModel.objectsListener?.cancel()
249163
}
@@ -263,20 +177,8 @@ struct ContentView: View {
263177
return;
264178
}
265179

266-
// Create a device-specific DeviceId to represent this device and user, so PubNub
267-
// knows who is connecting.
268-
// More info: https://support.pubnub.com/hc/en-us/articles/360051496532-How-do-I-set-the-UUID-
269-
// All iOS IDs are user-resettable but are still appropriate for use here.
270-
let deviceId = UIDevice.current.identifierForVendor?.uuidString ?? "defaultId"
271-
272-
// Create a PubNub configuration and instantiate the PubNub object, used to
273-
// communicate with PubNub
274-
let config = PubNubConfiguration (
275-
publishKey: publish_key, subscribeKey: subscribe_key, userId: deviceId
276-
)
180+
// TUTORIAL: STEP 2A CODE GOES HERE
277181

278-
// Application state
279-
viewModel.pubnub = PubNub(configuration: config)
280182
viewModel.deviceId = deviceId
281183
viewModel.channel = groupChatChannel
282184
viewModel.friendlyName = deviceId
@@ -317,21 +219,9 @@ struct ContentView: View {
317219
// We already know the member name, take no action
318220
}
319221
else{
320-
// Resolve the friendly name of the deviceId
321-
viewModel.pubnub?.fetch(uuid: deviceId) { result in
322-
switch result {
323-
case let .success(uuidMetadata):
324-
// Add the user's name to the memberNames dictionary (part of the viewModel, so
325-
// the UI will update accordingly)
326-
viewModel.memberNames[deviceId] = uuidMetadata.name
327-
// Set our own friendly name (stored separately to make the UI logic easier)
328-
if (deviceId == viewModel.deviceId) {
329-
viewModel.friendlyName = uuidMetadata.name ?? "default name"
330-
}
331-
case .failure(_):
332-
print("Could not find friendly name for device: " + deviceId)
333-
}
334-
}
222+
223+
// TUTORIAL: STEP 2I CODE GOES HERE (1/2)
224+
335225
}
336226
}
337227

Getting Started Swift Chat/Views/HeaderView.swift

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -66,21 +66,8 @@ struct Header: View {
6666
viewModel.friendlyName = "default"
6767
}
6868

69-
// Mapping of device ID to friendly name. Master record is PubNub
70-
// object storage
71-
// See: https://www.pubnub.com/docs/sdks/swift/api-reference/objects
72-
let uuidMetaData = PubNubUUIDMetadataBase(
73-
metadataId: viewModel.deviceId ?? "defaultValue",
74-
name: viewModel.friendlyName
75-
)
76-
viewModel.pubnub?.set(uuid: uuidMetaData) { result in
77-
switch result {
78-
case .success(_):
79-
print("Metadata successfully set")
80-
case let .failure(error):
81-
print("Create UUID meta data failed with error: \(error)")
82-
}
83-
}
69+
// TUTORIAL: STEP 2H CODE GOES HERE
70+
8471
}
8572
}.padding(3).background(RoundedRectangle(cornerRadius: 8).fill(Color.white))
8673
}

Getting Started Swift Chat/Views/MessageInput.swift

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,8 @@ struct MessageInput: View {
2323
return;
2424
}
2525

26-
// Publish message to PubNub using the pre-defined channel for this group chat
27-
viewModel.pubnub?.publish(
28-
channel: viewModel.channel ?? "default_channel",
29-
message: messageText,
30-
shouldStore: true
31-
) { result in
32-
switch result {
33-
case .success(_):
34-
// Message successfully sent
35-
break;
36-
case let .failure(error):
37-
print("publish failed: \(error.localizedDescription)")
38-
}
39-
}
26+
// TUTORIAL: STEP 2C CODE GOES HERE
27+
4028
messageText = ""
4129
}
4230
}.padding()

0 commit comments

Comments
 (0)