Skip to main content

Work in progress

Swift is not up to date with the core documentation. Some of the features you've seen described in other parts of the documentation might not be mentioned here. Those changes do not influence compatibility, however

Overview

Inboxes are a secure way for assigned members to receive encrypted inbound traffic from public sources. Inbox is a container, which is designed to be accessed only by the assigned users. It is managed similarly as Threads and Stores. However, writing to an Inbox is possible with public API, which doesn't require writer registration and access specification.

Info

Before working with Inboxes, follow our Getting Started Guide. It will show you how to set up your project to work with PrivMX Bridge.

The sample code on this page is based on the initial assumptions.

All policies in the following examples can be build with Policy Builders, according to Policies overview.

publicMeta and privateMeta fields in Inboxes support any kind of data formats encoded to byte arrays. Examples in this section use JSON format serialization, which is available directly in Swift.

Working with Inboxes

To access Inbox methods, get the field inboxApi from active connection. Connection should be initialized with [.inbox] and passed to PrivmxEndpoint.

guard let endpointSession =
try? await endpointContainer?.newEndpoint(
enabling: [.inbox],
connectingAs: USER1_PRIVATE_KEY,
to: SOLUTION_ID,
on: BRIDGE_URL ) else {return}
endpointSession.inboxApi // instance of InboxApi

Public session

Public submissions require using newPublicEndpoint function, provided by the EndpointContainer class, to establish a public connection to the Platform. After connecting, create an InboxApi instance, which allows to operate on Inboxes.

guard let publicEndpointSession =
try? await endpointContainer?.newPublicEndpoint(
enabling: [.inbox],
to: SOLUTION_ID,
on: BRIDGE_URL ) else {return}
publicEndpointSession.inboxApi // instance of Public InboxApi

Alternatively You can init publicInboxApi by:

guard var publicConnection =
try? Connection.connectPublic(
to: SOLUTION_ID,
on: BRIDGE_URL) as? Connection

else {return}

guard var publicStoreApi =
try? StoreApi.create(
connection: &publicConnection) else {return}
guard var publicThreadApi =
try? ThreadApi.create(
connection: &publicConnection) else {return}
guard let publicInboxApi =
try? InboxApi.create(
connection: &publicConnection,
threadApi: &publicThreadApi,
storeApi: &publicStoreApi) else {return}

Getting Public View

Users with public connection have access to the Public View which shares not encrypted fields of the Inbox, such as publicMeta.

    let inboxID = "INBOX_ID" 
guard let inboxPublicView = try? publicEndpointSession?.inboxApi?.getInboxPublicView(for: inboxID) else {return}
guard let inboxPublicMetaData = inboxPublicView.publicMeta.getData() else {return}
let inboxPublicMetaDecoded = try? JSONDecoder().decode(InboxPublicMeta.self, from: inboxPublicMetaData)

Assumptions

We use some structures in following examples:

struct InboxPublicMeta:Codable{
let tags: [String]
//definition by developer
}

Creating Inboxes

Creating a basic, unnamed Inbox, which can act as an encrypted data container:

 let users = [privmx.endpoint.core.UserWithPubKey]() //should be prepared by developer
let managers = [privmx.endpoint.core.UserWithPubKey]() //should be prepared by developer
let publicMeta = Data()
let privateMeta = Data()

let inboxId = try? endpointSession?.inboxApi?.createInbox(
in: contextId,
for: users,
managedBy: managers,
withPublicMeta: publicMeta,
withPrivateMeta: privateMeta,
withFilesConfig: nil,
withPolicies: nil
)

Getting Inboxes

Fetching the most recent Inboxes in given Context:

let startIndex:Int64 = 0
let pageSize:Int64 = 100

guard let pagingList = try? endpointSession?.inboxApi?
.listInboxes(
from:contextId,
basedOn: .init(skip: startIndex, limit: pageSize, sortOrder: .desc)) else {return}

let inboxes = pagingList.readItems.map { $0 }

Managing Inboxes

To update an Inbox you must always provide its current version, as well as:

  • list of users
  • list of managers
  • new private and public meta (even if it didn't change)
  • Inbox's current version
  • Inbox FilesConfig
  • true if update action should be forced
let inboxId = "INBOX_ID"
let inboxPublicMeta = InboxPublicMeta(tags: ["TAG1","TAG2","TAG3"])
guard let publicMeta = try? JSONEncoder().encode(inboxPublicMeta) else {return}
guard let inbox = try? endpointSession?.inboxApi?
.getInbox(inboxId) else {return}

//users list to be extracted from inbox
let users = inbox.users.map{
//Your application must provide a way,
//to get user's public key from their userId.
privmx.endpoint.core.UserWithPubKey(userId: $0, pubKey: "PUB")
}
//managers list to be extracted from inbox
let managers = inbox.managers.map{
//Your application must provide a way,
//to get user's public key from their userId.
privmx.endpoint.core.UserWithPubKey(userId: $0, pubKey: "PUB")
}

guard let newPrivateMeta = "New Inbox name".data(using: .utf8) else {return}
guard let filesConfig:privmx.endpoint.inbox.FilesConfig = inbox.filesConfig.value else {return}

_ = try? endpointSession?.inboxApi?.updateInbox(
inboxId,
replacingUsers: users,
replacingManagers: managers,
replacingPublicMeta: inbox.publicMeta.getData() ?? Data(),
replacingPrivateMeta: newPrivateMeta,
replacingFilesConfig: filesConfig,
atVersion: inbox.version,
force:false,
forceGenerateNewKey: false,
replacingPolicies:nil)