Kaynağa Gözat

mobile: separate filecontainer from filepicker

Tienson Qin 3 yıl önce
ebeveyn
işleme
881e65a9fa

+ 12 - 0
ios/App/App.xcodeproj/project.pbxproj

@@ -18,6 +18,8 @@
 		7435D10F2704660B00AB88E0 /* FolderPicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 7435D10E2704660B00AB88E0 /* FolderPicker.m */; };
 		B50C6194D06FE919721B594B /* Pods_Logseq.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 659A484D0A608EE5D778DEF1 /* Pods_Logseq.framework */; };
 		D32752BE275496C60039291C /* CloudKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D32752BD275496C60039291C /* CloudKit.framework */; };
+		D3D62A0A275C92880003FBDC /* FileContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3D62A09275C92880003FBDC /* FileContainer.swift */; };
+		D3D62A0C275C928F0003FBDC /* FileContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = D3D62A0B275C928F0003FBDC /* FileContainer.m */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
@@ -40,6 +42,8 @@
 		D32752BC275496A60039291C /* App.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = App.entitlements; sourceTree = "<group>"; };
 		D32752BD275496C60039291C /* CloudKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CloudKit.framework; path = System/Library/Frameworks/CloudKit.framework; sourceTree = SDKROOT; };
 		D32752BF2754C5AB0039291C /* AppDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AppDebug.entitlements; sourceTree = "<group>"; };
+		D3D62A09275C92880003FBDC /* FileContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileContainer.swift; sourceTree = "<group>"; };
+		D3D62A0B275C928F0003FBDC /* FileContainer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FileContainer.m; sourceTree = "<group>"; };
 		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>"; };
 /* End PBXFileReference section */
 
@@ -89,6 +93,8 @@
 				50B271D01FEDC1A000F3C39B /* public */,
 				7435D10B2704659F00AB88E0 /* FolderPicker.swift */,
 				7435D10E2704660B00AB88E0 /* FolderPicker.m */,
+				D3D62A09275C92880003FBDC /* FileContainer.swift */,
+				D3D62A0B275C928F0003FBDC /* FileContainer.m */,
 				7435D10D2704660A00AB88E0 /* App-Bridging-Header.h */,
 			);
 			path = App;
@@ -232,6 +238,8 @@
 			buildActionMask = 2147483647;
 			files = (
 				504EC3081FED79650016851F /* AppDelegate.swift in Sources */,
+				D3D62A0A275C92880003FBDC /* FileContainer.swift in Sources */,
+				D3D62A0C275C928F0003FBDC /* FileContainer.m in Sources */,
 				7435D10F2704660B00AB88E0 /* FolderPicker.m in Sources */,
 				7435D10C2704659F00AB88E0 /* FolderPicker.swift in Sources */,
 			);
@@ -380,10 +388,12 @@
 				CLANG_ENABLE_MODULES = YES;
 				CODE_SIGN_ENTITLEMENTS = App/AppDebug.entitlements;
 				CODE_SIGN_STYLE = Automatic;
+				CURRENT_PROJECT_VERSION = 2.2;
 				DEVELOPMENT_TEAM = K378MFWK59;
 				INFOPLIST_FILE = App/Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+				MARKETING_VERSION = 2.2;
 				OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\"";
 				PRODUCT_BUNDLE_IDENTIFIER = com.logseq.app;
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -403,10 +413,12 @@
 				CLANG_ENABLE_MODULES = YES;
 				CODE_SIGN_ENTITLEMENTS = App/App.entitlements;
 				CODE_SIGN_STYLE = Automatic;
+				CURRENT_PROJECT_VERSION = 2.2;
 				DEVELOPMENT_TEAM = K378MFWK59;
 				INFOPLIST_FILE = App/Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+				MARKETING_VERSION = 2.2;
 				PRODUCT_BUNDLE_IDENTIFIER = com.logseq.app;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_ACTIVE_COMPILATION_CONDITIONS = "";

+ 12 - 0
ios/App/App/FileContainer.m

