Skip to content

Commit 2f23188

Browse files
committed
ios universal link
1 parent e00fae6 commit 2f23188

File tree

8 files changed

+79
-84
lines changed

8 files changed

+79
-84
lines changed

ios/App/App.xcodeproj/project.pbxproj

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@
2828
D3490CC62E7CE9EA00E796A6 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D3490CC52E7CE9EA00E796A6 /* WidgetKit.framework */; };
2929
D3490CC82E7CE9EA00E796A6 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D3490CC72E7CE9EA00E796A6 /* SwiftUI.framework */; };
3030
D3490CD52E7CE9EB00E796A6 /* shortcutsExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = D3490CC42E7CE9EA00E796A6 /* shortcutsExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
31-
D39D1FDD2E7D6D8A00C903D1 /* LogseqIntents.swift in Sources */ = {isa = PBXBuildFile; fileRef = D39D1FDB2E7D6D8A00C903D1 /* LogseqIntents.swift */; };
32-
D39D1FDE2E7D6D8A00C903D1 /* LogseqShortcuts.swift in Sources */ = {isa = PBXBuildFile; fileRef = D39D1FDC2E7D6D8A00C903D1 /* LogseqShortcuts.swift */; };
31+
D39D1FE02E7DAFB000C903D1 /* LogseqIntents.swift in Sources */ = {isa = PBXBuildFile; fileRef = D39D1FDF2E7DAFB000C903D1 /* LogseqIntents.swift */; };
32+
D39D1FE12E7DAFB000C903D1 /* LogseqIntents.swift in Sources */ = {isa = PBXBuildFile; fileRef = D39D1FDF2E7DAFB000C903D1 /* LogseqIntents.swift */; };
3333
D3D62A0A275C92880003FBDC /* FileContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3D62A09275C92880003FBDC /* FileContainer.swift */; };
3434
D3D62A0C275C928F0003FBDC /* FileContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = D3D62A0B275C928F0003FBDC /* FileContainer.m */; };
3535
FE647FF427BDFEDE00F3206B /* FsWatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE647FF327BDFEDE00F3206B /* FsWatcher.swift */; };
@@ -100,8 +100,7 @@
100100
D3490CC52E7CE9EA00E796A6 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; };
101101
D3490CC72E7CE9EA00E796A6 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; };
102102
D3490CDA2E7CEA3900E796A6 /* shortcutsExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = shortcutsExtension.entitlements; sourceTree = "<group>"; };
103-
D39D1FDB2E7D6D8A00C903D1 /* LogseqIntents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogseqIntents.swift; sourceTree = "<group>"; };
104-
D39D1FDC2E7D6D8A00C903D1 /* LogseqShortcuts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogseqShortcuts.swift; sourceTree = "<group>"; };
103+
D39D1FDF2E7DAFB000C903D1 /* LogseqIntents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogseqIntents.swift; sourceTree = "<group>"; };
105104
D3D62A09275C92880003FBDC /* FileContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileContainer.swift; sourceTree = "<group>"; };
106105
D3D62A0B275C928F0003FBDC /* FileContainer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FileContainer.m; sourceTree = "<group>"; };
107106
DE5650F4AD4E2242AB9C012D /* Pods-Logseq.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Logseq.debug.xcconfig"; path = "Target Support Files/Pods-Logseq/Pods-Logseq.debug.xcconfig"; sourceTree = "<group>"; };
@@ -179,6 +178,7 @@
179178
504EC3061FED79650016851F /* App */ = {
180179
isa = PBXGroup;
181180
children = (
181+
D39D1FDF2E7DAFB000C903D1 /* LogseqIntents.swift */,
182182
CBF2D2E12DE95970006338BE /* AppViewController.swift */,
183183
CBF2D2D92DE83CB0006338BE /* UILocalPlugin.swift */,
184184
5FF86329283B5ADB0047731B /* Utils.swift */,
@@ -187,8 +187,6 @@
187187
D32752BC275496A60039291C /* App.entitlements */,
188188
50379B222058CBB4000EE86E /* capacitor.config.json */,
189189
504EC3071FED79650016851F /* AppDelegate.swift */,
190-
D39D1FDB2E7D6D8A00C903D1 /* LogseqIntents.swift */,
191-
D39D1FDC2E7D6D8A00C903D1 /* LogseqShortcuts.swift */,
192190
504EC30B1FED79650016851F /* Main.storyboard */,
193191
504EC30E1FED79650016851F /* Assets.xcassets */,
194192
504EC3101FED79650016851F /* LaunchScreen.storyboard */,
@@ -314,7 +312,6 @@
314312
504EC3031FED79650016851F = {
315313
CreatedOnToolsVersion = 9.2;
316314
LastSwiftMigration = 1250;
317-
ProvisioningStyle = Automatic;
318315
};
319316
5FFF7D6927E343FA00B00DA8 = {
320317
CreatedOnToolsVersion = 13.3;
@@ -421,8 +418,6 @@
421418
isa = PBXSourcesBuildPhase;
422419
buildActionMask = 2147483647;
423420
files = (
424-
D39D1FDD2E7D6D8A00C903D1 /* LogseqIntents.swift in Sources */,
425-
D39D1FDE2E7D6D8A00C903D1 /* LogseqShortcuts.swift in Sources */,
426421
504EC3081FED79650016851F /* AppDelegate.swift in Sources */,
427422
5FF8632C283B5BFD0047731B /* Utils.m in Sources */,
428423
FE647FF427BDFEDE00F3206B /* FsWatcher.swift in Sources */,
@@ -432,6 +427,7 @@
432427
CBF2D2DA2DE83CB8006338BE /* UILocalPlugin.swift in Sources */,
433428
D3D62A0C275C928F0003FBDC /* FileContainer.m in Sources */,
434429
7435D10F2704660B00AB88E0 /* FolderPicker.m in Sources */,
430+
D39D1FE12E7DAFB000C903D1 /* LogseqIntents.swift in Sources */,
435431
7435D10C2704659F00AB88E0 /* FolderPicker.swift in Sources */,
436432
FE647FF627BDFEF500F3206B /* FsWatcher.m in Sources */,
437433
);
@@ -450,6 +446,7 @@
450446
isa = PBXSourcesBuildPhase;
451447
buildActionMask = 2147483647;
452448
files = (
449+
D39D1FE02E7DAFB000C903D1 /* LogseqIntents.swift in Sources */,
453450
);
454451
runOnlyForDeploymentPostprocessing = 0;
455452
};

ios/App/App/App.entitlements

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,6 @@
44
<dict>
55
<key>aps-environment</key>
66
<string>development</string>
7-
<key>com.apple.developer.associated-domains</key>
8-
<array>
9-
<string>applinks:https://logseq.com</string>
10-
</array>
117
<key>com.apple.developer.icloud-container-identifiers</key>
128
<array>
139
<string>iCloud.com.logseq.logseq</string>
@@ -24,5 +20,9 @@
2420
<array>
2521
<string>group.com.logseq.logseq</string>
2622
</array>
23+
<key>com.apple.developer.associated-domains</key>
24+
<array>
25+
<string>applinks:logseq.com</string>
26+
</array>
2727
</dict>
2828
</plist>

ios/App/App/AppDelegate.swift

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,29 +28,49 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
2828
switch shortcutItem.type {
2929
case "logseq.quickadd":
3030
donateQuickAddShortcut()
31-
openURL("logseq://go/quick-add")
31+
openURL("logseq://mobile/go/quick-add")
3232
return true
3333
case "logseq.voice":
3434
donateAudioShortcut()
35-
openURL("logseq://go/audio")
35+
openURL("logseq://mobile/go/audio")
3636
return true
3737
default:
3838
return false
3939
}
4040
}
4141

4242
func application(_ application: UIApplication,
43-
continue userActivity: NSUserActivity,
44-
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
43+
continue userActivity: NSUserActivity,
44+
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
45+
46+
// Case 1: custom NSUserActivities
4547
if userActivity.activityType == "com.logseq.quickadd" {
46-
openURL("logseq://go/quick-add")
48+
openURL("logseq://mobile/go/quick-add")
4749
return true
4850
}
4951
if userActivity.activityType == "com.logseq.audio" {
50-
openURL("logseq://go/audio")
52+
openURL("logseq://mobile/go/audio")
53+
return true
54+
}
55+
56+
// Case 2: Universal Links
57+
if userActivity.activityType == NSUserActivityTypeBrowsingWeb,
58+
let url = userActivity.webpageURL {
59+
print("🌐 Universal link opened:", url)
60+
61+
// Forward to Capacitor (so JS gets `appUrlOpen`)
62+
NotificationCenter.default.post(
63+
name: .capacitorOpenURL,
64+
object: nil,
65+
userInfo: [
66+
"url": url,
67+
"options": [:]
68+
]
69+
)
5170
return true
5271
}
5372

73+
// Default: let Capacitor handle other cases
5474
return ApplicationDelegateProxy.shared.application(application,
5575
continue: userActivity,
5676
restorationHandler: restorationHandler)

ios/App/App/LogseqIntents.swift

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,51 @@
11
import AppIntents
22
import UIKit
33

4+
@available(iOS 18.0, *)
45
struct QuickAddIntent: AppIntent {
56
static var title: LocalizedStringResource = "Quick Add"
67
static var description = IntentDescription("Open Logseq Quick Add")
78

8-
func perform() async throws -> some IntentResult {
9-
if let url = URL(string: "logseq://go/quick-add") {
10-
await UIApplication.shared.open(url)
11-
}
12-
return .result()
9+
func perform() async throws -> some IntentResult & OpensIntent {
10+
let url = URL(string: "https://logseq.com/mobile/go/quick-add")!
11+
return .result(opensIntent: OpenURLIntent(url))
1312
}
1413
}
1514

15+
@available(iOS 18.0, *)
1616
struct RecordAudioIntent: AppIntent {
1717
static var title: LocalizedStringResource = "Record Audio"
1818
static var description = IntentDescription("Open Logseq Record Audio")
1919

20-
func perform() async throws -> some IntentResult {
21-
if let url = URL(string: "logseq://go/audio") {
22-
await UIApplication.shared.open(url)
23-
}
24-
return .result()
20+
func perform() async throws -> some IntentResult & OpensIntent {
21+
let url = URL(string: "https://logseq.com/mobile/go/audio")!
22+
return .result(opensIntent: OpenURLIntent(url))
23+
}
24+
}
25+
26+
@available(iOS 18.0, *)
27+
struct LogseqShortcuts: AppShortcutsProvider {
28+
static var appShortcuts: [AppShortcut] {
29+
return [
30+
AppShortcut(
31+
intent: QuickAddIntent(),
32+
phrases: [
33+
"Quick add in \(.applicationName)",
34+
"Add note in \(.applicationName)"
35+
],
36+
shortTitle: "Quick Add",
37+
systemImageName: "plus.circle"
38+
),
39+
40+
AppShortcut(
41+
intent: RecordAudioIntent(),
42+
phrases: [
43+
"Record audio in \(.applicationName)",
44+
"Start recording in \(.applicationName)"
45+
],
46+
shortTitle: "Record Audio",
47+
systemImageName: "waveform"
48+
)
49+
]
2550
}
2651
}

ios/App/App/LogseqShortcuts.swift

Lines changed: 0 additions & 27 deletions
This file was deleted.

ios/App/shortcuts/shortcuts.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ struct ShortcutsEntryView: View {
2727
var entry: Provider.Entry
2828

2929
var body: some View {
30-
Link(destination: URL(string: "logseq://go/quick-add")!) {
30+
Link(destination: URL(string: "logseq://mobile/go/quick-add")!) {
3131
VStack(alignment: .leading, spacing: 0) {
3232
// Top heading
3333
Text("Logseq")
@@ -46,7 +46,7 @@ struct ShortcutsEntryView: View {
4646
// Bottom buttons row
4747
HStack(spacing: 8) {
4848
// Left button (audio waves)
49-
Link(destination: URL(string: "logseq://go/audio")!) {
49+
Link(destination: URL(string: "logseq://mobile/go/audio")!) {
5050
Image(systemName: "waveform")
5151
.font(.body)
5252
.foregroundColor(Color(hex: "#002b36"))
@@ -57,7 +57,7 @@ struct ShortcutsEntryView: View {
5757
}
5858

5959
// Right button (quick add)
60-
Link(destination: URL(string: "logseq://go/quick-add")!) {
60+
Link(destination: URL(string: "logseq://mobile/go/quick-add")!) {
6161
Image(systemName: "plus")
6262
.font(.body)
6363
.foregroundColor(.white)

ios/App/shortcuts/shortcutsControl.swift

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -30,33 +30,11 @@ struct RecordAudioButton: ControlWidget {
3030
StaticControlConfiguration(
3131
kind: "com.logseq.logseq.recordAudioButton"
3232
) {
33-
ControlWidgetButton(action: RecordAudioIntent()) { // ✅ fixed
33+
ControlWidgetButton(action: RecordAudioIntent()) {
3434
Label("Record Audio", systemImage: "waveform")
3535
}
3636
}
3737
.displayName("Record Audio")
3838
.description("Record Audio.")
3939
}
4040
}
41-
42-
@available(iOS 18.0, *)
43-
struct QuickAddIntent: AppIntent {
44-
static var title: LocalizedStringResource = "Quick Add"
45-
static var description = IntentDescription("Open Logseq Quick Add")
46-
47-
// TODO: use https://logseq.com/mobile/go/quick-add
48-
func perform() async throws -> some IntentResult {
49-
.result()
50-
}
51-
}
52-
53-
@available(iOS 18.0, *)
54-
struct RecordAudioIntent: AppIntent {
55-
static var title: LocalizedStringResource = "Record Audio"
56-
static var description = IntentDescription("Open Logseq Record Audio")
57-
58-
// TODO: https://logseq.com/mobile/go/record-audio
59-
func perform() async throws -> some IntentResult {
60-
.result()
61-
}
62-
}

src/main/mobile/deeplink.cljs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,12 @@
2929
(remove #(= (:url %) config/demo-repo))
3030
(map :url))
3131
repo-names (map #(get-graph-name-fn %) repos)]
32+
(prn :debug :hostname hostname
33+
:pathname pathname)
3234
(cond
33-
(and (= hostname "go") (= pathname "/audio"))
35+
(and (= hostname "mobile") (= pathname "/go/audio"))
3436
(state/pub-event! [:mobile/start-audio-record])
35-
(and (= hostname "go") (= pathname "/quick-add"))
37+
(and (= hostname "mobile") (= pathname "/go/quick-add"))
3638
(state/pub-event! [:dialog/mobile-quick-add])
3739
(= hostname "graph")
3840
(let [graph-name (some-> pathname

0 commit comments

Comments
 (0)