SwiftSwift Native SDK 3.1.0

 
The PubNub Swift 3.0 SDK contains many significant changes from the 2.x SDK, including breaking changes. Please refer to the PubNub Swift 3.0 Migration Guide for more details.

The Swift Package Manager is a tool for managing the distribution of Swift code. It’s integrated with the Swift build system to automate the process of downloading, compiling, and linking dependencies. To integrate PubNub into your Xcode project using Swift Package Manager, specify it in the dependencies list of your Package.swift file:

dependencies: [
  .package(url: "https://github.com/pubnub/swift.git", from: "3.1.0")
]

To integrate PubNub into your Xcode project using Embedded Framework, do the following:

  1. In your top-level project directory add PubNub as a submodule:
    git submodule add https://github.com/pubnub/swift.git
  2. Open your app’s Xcode project.
  3. In Finder, locate the PubNub.xcodeproj Xcode project inside the submodule directory, and drag it onto your app's project in the Project Navigator.

    PubNub.xcodeproj

    This nests a reference to the framework project in the app project.

  4. Select your applications's project in the Project Navigator (blue project icon), navigate to the target configuration window, and select the application target under the "Targets" heading in the sidebar.
  5. Select your application project in the Project Navigator, and then select your application's Target under the TARGETS panel.
  6. Select the General tab in the top middle of the window, and then click the + inside the EMBEDDED BINARIES section.
  7. Select the PubNub.framework nested inside the top-most PubNub.xcodeproj/Products/ directory.

For more information see Apple's guide on Adding Package Dependencies to Your App

CocoaPods is a dependency manager and is by far the easiest and quickest way to get started with the PubNub Swift SDK! (If you don't have CocoaPods installed yet, follow the installation instructions in the CocoaPods documentation.)

To integrate PubNub into your Xcode project using CocoaPods, specify it in your Podfile:

pod 'PubNubSwift', '~> 3.0'

Carthage builds your dependencies and provides you with binary frameworks, but you retain full control over your project structure and setup. Carthage doesn't automatically modify your project files or your build settings. To integrate PubNub into your Xcode project using Carthage, specify it in your Cartfile:

github "pubnub/swift" ~> 3.1.0


To add the PubNub SDK to your project with Swift Package Manager, do the following:
  1. Create a new Xcode project.
    Create the project as a Single View App, using a Storyboard user interface.

    Xcode project setup
  2. Navigate to File > Swift Packages > Add Package Dependency.
  3. Search for PubNub and select the swift package owned by pubnub, and click Next.
  4. Use the Up to Next Major Version rule spanning from 3.0.0 < 4.0.0, and click Next.
  5. Import the module named PubNub inside your AppDelegate:

    import UIKit
    import PubNub // <- Here is our PubNub module import.
  6. Create a PubNub object and pass it to your root view controller:

     Always set the UUID to uniquely identify the user or device that connects to PubNub. This UUID should be persisted, and should remain unchanged for the lifetime of the user or the device. Not setting the UUID can significantly impact your billing if your account uses the Monthly Active Users (MAUs) based pricing model, and can also lead to unexpected behavior if you have Presence enabled.
    import UIKit
    import PubNub
    
    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
    
      var pubnub: PubNub!
      var window: UIWindow?
    
      func application(_ application: UIApplication,
                      willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        PubNub.log.levels = [.all]
        PubNub.log.writers = [ConsoleLogWriter(), FileLogWriter()]
    
        var config = PubNubConfiguration(publishKey: "demo", subscribeKey: "demo")
        pubnub = PubNub(configuration: config)
    
        if #available(iOS 13.0, *) {
          // no-op - UI created in scene delegate
        } else if let rootVC = self.window?.rootViewController as? ViewController {
          rootVC.pubnub = pubnub
        }
    
        return true
      }
    
      // MARK: UISceneSession Lifecycle
    
      @available(iOS 13.0, *)
      func application(_ application: UIApplication,
                      configurationForConnecting connectingSceneSession: UISceneSession,
                      options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
      }
    
      @available(iOS 13.0, *)
      func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
        // no-op
      }
    }
  7. If using multiple Scenes, use the SceneDelegate to pass your PubNub instance to your view controllers:

     Always set the UUID to uniquely identify the user or device that connects to PubNub. This UUID should be persisted, and should remain unchanged for the lifetime of the user or the device. Not setting the UUID can significantly impact your billing if your account uses the Monthly Active Users (MAUs) based pricing model, and can also lead to unexpected behavior if you have Presence enabled.
    import UIKit
    import PubNub
    
    @available(iOS 13.0, *)
    class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    
      var window: UIWindow?
      var pubnub: PubNub?
    
      func scene(
        _ scene: UIScene,
        willConnectTo session: UISceneSession,
        options connectionOptions: UIScene.ConnectionOptions
      ) {
        guard let windowScence = scene as? UIWindowScene,
            let pubnub = (UIApplication.shared.delegate as? AppDelegate)?.pubnub else { return }
    
        let mainStoryboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    
        let rootVC = mainStoryboard.instantiateInitialViewController() as? ViewController
        rootVC?.pubnub = pubnub
    
        let window = UIWindow(windowScene: windowScence)
        window.rootViewController = rootVC
        window.makeKeyAndVisible()
    
        self.window = window
      }
    }
  8. Finally, set up your root ViewController:

    import UIKit
    import PubNub
    
    class ViewController: UIViewController {
    
      var pubnub: PubNub!
      let channels = ["awesomeChannel"]
      let listener = SubscriptionListener(queue: .main)
    
      override func viewDidLoad() {
        super.viewDidLoad()
    
        listener.didReceiveMessage = { message in
          print("[Message]: \(message)")
        }
        listener.didReceiveStatus = { status in
          switch status {
          case .success(let connection):
            if connection == .connected {
              self.pubnub.publish(channel: self.channels[0], message: "Hello, PubNub Swift!") { result in
                print(result.map { "Publish Response at \($0.timetokenDate)" })
              }
            }
          case .failure(let error):
            print("Status Error: \(error.localizedDescription)")
          }
        }
    
        pubnub.add(listener)
    
        pubnub.subscribe(to: channels, withPresence: true)
      }
    }