@@ -0,0 +1,12 @@
+//
+//  FileContainer.m
+//  App
+//
+//  Created by weihua on 9/29/21.
+//
+
+#import <Capacitor/Capacitor.h>
+
+CAP_PLUGIN(FileContainer, "FileContainer",
+           CAP_PLUGIN_METHOD(ensureDocuments, CAPPluginReturnPromise);
+           )

+ 40 - 0
ios/App/App/FileContainer.swift

@@ -0,0 +1,40 @@
+//
+//  FileContainer.swift
+//  App
+//
+//
+
+import Capacitor
+import Foundation
+import MobileCoreServices
+
+@objc(FileContainer)
+public class FileContainer: CAPPlugin, UIDocumentPickerDelegate {
+
+    public var _call: CAPPluginCall? = nil
+
+    var containerUrl: URL? {
+        let id = "iCloud.com.logseq.app"
+        return FileManager.default.url(forUbiquityContainerIdentifier: id)?.appendingPathComponent("Documents")
+    }
+
+    @objc func ensureDocuments(_ call: CAPPluginCall) {
+        self._call = call
+
+        // check for container existence
+        if let url = self.containerUrl, !FileManager.default.fileExists(atPath: url.path, isDirectory: nil) {
+            do {
+                print("the url = " + url.path)
+                try FileManager.default.createDirectory(at: url, withIntermediateDirectories: true, attributes: nil)
+            }
+            catch {
+                print("container doesn't exist")
+                print(error.localizedDescription)
+            }
+        }
+
+        self._call?.resolve([
+            "path": self.containerUrl!.path
+                            ])
+    }
+}

+ 31 - 48
ios/App/App/FolderPicker.swift

@@ -11,59 +11,42 @@ import MobileCoreServices
 
 @objc(FolderPicker)
 public class FolderPicker: CAPPlugin, UIDocumentPickerDelegate {
-    
+
     public var _call: CAPPluginCall? = nil
-    
-    var containerUrl: URL? {
-        let id = "iCloud.com.logseq.app"
-        return FileManager.default.url(forUbiquityContainerIdentifier: id)?.appendingPathComponent("Documents")
-    }
-    
+
     @objc func pickFolder(_ call: CAPPluginCall) {
-        // check for container existence
-        if let url = self.containerUrl, !FileManager.default.fileExists(atPath: url.path, isDirectory: nil) {
-            do {
-                print("the url = " + url.path)
-                try FileManager.default.createDirectory(at: url, withIntermediateDirectories: true, attributes: nil)
-            }
-            catch {
-                print("container doesn't exist")
-                print(error.localizedDescription)
-            }
-        }
-        
         self._call = call
-        
+
         DispatchQueue.main.async { [weak self] in
             let documentPicker = UIDocumentPickerViewController(
-                documentTypes: [String(kUTTypeFolder)],
-                       in: UIDocumentPickerMode.open
-                   )
-                   
-                   documentPicker.allowsMultipleSelection = false
-                   documentPicker.delegate = self
-                   documentPicker.modalPresentationStyle = UIModalPresentationStyle.fullScreen
-                   
-                   self?.bridge?.viewController?.present(
-                       documentPicker,
-                       animated: true,
-                       completion: nil
-                   )
-               }
+              documentTypes: [String(kUTTypeFolder)],
+              in: UIDocumentPickerMode.open
+            )
+
+            documentPicker.allowsMultipleSelection = false
+            documentPicker.delegate = self
+            documentPicker.modalPresentationStyle = UIModalPresentationStyle.fullScreen
+
+            self?.bridge?.viewController?.present(
+              documentPicker,
+              animated: true,
+              completion: nil
+            )
+        }
     }
-    
+
     public func documentPicker(
-          _ controller: UIDocumentPickerViewController,
-          didPickDocumentsAt urls: [URL]
-      ){
-          var items: [String] = []
-          
-          for url in urls {
-              items.append(url.absoluteString)
-          }
-          
-          self._call?.resolve([
-            "path": items.first as Any
-          ])
-      }
+      _ controller: UIDocumentPickerViewController,
+      didPickDocumentsAt urls: [URL]
+    ){
+        var items: [String] = []
+
+        for url in urls {
+            items.append(url.absoluteString)
+        }
+
+        self._call?.resolve([
+                              "path": items.first as Any
+                            ])
+    }
 }

