Skip to content

chore: remove many calls to ZMUserSession.shared() - WPB-23738#4373

Open
samwyndham wants to merge 38 commits intodevelopfrom
chore/share-user-session-WPB-23738
Open

chore: remove many calls to ZMUserSession.shared() - WPB-23738#4373
samwyndham wants to merge 38 commits intodevelopfrom
chore/share-user-session-WPB-23738

Conversation

@samwyndham
Copy link
Contributor

@samwyndham samwyndham commented Feb 26, 2026

TaskWPB-23738 [iOS] Remove calls to ZMUserSession.shared() where possible

Issue

This PR removes many calls to the deprecated ZMUserSession.shared().

Before After
Screenshot 2026-02-26 at 13 48 50 Screenshot 2026-02-26 at 13 50 12

I hope this will help lay down some work towards simplifying session management by removing the implicit dependency of SessionManager from many components. (ZMUserSession.shared() uses SessionManager.shared) internally.

I used Claude code to help me here which generally worked well but also made some funny choices that I changed. It also took me longer than I had hoped.

In general I've tried to keep changes to a minimum and to avoid behavior changes. ZMUserSession is has generally be passed through init methods as a UserSession and calls to ZMUserSession.shared() have often been changed to UserSession as? ZMUserSession.

I noticed that a lot of our tests depend on not using a real ZMUserSession which I haven't attempted to fix.

While this PR does get rid of a lot of calls to ZMUserSession.shared() that call is still used by for example ZMUser.selfUser() so may take quite some effort to completely get rid of it.

I recommend checking this PR commit by commit. There are some overly large commits but many are small

Testing

Changes can't really be tested outside a full regression test at least the following should be tested before merge as it

  1. Login with multiple accounts (A + B)

Repeat the following with call kit enabled & disabled and in the foreground, background, and app quit
(6 states).

  1. Ensure account A is seleced
  2. Receive a call to account B
  3. Answer call
  4. Account should switch.

Checklist

  • Title contains a reference JIRA issue number like [WPB-XXX].
  • Description is filled and free of optional paragraphs.
  • Adds/updates automated tests.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 26, 2026

Test Results

1 872 tests   1 845 ✅  2m 7s ⏱️
  301 suites     27 💤
    1 files        0 ❌

Results for commit 91802bd.

♻️ This comment has been updated with latest results.

Summary: workflow run #22569268487
Allure report (download zip): html-report-28223-chore_share-user-session-WPB-23738

# Conflicts:
#	wire-ios/Wire-iOS Tests/MessageReplyPreviewViewTests.swift
@sonarqubecloud
Copy link

sonarqubecloud bot commented Mar 2, 2026

@samwyndham samwyndham requested review from netbe and removed request for jullianm March 2, 2026 15:29
@netbe netbe requested review from Copilot and removed request for johnxnguyen and netbe March 6, 2026 09:07
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR continues the app-wide effort to reduce implicit session dependencies by removing many direct calls to the deprecated ZMUserSession.shared() and instead passing a UserSession (and casting to ZMUserSession only where unavoidable).

Changes:

  • Reworked many UI/controller initializers to accept UserSession and removed ZMUserSession.shared() defaults.
  • Threaded UserSession into media picking/confirmation, message preview/forwarding, and call-related UI flows.
  • Updated Settings / Developer tools to operate on an injected session rather than global state.

Reviewed changes