In addition to the Hello World sample code, we also provide some copy and paste snippets of common API functions:

Instantiate a new PubNub instance. Only the subscribeKey is mandatory. Also include publishKey if you intend to publish from this instance.

 Always set the UUID to uniquely identify the user or device that connects to PubNub. This UUID should be persisted, and should remain unchanged for the lifetime of the user or the device. Not setting the UUID can significantly impact your billing if your account uses the Monthly Active Users (MAUs) based pricing model, and can also lead to unexpected behavior if you have Presence enabled.
var config = PubNubConfiguration(
  publishKey: "demo",
  subscribeKey: "demo",
  uuid: "myUniqueUUID"
)
let pubnub = PubNub(configuration: config)
// Create a new listener instance
let listener = SubscriptionListener()

// Add listener event callbacks
listener.didReceiveSubscription = { event in
  switch event {
  case let .messageReceived(message):
    print("Message Received: \(message) Publisher: \(message.publisher ?? "defaultUUID")")
  case let .connectionStatusChanged(status):
    print("Status Received: \(status)")
  case let .presenceChanged(presence):
    print("Presence Received: \(presence)")
  case let .subscribeError(error):
    print("Subscription Error \(error)")
  default:
    break
  }
}

// Start receiving subscription events
pubnub.add(listener)
 

You can check the UUID of the publisher of a particular message by checking the message.publisher property in the subscription listener. You must also provide a default value for publisher, as the UUID parameter is optional.

The SubscriptionListener can be removed by either calling listener.cancel(), or by letting it fall out of scope and be removed as an autoreleased object.

This is the list of SubscriptionEvent case types that can be emitted from didReceiveSubscription, or grouped together using didReceiveBatchSubscription. Each event case also has a standalone listener that can save code space, but will be functionally equivalent to using didReceiveSubscription.