+ 83 - 83
ios/App/App/Info.plist

@@ -2,88 +2,88 @@
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 <plist version="1.0">
 <dict>
-        <key>APFiles</key>
-        <dict>
-                <key>APFileDescriptionKey</key>
-                <string></string>
-                <key>APFileDestinationPath</key>
-                <string></string>
-                <key>APFileName</key>
-                <string></string>
-                <key>APFileSourcePath</key>
-                <string></string>
-        </dict>
-        <key>CFBundleDevelopmentRegion</key>
-        <string>en</string>
-        <key>CFBundleDisplayName</key>
-        <string>Logseq</string>
-        <key>CFBundleExecutable</key>
-        <string>$(EXECUTABLE_NAME)</string>
-        <key>CFBundleIdentifier</key>
-        <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
-        <key>CFBundleInfoDictionaryVersion</key>
-        <string>6.0</string>
-        <key>CFBundleName</key>
-        <string>$(PRODUCT_NAME)</string>
-        <key>CFBundlePackageType</key>
-        <string>APPL</string>
-        <key>CFBundleShortVersionString</key>
-        <string>2.1</string>
-        <key>CFBundleVersion</key>
-        <string>2.1</string>
-        <key>LSRequiresIPhoneOS</key>
-        <true/>
-        <key>LSSupportsOpeningDocumentsInPlace</key>
-        <true/>
-        <key>NSAppTransportSecurity</key>
-        <dict>
-                <key>NSAllowsArbitraryLoads</key>
-                <true/>
-        </dict>
-        <key>NSDocumentsFolderUsageDescription</key>
-        <string></string>
-        <key>NSDownloadsFolderUsageDescription</key>
-        <string></string>
-        <key>NSFileProviderDomainUsageDescription</key>
-        <string></string>
-        <key>NSFileProviderPresenceUsageDescription</key>
-        <string></string>
-        <key>NSUbiquitousContainers</key>
-        <dict>
-                <key>iCloud.$(PRODUCT_BUNDLE_IDENTIFIER)</key>
-                <dict>
-                        <key>NSUbiquitousContainerIsDocumentScopePublic</key>
-                        <true/>
-                        <key>NSUbiquitousContainerName</key>
-                        <string>Logseq</string>
-                        <key>NSUbiquitousContainerSupportedFolderLevels</key>
-                        <string>None</string>
-                </dict>
-        </dict>
-        <key>UILaunchStoryboardName</key>
-        <string>LaunchScreen</string>
-        <key>UIMainStoryboardFile</key>
-        <string>Main</string>
-        <key>UIRequiredDeviceCapabilities</key>
-        <array>
-                <string>armv7</string>
-        </array>
-        <key>UISupportedInterfaceOrientations</key>
-        <array>
-                <string>UIInterfaceOrientationPortrait</string>
-                <string>UIInterfaceOrientationLandscapeLeft</string>
-                <string>UIInterfaceOrientationLandscapeRight</string>
-        </array>
-        <key>UISupportedInterfaceOrientations~ipad</key>
-        <array>
-                <string>UIInterfaceOrientationPortrait</string>
-                <string>UIInterfaceOrientationPortraitUpsideDown</string>
-                <string>UIInterfaceOrientationLandscapeLeft</string>
-                <string>UIInterfaceOrientationLandscapeRight</string>
-        </array>
-        <key>UISupportsDocumentBrowser</key>
-        <true/>
-        <key>UIViewControllerBasedStatusBarAppearance</key>
-        <true/>
+	<key>APFiles</key>
+	<dict>
+		<key>APFileDescriptionKey</key>
+		<string></string>
+		<key>APFileDestinationPath</key>
+		<string></string>
+		<key>APFileName</key>
+		<string></string>
+		<key>APFileSourcePath</key>
+		<string></string>
+	</dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>en</string>
+	<key>CFBundleDisplayName</key>
+	<string>Logseq</string>
+	<key>CFBundleExecutable</key>
+	<string>$(EXECUTABLE_NAME)</string>
+	<key>CFBundleIdentifier</key>
+	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>$(PRODUCT_NAME)</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>$(MARKETING_VERSION)</string>
+	<key>CFBundleVersion</key>
+	<string>$(CURRENT_PROJECT_VERSION)</string>
+	<key>LSRequiresIPhoneOS</key>
+	<true/>
+	<key>LSSupportsOpeningDocumentsInPlace</key>
+	<true/>
+	<key>NSAppTransportSecurity</key>
+	<dict>
+		<key>NSAllowsArbitraryLoads</key>
+		<true/>
+	</dict>
+	<key>NSDocumentsFolderUsageDescription</key>
+	<string></string>
+	<key>NSDownloadsFolderUsageDescription</key>
+	<string></string>
+	<key>NSFileProviderDomainUsageDescription</key>
+	<string></string>
+	<key>NSFileProviderPresenceUsageDescription</key>
+	<string></string>
+	<key>NSUbiquitousContainers</key>
+	<dict>
+		<key>iCloud.$(PRODUCT_BUNDLE_IDENTIFIER)</key>
+		<dict>
+			<key>NSUbiquitousContainerIsDocumentScopePublic</key>
+			<true/>
+			<key>NSUbiquitousContainerName</key>
+			<string>Logseq</string>
+			<key>NSUbiquitousContainerSupportedFolderLevels</key>
+			<string>None</string>
+		</dict>
+	</dict>
+	<key>UILaunchStoryboardName</key>
+	<string>LaunchScreen</string>
+	<key>UIMainStoryboardFile</key>
+	<string>Main</string>
+	<key>UIRequiredDeviceCapabilities</key>
+	<array>
+		<string>armv7</string>
+	</array>
+	<key>UISupportedInterfaceOrientations</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+	<key>UISupportedInterfaceOrientations~ipad</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationPortraitUpsideDown</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+	<key>UISupportsDocumentBrowser</key>
+	<true/>
+	<key>UIViewControllerBasedStatusBarAppearance</key>
+	<true/>
 </dict>
 </plist>