Copilot reviewed 150 out of 150 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
wire-ios/Wire-iOS/Sources/UserInterface/UserProfile/Views/SecurityLevelView.swift Remove shared-session default provider
wire-ios/Wire-iOS/Sources/UserInterface/UserProfile/SearchUserViewController.swift Use injected session for directory
wire-ios/Wire-iOS/Sources/UserInterface/UserProfile/ProfileViewControllerViewModel.swift Remove shared-session default provider
wire-ios/Wire-iOS/Sources/UserInterface/UserProfile/ProfileViewController.swift Derive classification provider from session
wire-ios/Wire-iOS/Sources/UserInterface/UserProfile/Details/ProfileDetailsViewController.swift Pass session into content controller
wire-ios/Wire-iOS/Sources/UserInterface/UserProfile/Details/ProfileDetailsContentController.swift Store session; replace shared calls
wire-ios/Wire-iOS/Sources/UserInterface/StartUI/StartUI/SearchResultsViewController.swift Inject session into sections
wire-ios/Wire-iOS/Sources/UserInterface/StartUI/Common/SectionControllers/TopPeopleLine/TopPeopleSectionController.swift Pass session to inner controller
wire-ios/Wire-iOS/Sources/UserInterface/StartUI/Common/SectionControllers/TopPeopleLine/TopPeopleLineCollectionViewController.swift Carry session to cells
wire-ios/Wire-iOS/Sources/UserInterface/StartUI/Common/SectionControllers/Suggestions/DirectorySectionController.swift Require session; cast when needed
wire-ios/Wire-iOS/Sources/UserInterface/StartUI/Common/Cells/TopPeopleCell.swift Expose session to avatar view
wire-ios/Wire-iOS/Sources/UserInterface/Sketchpad/CanvasViewController.swift Require session; remove shared usage
wire-ios/Wire-iOS/Sources/UserInterface/Settings/SettingsViewControllerBuilder.swift Thread session into Settings VCs
wire-ios/Wire-iOS/Sources/UserInterface/Settings/SettingsTableViewController.swift Store session; remove shared observers
wire-ios/Wire-iOS/Sources/UserInterface/Settings/DeviceManagement/SettingsClientViewController.swift Pass session into removal observer
wire-ios/Wire-iOS/Sources/UserInterface/Settings/DeviceManagement/ClientListViewController.swift Make session non-optional; update observers
wire-ios/Wire-iOS/Sources/UserInterface/Settings/DebugActions.swift Accept session explicitly in actions
wire-ios/Wire-iOS/Sources/UserInterface/Settings/DatabaseStatisticsController.swift Require session; remove shared lookup
wire-ios/Wire-iOS/Sources/UserInterface/Settings/ChangingDetails/ChangeHandleViewController.swift Pull profile from injected session
wire-ios/Wire-iOS/Sources/UserInterface/Settings/CellDescriptors/SettingsSignOutCellDescriptor.swift Build logout helper with session
wire-ios/Wire-iOS/Sources/UserInterface/Settings/CellDescriptors/SettingsShareDatabaseCellDescriptor.swift Use captured session vs shared
wire-ios/Wire-iOS/Sources/UserInterface/Settings/CellDescriptors/SettingsCellDescriptorFactory.swift Carry session through descriptor tree
wire-ios/Wire-iOS/Sources/UserInterface/Settings/CellDescriptors/SettingsCellDescriptorFactory+SoundAlert.swift Pass session into group descriptors
wire-ios/Wire-iOS/Sources/UserInterface/Settings/CellDescriptors/SettingsCellDescriptorFactory+Options.swift Pass session into option groups
wire-ios/Wire-iOS/Sources/UserInterface/Settings/CellDescriptors/SettingsCellDescriptorFactory+Developer.swift Use injected session for debug actions
wire-ios/Wire-iOS/Sources/UserInterface/Settings/CellDescriptors/SettingsCellDescriptorFactory+DataUsagePermissions.swift Pass session into group descriptor
wire-ios/Wire-iOS/Sources/UserInterface/Settings/CellDescriptors/SettingsCellDescriptorFactory+Advanced.swift Pass session; remove shared push token call
wire-ios/Wire-iOS/Sources/UserInterface/Settings/CellDescriptors/SettingsCellDescriptorFactory+Account.swift Pass session into account flows
wire-ios/Wire-iOS/Sources/UserInterface/Settings/CellDescriptors/SettingsCellDescriptor.swift Store session on group descriptor
wire-ios/Wire-iOS/Sources/UserInterface/SelfProfile/SelfProfileViewController.swift Create picker/factory with session
wire-ios/Wire-iOS/Sources/UserInterface/SelfProfile/SelfProfileViewController+SettingsChangeAlert.swift Use injected session for perform block
wire-ios/Wire-iOS/Sources/UserInterface/SelfProfile/AccountViews/PersonalAccountView.swift Add session dependency for observers
wire-ios/Wire-iOS/Sources/UserInterface/SelfProfile/AccountViews/AccountViewBuilder.swift Thread session into account view
wire-ios/Wire-iOS/Sources/UserInterface/Overlay/CallTopOverlayController.swift Require session for call observers
wire-ios/Wire-iOS/Sources/UserInterface/MainController/ZClientViewController.swift Inject session into proximity/settings
wire-ios/Wire-iOS/Sources/UserInterface/MainController/DefaultSettingsPropertyFactoryDelegate.swift Pass session into passcode flow
wire-ios/Wire-iOS/Sources/UserInterface/LegalHoldDetails/Sections/LegalHoldParticipantsSectionController.swift Add session dependency for observers
wire-ios/Wire-iOS/Sources/UserInterface/LegalHoldDetails/LegalHoldDetailsViewController.swift Pass session into section controller
wire-ios/Wire-iOS/Sources/UserInterface/GroupDetails/Sections/ReceiptOptionsSectionController.swift Use stored session instead of shared
wire-ios/Wire-iOS/Sources/UserInterface/GroupDetails/GroupDetailsViewController.swift Replace shared session calls with injected
wire-ios/Wire-iOS/Sources/UserInterface/GroupDetails/ConversationActions/ConversationCallController.swift Require session; remove shared leave
wire-ios/Wire-iOS/Sources/UserInterface/GroupDetails/ConversationActions/ConversationActionController.swift Use injected session cast
wire-ios/Wire-iOS/Sources/UserInterface/GroupDetails/ConversationActions/ConversationActionController+Folders.swift Get directory from injected session
wire-ios/Wire-iOS/Sources/UserInterface/DeviceView/DeviceDetailsViewActionsHandler.swift Pass session into removal observer
wire-ios/Wire-iOS/Sources/UserInterface/CustomAppLock/Setup/PasscodeSetupViewController.swift Require session; inject into presenter
wire-ios/Wire-iOS/Sources/UserInterface/CustomAppLock/Setup/PasscodeSetupPresenter.swift Inject session into interactor
wire-ios/Wire-iOS/Sources/UserInterface/CustomAppLock/Setup/PasscodeSetupInteractor.swift Use injected session for app lock
wire-ios/Wire-iOS/Sources/UserInterface/ConversationList/ListContent/ConversationListContentController/ViewModel/ConversationListViewModel.swift Make session non-optional; remove shared enqueue
wire-ios/Wire-iOS/Sources/UserInterface/ConversationList/ListContent/ConversationListContentController/ConversationListContentController.swift Pass session into connect/call flows
wire-ios/Wire-iOS/Sources/UserInterface/ConversationList/ListContent/ConnectRequestsCell.swift Configure cell with injected session
wire-ios/Wire-iOS/Sources/UserInterface/ConversationList/Container/ViewModel/ConversationListViewControllerViewModel.swift Use injected session for observers
wire-ios/Wire-iOS/Sources/UserInterface/ConversationList/Container/ViewModel/ConversationListViewControllerViewModel+ZMConversationListObserver.swift Use injected session for list observers
wire-ios/Wire-iOS/Sources/UserInterface/ConversationList/Container/ConversationListViewController.swift Require session for network status VC
wire-ios/Wire-iOS/Sources/UserInterface/ConversationList/Container/ConversationListViewController+EmptyState.swift Remove optional session usage
wire-ios/Wire-iOS/Sources/UserInterface/ConversationList/ArchivedList/ArchivedListViewController.swift Pass session into call controller
wire-ios/Wire-iOS/Sources/UserInterface/Conversation/InputBar/ReplyComposingView.swift Require session for message preview/obs
wire-ios/Wire-iOS/Sources/UserInterface/Conversation/InputBar/ConversationInputBarViewController/ConversationInputBarViewController.swift Init restriction manager with session
wire-ios/Wire-iOS/Sources/UserInterface/Conversation/InputBar/ConversationInputBarViewController+ImagePicker.swift Reuse restriction manager
wire-ios/Wire-iOS/Sources/UserInterface/Conversation/InputBar/ConversationInputBarViewController+FilesPopover.swift Use session for upload limit
wire-ios/Wire-iOS/Sources/UserInterface/Conversation/InputBar/ConversationInputBarViewController+DragAndDrop.swift Pass session into confirmation VC
wire-ios/Wire-iOS/Sources/UserInterface/Conversation/InputBar/ConversationInputBarViewController+Camera.swift Pass session into camera/confirm flows
wire-ios/Wire-iOS/Sources/UserInterface/Conversation/InputBar/ConversationInputBarViewController+Audio.swift Remove shared guard; use session contextProvider
wire-ios/Wire-iOS/Sources/UserInterface/Conversation/InputBar/CameraKeyboard/CameraKeyboardViewController.swift Require session; remove shared limits
wire-ios/Wire-iOS/Sources/UserInterface/Conversation/InputBar/AudioRecorder.swift Require session for call-state gating
wire-ios/Wire-iOS/Sources/UserInterface/Conversation/InputBar/AudioRecordViewController.swift Inject session into recorder
wire-ios/Wire-iOS/Sources/UserInterface/Conversation/InputBar/AudioRecordKeyboardViewController.swift Inject session into recorder
wire-ios/Wire-iOS/Sources/UserInterface/Conversation/ConversationViewController.swift Pass session into call controller; remove shared didClose
wire-ios/Wire-iOS/Sources/UserInterface/Conversation/ConversationViewController+ViewLifeCycle.swift Remove shared didOpen
wire-ios/Wire-iOS/Sources/UserInterface/Conversation/ConversationRootViewController.swift Use session for network status + classification
wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/MessagePresenter.swift Require session; remove shared enqueue
wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/ConversationContentViewController.swift Create presenter with session
wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/ConversationContentViewController+Reply.swift Pass session into reply composing view
wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/ConversationContentViewController+MessageAction.swift Use session perform; pass session to canvas
wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/ConversationContentViewController+Header.swift Cast injected session where required
wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/ConversationContentViewController+Forward.swift Update Shareable forwarding to use session
wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/FileTransfer/AudioMessageView.swift Add session setter; remove shared observer
wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/ConversationMessageSectionController.swift Pass session into cell descriptions
wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/Content/Text/ConversationCollapsedMessageCell.swift Inject session into avatar/observers
wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/Components/ConversationSystemMessageCellDescription.swift Pass session to sender cell
wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/Components/ConversationSenderMessageDetailsCell.swift Inject session into avatar/observers
wire-ios/Wire-iOS/Sources/UserInterface/ConnectRequests/UserConnectionViewController.swift Make userSession required; pass to views
wire-ios/Wire-iOS/Sources/UserInterface/ConnectRequests/UserConnectionView.swift Require session; remove shared image session
wire-ios/Wire-iOS/Sources/UserInterface/ConnectRequests/IncomingConnectionView.swift Require session; remove shared image session
wire-ios/Wire-iOS/Sources/UserInterface/ConnectRequests/ConnectRequestsViewController.swift Configure cell with user+session
wire-ios/Wire-iOS/Sources/UserInterface/ConnectRequests/ConnectRequestCell.swift Configure via injected session (no shared)
wire-ios/Wire-iOS/Sources/UserInterface/Components/NetworkStatus/NetworkStatusViewController.swift Require session; remove shared lookups
wire-ios/Wire-iOS/Sources/UserInterface/Components/MessagePreviewView.swift Require session for previews/observers
wire-ios/Wire-iOS/Sources/UserInterface/Components/Controllers/ImagePickerConfirmationController.swift Require session for confirmation VC
wire-ios/Wire-iOS/Sources/UserInterface/Components/Controllers/ConfirmAssetViewController/ConfirmAssetViewController.swift Require session; pass to canvas
wire-ios/Wire-iOS/Sources/UserInterface/Collections/ConversationImagesViewController.swift Use injected session for restrictions
wire-ios/Wire-iOS/Sources/UserInterface/Collections/CollectionsViewController.swift Create presenter with session; set audio session
wire-ios/Wire-iOS/Sources/UserInterface/Collections/CollectionAudioCell.swift Forward session into audio view
wire-ios/Wire-iOS/Sources/UserInterface/Calling/CallViewController/CallViewController.swift Pass session into call grid VC
wire-ios/Wire-iOS/Sources/UserInterface/Calling/CallQualityController/CallQualityController.swift Observe calls via injected session
wire-ios/Wire-iOS/Sources/UserInterface/Calling/CallGridView/CallParticipantViews/CallParticipantView.swift Pass session through participant view
wire-ios/Wire-iOS/Sources/UserInterface/Calling/CallGridView/CallParticipantViews/BaseCallParticipantView.swift Store injected session (no shared)
wire-ios/Wire-iOS/Sources/UserInterface/Calling/CallGridView/CallGridViewController.swift Store injected session; pass to views
wire-ios/Wire-iOS/Sources/UserInterface/Calling/CallController/CallController.swift Use injected session instead of shared
wire-ios/Wire-iOS/Sources/UserInterface/Calling/CallController/ActiveCallRouter.swift Pass session to call controller/quality/top overlay
wire-ios/Wire-iOS/Sources/UserInterface/Calling/BottomSheetContainerViewController/CallingBottomSheetViewController.swift Use injected session for priority call
wire-ios/Wire-iOS/Sources/Managers/ProximityMonitorManager.swift Require session; remove shared callCenter
wire-ios/Wire-iOS/Sources/Managers/Image/ProfileImagePickerManager.swift Use injected session for profile update
wire-ios/Wire-iOS/Sources/Managers/Image/ImagePickerManager.swift Require session; remove shared restrictions
wire-ios/Wire-iOS/Sources/Helpers/syncengine/MessageKeyPathObserver.swift Require session for message observing
wire-ios/Wire-iOS/Sources/Helpers/syncengine/ClientRemovalObserver.swift Store injected session; remove shared usage
wire-ios/Wire-iOS/Sources/Developer/DeveloperTools/Journal/JournalViewModel.swift Use injected session for CoreData context
wire-ios/Wire-iOS/Sources/Developer/DeveloperTools/DeveloperToolsViewModel.swift Use active session from router
wire-ios/Wire-iOS/Sources/Developer/DeveloperTools/DeveloperE2ei/DeveloperE2eiViewModel.swift Inject session instead of shared
wire-ios/Wire-iOS/Sources/Developer/DeveloperTools/DeveloperE2ei/DeveloperE2eiView.swift Update preview initializer
wire-ios/Wire-iOS/Sources/Developer/DeveloperTools/DebugActions/DeveloperDebugActionsViewModel.swift Inject session; logout uses helper(session)
wire-ios/Wire-iOS/Sources/Developer/DeveloperTools/DebugActions/DeveloperDebugActionsView.swift Update preview initializer
wire-ios/Wire-iOS/Sources/Components/ShareViewController/ShareViewController.swift Shareable now requires session
wire-ios/Wire-iOS/Sources/Components/ShareViewController/ShareViewController+Views.swift Pass session to preview generation
wire-ios/Wire-iOS/Sources/Components/Settings+Account.swift lastViewedConversation now takes session
wire-ios/Wire-iOS/Sources/Authentication/Helpers/LogOutHelper.swift Require session; remove shared logout

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +57 to 65
func setupConnectRequestsCell(userSession: UserSession) {
self.userSession = userSession

clipsToBounds = true
addSubview(itemView)
updateAppearance()

if let userSession = ZMUserSession.shared() {
if let userSession = userSession as? ZMUserSession {
conversationListObserverToken = ConversationListChangeInfo.add(
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setupConnectRequestsCell(userSession:) is not idempotent: it re-adds itemView and re-registers ConversationListChangeInfo every time it's called. Since the collection view calls this during cell reuse, this can lead to lost constraints (because hasCreatedInitialConstraints prevents re-adding them after reattaching the view) and multiple active observers (the previous token is overwritten without being removed). Consider moving the one-time view setup/constraints/observer registration back into init, and keep a separate lightweight configure(userSession:) that only updates stored session + appearance, or guard so setup/observer registration runs only once (and explicitly unregister/replace observers when session changes).

Copilot uses AI. Check for mistakes.
Comment on lines 70 to 73
cancelAction: { [weak self] in
guard let userSession = ZMUserSession.shared() else { return }
self?.conversation.voiceChannel?.leave(userSession: userSession, completion: nil)
guard let self, let userSession = userSession as? ZMUserSession else { return }
conversation.voiceChannel?.leave(userSession: userSession, completion: nil)

Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In cancelAction, let userSession = userSession as? ZMUserSession relies on implicit member lookup inside an escaping closure and also shadows the stored userSession property name, which is easy to misread and can trip Swift's explicit-self rules. Rename the unwrapped variable (e.g. zmUserSession) and reference self.userSession explicitly to make capture semantics unambiguous.

Copilot uses AI. Check for mistakes.
Comment on lines 76 to 79
func startRemoval() {
delegate?.setIsLoadingViewVisible(self, isVisible: true)
ZMUserSession.shared()?.deleteClient(userClientToDelete, credentials: credentials)
(userSession as? ZMUserSession)?.deleteClient(userClientToDelete, credentials: credentials)
}
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

startRemoval() turns on the loading UI and then calls deleteClient only if userSession can be cast to ZMUserSession. If a non-ZMUserSession implementation is ever passed in (e.g. in tests/mocks), the deletion is skipped and the loading UI can remain stuck indefinitely with no completion. Either require ZMUserSession in the initializer (since this type needs deleteClient/addClientUpdateObserver anyway) or handle the cast failure by hiding the loading UI and calling completion with an error.

Copilot uses AI. Check for mistakes.
Comment on lines +65 to 73
func lastViewedConversation(for account: Account, in session: UserSession) -> ZMConversation? {
guard let conversationID: String = value(for: .lastViewedConversation, in: account) else {
return nil
}

let conversationURI = URL(string: conversationID)
let session = ZMUserSession.shared()
let session = session as? ZMUserSession
let objectID = ZMManagedObject.objectID(forURIRepresentation: conversationURI, inUserSession: session)
return ZMConversation.existingObject(with: objectID, inUserSession: session)
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parameter session is immediately shadowed by let session = session as? ZMUserSession, which makes the code harder to follow and easier to misuse (especially when passing session into other APIs below). Consider renaming the casted value (e.g. zmSession) or using a separate guard let zmSession = session as? ZMUserSession else { return nil } to avoid shadowing.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator

@netbe netbe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is quite a large PR so hard to be thorough. I left some comments but looking at the complexity it looks fine to me


guard let userSession = ZMUserSession.shared() else {
// This is a hack for testing as a real ZMUserSession is not available
guard userSession is ZMUserSession else {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: change zmlog as WireLogger

guard let userSession = ZMUserSession.shared() else {
// This is a hack for testing as a real ZMUserSession is not available
guard userSession is ZMUserSession else {
zmLog.error("UserSession not available when initializing \(type(of: self))")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: change zmlog as WireLogger

}
}

func setUserSession(userSession: UserSession) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: where is this method called?

func setUserSession(userSession: UserSession) {
self.userSession = userSession

if callStateObserverToken == nil, let userSession = userSession as? ZMUserSession {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: I notice the check for callStateObserverToken == nil compared to before, is it needed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants