Files
Narasimha-sc 547595041e ios: open SimpleX links in chat messages via in-app connect flow (#7101)
* ios: open SimpleX links in chat messages via in-app connect flow

Tapping an inline SimpleX connection link in message text was dispatched
through UIApplication.shared.open. iOS drops an open() of a URL owned by
the same app while it is in the foreground (the simplex: scheme and the
simplex.chat universal links both belong to this app), so the tap was
ignored and never reached the connection flow. Web links (Safari) and
mailto:/tel: (other apps) were unaffected, which is why only SimpleX
links appeared dead.

Route SimpleX links to ChatModel.appOpenUrl instead - the same sink
onOpenURL feeds, leading to connectViaUrl/planAndConnect. This matches
the connection-link card and the multiplatform clients, which connect
in-process rather than via an OS round-trip.

Also fixes the same problem for the "Send questions and ideas" and
"connect to SimpleX Chat developers" buttons, which open simplexTeamURL
(a simplex: link) the same broken way.

* docs: plan - justify iOS in-app dispatch for SimpleX links in messages

Root cause and justification for opening inline SimpleX links via the
in-app connect flow instead of UIApplication.shared.open (undefined
re-entry of the same foreground app for a self-owned simplex: URL).
2026-06-19 23:36:28 +01:00

74 lines
2.3 KiB
Swift

//
// ChatHelp.swift
// SimpleX
//
// Created by Evgeny Poberezkin on 10/02/2022.
// Copyright © 2022 SimpleX Chat. All rights reserved.
//
import SwiftUI
struct ChatHelp: View {
@EnvironmentObject var chatModel: ChatModel
@State private var showNewChatSheet = false
let dismissSettingsSheet: DismissAction
var body: some View {
ScrollView { chatHelp() }
}
func chatHelp() -> some View {
VStack(alignment: .leading, spacing: 10) {
Text("Thank you for installing SimpleX Chat!")
VStack(alignment: .leading, spacing: 0) {
Text("To ask any questions and to receive updates:")
Button("connect to SimpleX Chat developers.") {
dismissSettingsSheet()
DispatchQueue.main.async {
// simplexTeamURL targets this same app; route to the in-app connect flow
// (UIApplication.shared.open is dropped for self-owned URLs in the foreground)
ChatModel.shared.appOpenUrl = simplexTeamURL
}
}
.padding(.top, 2)
}
VStack(alignment: .leading, spacing: 10) {
Text("To make a new connection")
.font(.title2)
.fontWeight(.bold)
HStack(spacing: 8) {
Text("Tap button ")
NewChatMenuButton(showNewChatSheet: $showNewChatSheet)
Text("above, then choose:")
}
Text("**Create 1-time link**: to create and share a new invitation link.")
Text("**Scan / Paste link**: to connect via a link you received.")
Text("**Create group**: to create a new group.")
}
.padding(.top, 24)
VStack(alignment: .leading, spacing: 10) {
Text("Markdown in messages")
.font(.title2)
.fontWeight(.bold)
MarkdownHelp()
}
.padding(.top, 24)
}
.padding()
}
}
struct ChatHelp_Previews: PreviewProvider {
@Environment(\.dismiss) static var mockDismiss
static var previews: some View {
ChatHelp(dismissSettingsSheet: mockDismiss)
}
}