+ 0 - 4
ios/App/App/capacitor.config.json

@@ -14,9 +14,5 @@
 	},
 	"ios": {
 		"scheme": "Logseq"
-	},
-	"server": {
-		"url": "http://192.168.1.59:3001",
-		"cleartext": true
 	}
 }

+ 5 - 0
src/main/frontend/fs/capacitor_fs.cljs

@@ -11,6 +11,11 @@
             [promesa.core :as p]
             [clojure.string :as string]))
 
+(when (util/native-ios?)
+  (defn iOS-ensure-documents!
+    []
+    (.ensureDocuments util/ios-file-container)))
+
 (defn check-permission-android []
   (p/let [permission (.checkPermissions Filesystem)
           permission (-> permission

+ 25 - 23
src/main/frontend/mobile/util.cljs

@@ -24,6 +24,8 @@
   (.isPluginAvailable Capacitor name))
 
 (defonce folder-picker (registerPlugin "FolderPicker"))
+(when (native-ios?)
+  (defonce ios-file-container (registerPlugin "FileContainer")))
 
 (defn hide-splash []
   (.hide SplashScreen))
@@ -35,36 +37,36 @@
     :iPadPro10.5    {:width 834  :height 1112 :statusbar 40}
     :iPadAir10.5    {:width 834  :height 1112 :statusbar 40}
     :iPadAir10.9    {:width 820  :height 1180 :statusbar 40}
-    :iPad10.2	    {:width 810  :height 1080 :statusbar 40}
-    :iPadPro9.7	    {:width 768  :height 1024 :statusbar 40}
+    :iPad10.2       {:width 810  :height 1080 :statusbar 40}
+    :iPadPro9.7     {:width 768  :height 1024 :statusbar 40}
     :iPadmini9.7    {:width 768  :height 1024 :statusbar 40}
-    :iPadAir9.7	    {:width 768  :height 1024 :statusbar 40}
-    :iPad9.7	    {:width 768  :height 1024 :statusbar 40}
-    :iPadmini8.3	{:width 744  :height 1133 :statusbar 40}
-    :iPhone7Plus	{:width 476  :height 847  :statusbar 20}
+    :iPadAir9.7     {:width 768  :height 1024 :statusbar 40}
+    :iPad9.7        {:width 768  :height 1024 :statusbar 40}
+    :iPadmini8.3        {:width 744  :height 1133 :statusbar 40}
+    :iPhone7Plus        {:width 476  :height 847  :statusbar 20}
     :iPhone6sPlus   {:width 476  :height 847  :statusbar 20}
-    :iPhone6Plus	{:width 476  :height 847  :statusbar 20}
+    :iPhone6Plus        {:width 476  :height 847  :statusbar 20}
     :iPhone13ProMax {:width 428  :height 926  :statusbar 47}
     :iPhone12ProMax {:width 428  :height 926  :statusbar 47}
     :iPhone11ProMax {:width 414  :height 896  :statusbar 44}
-    :iPhone11	    {:width 414  :height 896  :statusbar 48}
-    :iPhoneXSMax	{:width 414  :height 896  :statusbar 48}
-    :iPhoneXR	    {:width 414  :height 896  :statusbar 48}
-    :iPhone8Plus	{:width 414  :height 736  :statusbar 20}
-    :iPhone13Pro	{:width 390  :height 844  :statusbar 47}
-    :iPhone13	    {:width 390  :height 844  :statusbar 47}
-    :iPhone12	    {:width 390  :height 844  :statusbar 47}
-    :iPhone12Pro	{:width 390  :height 844  :statusbar 47}
-    :iPhone11Pro	{:width 375  :height 812  :statusbar 44}
-    :iPhoneXS	    {:width 375  :height 812  :statusbar 44}
-    :iPhoneX	    {:width 375  :height 812  :statusbar 44}
-    :iPhone8	    {:width 375  :height 667  :statusbar 20}
-    :iPhone7	    {:width 375  :height 667  :statusbar 20}
-    :iPhone6s	    {:width 375  :height 667  :statusbar 20}
-    :iPhone6	    {:width 375  :height 667  :statusbar 20}
+    :iPhone11       {:width 414  :height 896  :statusbar 48}
+    :iPhoneXSMax        {:width 414  :height 896  :statusbar 48}
+    :iPhoneXR       {:width 414  :height 896  :statusbar 48}
+    :iPhone8Plus        {:width 414  :height 736  :statusbar 20}
+    :iPhone13Pro        {:width 390  :height 844  :statusbar 47}
+    :iPhone13       {:width 390  :height 844  :statusbar 47}
+    :iPhone12       {:width 390  :height 844  :statusbar 47}
+    :iPhone12Pro        {:width 390  :height 844  :statusbar 47}
+    :iPhone11Pro        {:width 375  :height 812  :statusbar 44}
+    :iPhoneXS       {:width 375  :height 812  :statusbar 44}
+    :iPhoneX        {:width 375  :height 812  :statusbar 44}
+    :iPhone8        {:width 375  :height 667  :statusbar 20}
+    :iPhone7        {:width 375  :height 667  :statusbar 20}
+    :iPhone6s       {:width 375  :height 667  :statusbar 20}
+    :iPhone6        {:width 375  :height 667  :statusbar 20}
     :iPhone13mini   {:width 375  :height 812  :statusbar 44}
     :iPhone12mini   {:width 375  :height 812  :statusbar 44}
-    :iPhoneSE4	    {:width 320  :height 568  :statusbar 20}
+    :iPhoneSE4      {:width 320  :height 568  :statusbar 20}
     :iPodtouch5     {:width 320  :height 568  :statusbar 20}}))
 
 (defn get-idevice-model