SubscriptionEvent CaseEvent TypeStandalone ListenerEvent Description
messageReceivedPubNubMessagedidReceiveMessageMessages sent to subscribed channels/groups
signalReceivedPubNubMessagedidReceiveSignalSignals sent to subscribed channels/groups
connectionStatusChangedConnectionStatusdidReceiveStatusChanges in the connection to the PubNub system
subscriptionChangedSubscriptionChangeEventdidReceiveSubscriptionChangeNotifies when channels/groups are subscribed or unsubscribed
presenceChangedPubNubPresenceChangedidReceivePresencePresence changes on subscribed channels/groups tracking presence
uuidMetadataSetPubNubUUIDMetadataChangesetdidReceiveObjectMetadataEventUUID metadata was set
uuidMetadataRemovedStringdidReceiveObjectMetadataEventUUID metadata was removed
channelMetadataSetPubNubChannelMetadataChangesetdidReceiveObjectMetadataEventChannel metadata was set
channelMetadataRemovedStringdidReceiveObjectMetadataEventChannel metadata was removed
membershipMetadataSetPubNubMembershipMetadatadidReceiveObjectMetadataEventMembership metadata was set
membershipMetadataRemovedPubNubMembershipMetadatadidReceiveObjectMetadataEventMembership metadata was removed
messageActionAddedPubNubMessageActiondidReceiveMessageActionA PubNubMessageAction was added to a published message
messageActionRemovedPubNubMessageActiondidReceiveMessageActionA PubNubMessageAction was removed from a published message
subscribeErrorPubNubErrorsubscribeErrorAny error that might have occurred during the subscription stream
Call pubnub.time to obtain a PubNub Timetoken object:
pubnub.time { result in
  switch result {
  case let .success(timetoken):
    print("Handle downloaded server time token: \(timetoken)")
  case let .failure(error):
    print("Handle response error: \(error.localizedDescription)")
  }
}
pubnub.subscribe(to: ["my_channel"])
The response of the call is handled by adding a Listener. Please see the Listeners section for more details. Listeners should be added before calling the method.
Publish a message to a channel:
pubnub.publish(channel: "my_channel", message: "Test Message!") { result in
  switch result {
  case let .success(timetoken):
    print("The message was successfully published at: \(timetoken)")
  case let .failure(error):
    print("Handle response error: \(error.localizedDescription)")
  }
}
Get occupancy of who's here now on the channel by UUID:
Requires you to enable the Presence add-on for your key. Refer to the How do I enable add-on features for my keys? knowledge base article for details on enabling features.
pubnub.hereNow(on: ["my_channel"]) { result in
  switch result {
  case let .success(presenceByChannel):
    print("Total channels \(presenceByChannel.totalChannels)")
    print("Total occupancy across all channels \(presenceByChannel.totalOccupancy)")
    if let myChannelPresence = presenceByChannel["my_channel"] {
      print("The occupancy for `my_channel` is \(myChannelPresence.occupancy)")
      print("The list of occupants for `my_channel` are \(myChannelPresence.occupants)")
    }
  case let .failure(error):
    print("Failed hereNow Response: \(error.localizedDescription)")
  }
})
Subscribe to realtime Presence events, such as join, leave, and timeout, by UUID. Setting the presence attribute to a callback will subscribe to presents events on my_channel.
Requires you to enable the Presence add-on for your key. Refer to the How do I enable add-on features for my keys? knowledge base article for details on enabling features.
The response of the call is handled by adding a Listener. Please see the Listeners section for more details. Listeners should be added before calling the method.
pubnub.subscribe(
  to: ["my_channel"],
  withPresence: true
)
Requires that the Storage and Playback add-on is enabled for your key. How do I enable add-on features for my keys? - see https://support.pubnub.com/hc/en-us/articles/360051974791-How-do-I-enable-add-on-features-for-my-keys-
Retrieve published messages from archival storage:
pubnub.fetchMessageHistory(for: ["my_channel"]) { result in
  switch result {
  case let .success(messagesByChannelId, nextPage):
    print("Successful History Fetch Response: \(messagesByChannelId)")
    print("The start/end values for the next page: \(nextPage)")
  case let .failure(error):
    print("Failed History Fetch Response: \(error.localizedDescription)")
  }
})
pubnub.unsubscribe(from: ["my_channel"])
The response of the call is handled by adding a Listener. Please see the Listeners section for more details. Listeners should be added before calling the method.