├── .gitignore ├── .swiftpm └── xcode │ └── package.xcworkspace │ └── contents.xcworkspacedata ├── Cartfile ├── Cartfile.resolved ├── Demo ├── Demo.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── Public │ ├── Examples │ │ ├── example0.xmind │ │ └── example1.xmind │ └── Sources │ │ └── ContentView.swift ├── XMindSDK-Demo-iOS │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Base.lproj │ │ └── LaunchScreen.storyboard │ ├── Info.plist │ └── SceneDelegate.swift └── XMindSDK-Demo-macOS │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json │ ├── Base.lproj │ └── Main.storyboard │ ├── Info.plist │ ├── Preview Content │ └── Preview Assets.xcassets │ │ └── Contents.json │ └── XMindSDK_Demo_macOS.entitlements ├── LICENSE ├── Package.resolved ├── Package.swift ├── README.md ├── Sources ├── Builder │ ├── Builders.swift │ └── ElementsBuilder.swift ├── Info.plist ├── Internal │ ├── Constants.swift │ ├── Crypto.swift │ ├── EncryptionData.swift │ ├── Manifest.swift │ ├── Metadata.swift │ └── TemporaryStorge.swift ├── XMind │ ├── Error.swift │ ├── Marker.swift │ ├── Point.swift │ ├── Relationship.swift │ ├── Sheet.swift │ ├── Theme.swift │ ├── Topic.swift │ └── Workbook.swift └── XMindSDK.h ├── XMindSDK.xcodeproj └── project.pbxproj ├── XMindSDK.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ ├── IDETemplateMacros.plist │ └── IDEWorkspaceChecks.plist └── doc └── main.md /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/swift,xcode,macos,carthage 3 | # Edit at https://www.gitignore.io/?templates=swift,xcode,macos,carthage 4 | 5 | ### Carthage ### 6 | # Carthage 7 | # 8 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 9 | Carthage/Checkouts 10 | 11 | Carthage/Build 12 | 13 | ### macOS ### 14 | # General 15 | .DS_Store 16 | .AppleDouble 17 | .LSOverride 18 | 19 | # Icon must end with two \r 20 | Icon 21 | 22 | # Thumbnails 23 | ._* 24 | 25 | # Files that might appear in the root of a volume 26 | .DocumentRevisions-V100 27 | .fseventsd 28 | .Spotlight-V100 29 | .TemporaryItems 30 | .Trashes 31 | .VolumeIcon.icns 32 | .com.apple.timemachine.donotpresent 33 | 34 | # Directories potentially created on remote AFP share 35 | .AppleDB 36 | .AppleDesktop 37 | Network Trash Folder 38 | Temporary Items 39 | .apdisk 40 | 41 | ### Swift ### 42 | # Xcode 43 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 44 | 45 | ## Build generated 46 | build/ 47 | DerivedData/ 48 | 49 | ## Various settings 50 | *.pbxuser 51 | !default.pbxuser 52 | *.mode1v3 53 | !default.mode1v3 54 | *.mode2v3 55 | !default.mode2v3 56 | *.perspectivev3 57 | !default.perspectivev3 58 | xcuserdata/ 59 | 60 | ## Other 61 | *.moved-aside 62 | *.xccheckout 63 | *.xcscmblueprint 64 | 65 | ## Obj-C/Swift specific 66 | *.hmap 67 | *.ipa 68 | *.dSYM.zip 69 | *.dSYM 70 | 71 | ## Playgrounds 72 | timeline.xctimeline 73 | playground.xcworkspace 74 | 75 | # Swift Package Manager 76 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 77 | # Packages/ 78 | # Package.pins 79 | # Package.resolved 80 | .build/ 81 | # Add this line if you want to avoid checking in Xcode SPM integration. 82 | # .swiftpm/xcode 83 | 84 | # CocoaPods 85 | # We recommend against adding the Pods directory to your .gitignore. However 86 | # you should judge for yourself, the pros and cons are mentioned at: 87 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 88 | # Pods/ 89 | # Add this line if you want to avoid checking in source code from the Xcode workspace 90 | # *.xcworkspace 91 | 92 | # Carthage 93 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 94 | # Carthage/Checkouts 95 | 96 | 97 | # Accio dependency management 98 | Dependencies/ 99 | .accio/ 100 | 101 | # fastlane 102 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 103 | # screenshots whenever they are needed. 104 | # For more information about the recommended setup visit: 105 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 106 | 107 | fastlane/report.xml 108 | fastlane/Preview.html 109 | fastlane/screenshots/**/*.png 110 | fastlane/test_output 111 | 112 | # Code Injection 113 | # After new code Injection tools there's a generated folder /iOSInjectionProject 114 | # https://github.com/johnno1962/injectionforxcode 115 | 116 | iOSInjectionProject/ 117 | 118 | ### Xcode ### 119 | # Xcode 120 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 121 | 122 | ## User settings 123 | 124 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 125 | 126 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 127 | 128 | ## Xcode Patch 129 | *.xcodeproj/* 130 | !*.xcodeproj/project.pbxproj 131 | !*.xcodeproj/xcshareddata/ 132 | !*.xcworkspace/contents.xcworkspacedata 133 | /*.gcno 134 | 135 | ### Xcode Patch ### 136 | **/xcshareddata/WorkspaceSettings.xcsettings 137 | 138 | # End of https://www.gitignore.io/api/swift,xcode,macos,carthage -------------------------------------------------------------------------------- /.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Cartfile: -------------------------------------------------------------------------------- 1 | github "weichsel/ZIPFoundation" ~> 0.9 2 | github "krzyzanowskim/CryptoSwift" ~> 1.3 -------------------------------------------------------------------------------- /Cartfile.resolved: -------------------------------------------------------------------------------- 1 | github "krzyzanowskim/CryptoSwift" "1.3.0" 2 | github "weichsel/ZIPFoundation" "0.9.11" 3 | -------------------------------------------------------------------------------- /Demo/Demo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0705DF1F23CC421F00BABCEC /* CryptoSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0705DF1E23CC421F00BABCEC /* CryptoSwift.framework */; }; 11 | 0705DF2223CC422400BABCEC /* ZIPFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0705DF2123CC422400BABCEC /* ZIPFoundation.framework */; }; 12 | 0705DF2423CC423400BABCEC /* XMindSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 07CABF62236FF51B00A50B58 /* XMindSDK.framework */; }; 13 | 0705DF2523CC423400BABCEC /* XMindSDK.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 07CABF62236FF51B00A50B58 /* XMindSDK.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 14 | 0777280423CC425200EDE052 /* ZIPFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0777280323CC425200EDE052 /* ZIPFoundation.framework */; }; 15 | 077E01B3237505E1000016BB /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077E01B2237505E1000016BB /* ContentView.swift */; }; 16 | 077E01B4237505E1000016BB /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077E01B2237505E1000016BB /* ContentView.swift */; }; 17 | 07BEC05C2373B73C00A94E7A /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07BEC05B2373B73C00A94E7A /* AppDelegate.swift */; }; 18 | 07BEC0602373B73D00A94E7A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 07BEC05F2373B73D00A94E7A /* Assets.xcassets */; }; 19 | 07BEC0632373B73D00A94E7A /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 07BEC0622373B73D00A94E7A /* Preview Assets.xcassets */; }; 20 | 07BEC0662373B73D00A94E7A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 07BEC0642373B73D00A94E7A /* Main.storyboard */; }; 21 | 07BEC0702373BA6700A94E7A /* example0.xmind in Resources */ = {isa = PBXBuildFile; fileRef = 07BEC06F2373BA6700A94E7A /* example0.xmind */; }; 22 | 07BEC0712373BA6700A94E7A /* example0.xmind in Resources */ = {isa = PBXBuildFile; fileRef = 07BEC06F2373BA6700A94E7A /* example0.xmind */; }; 23 | 07BEC0762373BD5500A94E7A /* XMindSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 07BEC0752373BD5500A94E7A /* XMindSDK.framework */; }; 24 | 07BEC0772373BD5500A94E7A /* XMindSDK.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 07BEC0752373BD5500A94E7A /* XMindSDK.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 25 | 07CABF51236FF4FB00A50B58 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07CABF50236FF4FB00A50B58 /* AppDelegate.swift */; }; 26 | 07CABF53236FF4FB00A50B58 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07CABF52236FF4FB00A50B58 /* SceneDelegate.swift */; }; 27 | 07CABF5A236FF4FB00A50B58 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 07CABF59236FF4FB00A50B58 /* Assets.xcassets */; }; 28 | 07CABF5D236FF4FB00A50B58 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 07CABF5B236FF4FB00A50B58 /* LaunchScreen.storyboard */; }; 29 | 07E117342398A5EA0042C083 /* example1.xmind in Resources */ = {isa = PBXBuildFile; fileRef = 07E117332398A5EA0042C083 /* example1.xmind */; }; 30 | 07E117352398A5EA0042C083 /* example1.xmind in Resources */ = {isa = PBXBuildFile; fileRef = 07E117332398A5EA0042C083 /* example1.xmind */; }; 31 | 07E1173F2398E78D0042C083 /* CryptoSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 07E1173E2398E78D0042C083 /* CryptoSwift.framework */; }; 32 | /* End PBXBuildFile section */ 33 | 34 | /* Begin PBXCopyFilesBuildPhase section */ 35 | 07BEC0782373BD5500A94E7A /* Embed Frameworks */ = { 36 | isa = PBXCopyFilesBuildPhase; 37 | buildActionMask = 2147483647; 38 | dstPath = ""; 39 | dstSubfolderSpec = 10; 40 | files = ( 41 | 07BEC0772373BD5500A94E7A /* XMindSDK.framework in Embed Frameworks */, 42 | ); 43 | name = "Embed Frameworks"; 44 | runOnlyForDeploymentPostprocessing = 0; 45 | }; 46 | 07CABF68236FF59400A50B58 /* Embed Frameworks */ = { 47 | isa = PBXCopyFilesBuildPhase; 48 | buildActionMask = 2147483647; 49 | dstPath = ""; 50 | dstSubfolderSpec = 10; 51 | files = ( 52 | 0705DF2523CC423400BABCEC /* XMindSDK.framework in Embed Frameworks */, 53 | ); 54 | name = "Embed Frameworks"; 55 | runOnlyForDeploymentPostprocessing = 0; 56 | }; 57 | /* End PBXCopyFilesBuildPhase section */ 58 | 59 | /* Begin PBXFileReference section */ 60 | 0705DF1E23CC421F00BABCEC /* CryptoSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CryptoSwift.framework; path = ../Carthage/Build/iOS/CryptoSwift.framework; sourceTree = ""; }; 61 | 0705DF2123CC422400BABCEC /* ZIPFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ZIPFoundation.framework; path = ../Carthage/Build/iOS/ZIPFoundation.framework; sourceTree = ""; }; 62 | 076F370823740AE500565A92 /* ZipArchive.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ZipArchive.framework; path = ../Carthage/Build/Mac/ZipArchive.framework; sourceTree = ""; }; 63 | 0777280323CC425200EDE052 /* ZIPFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ZIPFoundation.framework; path = ../Carthage/Build/Mac/ZIPFoundation.framework; sourceTree = ""; }; 64 | 077E01B2237505E1000016BB /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 65 | 07BEC0592373B73C00A94E7A /* XMindSDK-Demo-macOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "XMindSDK-Demo-macOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 66 | 07BEC05B2373B73C00A94E7A /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 67 | 07BEC05F2373B73D00A94E7A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 68 | 07BEC0622373B73D00A94E7A /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 69 | 07BEC0652373B73D00A94E7A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 70 | 07BEC0672373B73D00A94E7A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 71 | 07BEC0682373B73D00A94E7A /* XMindSDK_Demo_macOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = XMindSDK_Demo_macOS.entitlements; sourceTree = ""; }; 72 | 07BEC06F2373BA6700A94E7A /* example0.xmind */ = {isa = PBXFileReference; lastKnownFileType = file; path = example0.xmind; sourceTree = ""; }; 73 | 07BEC0752373BD5500A94E7A /* XMindSDK.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = XMindSDK.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 74 | 07BEC0792373BDD200A94E7A /* Zip.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Zip.framework; path = ../Carthage/Build/Mac/Zip.framework; sourceTree = ""; }; 75 | 07BEC07C2373BDDB00A94E7A /* Zip.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Zip.framework; path = ../Carthage/Build/iOS/Zip.framework; sourceTree = ""; }; 76 | 07BEC0832374095800A94E7A /* ZipArchive.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ZipArchive.framework; path = ../Carthage/Build/iOS/ZipArchive.framework; sourceTree = ""; }; 77 | 07CABF4E236FF4FB00A50B58 /* XMindSDK-Demo-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "XMindSDK-Demo-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 78 | 07CABF50236FF4FB00A50B58 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 79 | 07CABF52236FF4FB00A50B58 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; 80 | 07CABF59236FF4FB00A50B58 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 81 | 07CABF5C236FF4FB00A50B58 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 82 | 07CABF5E236FF4FB00A50B58 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 83 | 07CABF62236FF51B00A50B58 /* XMindSDK.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = XMindSDK.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 84 | 07E117332398A5EA0042C083 /* example1.xmind */ = {isa = PBXFileReference; lastKnownFileType = file; path = example1.xmind; sourceTree = ""; }; 85 | 07E1173E2398E78D0042C083 /* CryptoSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CryptoSwift.framework; path = ../Carthage/Build/Mac/CryptoSwift.framework; sourceTree = ""; }; 86 | /* End PBXFileReference section */ 87 | 88 | /* Begin PBXFrameworksBuildPhase section */ 89 | 07BEC0562373B73C00A94E7A /* Frameworks */ = { 90 | isa = PBXFrameworksBuildPhase; 91 | buildActionMask = 2147483647; 92 | files = ( 93 | 07E1173F2398E78D0042C083 /* CryptoSwift.framework in Frameworks */, 94 | 07BEC0762373BD5500A94E7A /* XMindSDK.framework in Frameworks */, 95 | 0777280423CC425200EDE052 /* ZIPFoundation.framework in Frameworks */, 96 | ); 97 | runOnlyForDeploymentPostprocessing = 0; 98 | }; 99 | 07CABF4B236FF4FB00A50B58 /* Frameworks */ = { 100 | isa = PBXFrameworksBuildPhase; 101 | buildActionMask = 2147483647; 102 | files = ( 103 | 0705DF1F23CC421F00BABCEC /* CryptoSwift.framework in Frameworks */, 104 | 0705DF2423CC423400BABCEC /* XMindSDK.framework in Frameworks */, 105 | 0705DF2223CC422400BABCEC /* ZIPFoundation.framework in Frameworks */, 106 | ); 107 | runOnlyForDeploymentPostprocessing = 0; 108 | }; 109 | /* End PBXFrameworksBuildPhase section */ 110 | 111 | /* Begin PBXGroup section */ 112 | 07BEC05A2373B73C00A94E7A /* XMindSDK-Demo-macOS */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | 07BEC05B2373B73C00A94E7A /* AppDelegate.swift */, 116 | 07BEC05F2373B73D00A94E7A /* Assets.xcassets */, 117 | 07BEC0642373B73D00A94E7A /* Main.storyboard */, 118 | 07BEC0672373B73D00A94E7A /* Info.plist */, 119 | 07BEC0682373B73D00A94E7A /* XMindSDK_Demo_macOS.entitlements */, 120 | 07BEC0612373B73D00A94E7A /* Preview Content */, 121 | ); 122 | path = "XMindSDK-Demo-macOS"; 123 | sourceTree = ""; 124 | }; 125 | 07BEC0612373B73D00A94E7A /* Preview Content */ = { 126 | isa = PBXGroup; 127 | children = ( 128 | 07BEC0622373B73D00A94E7A /* Preview Assets.xcassets */, 129 | ); 130 | path = "Preview Content"; 131 | sourceTree = ""; 132 | }; 133 | 07BEC06C2373B8DA00A94E7A /* Public */ = { 134 | isa = PBXGroup; 135 | children = ( 136 | 07BEC06E2373BA4000A94E7A /* Sources */, 137 | 07BEC06D2373BA3700A94E7A /* Examples */, 138 | ); 139 | path = Public; 140 | sourceTree = ""; 141 | }; 142 | 07BEC06D2373BA3700A94E7A /* Examples */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | 07E117332398A5EA0042C083 /* example1.xmind */, 146 | 07BEC06F2373BA6700A94E7A /* example0.xmind */, 147 | ); 148 | path = Examples; 149 | sourceTree = ""; 150 | }; 151 | 07BEC06E2373BA4000A94E7A /* Sources */ = { 152 | isa = PBXGroup; 153 | children = ( 154 | 077E01B2237505E1000016BB /* ContentView.swift */, 155 | ); 156 | path = Sources; 157 | sourceTree = ""; 158 | }; 159 | 07CABED5236FEFF700A50B58 = { 160 | isa = PBXGroup; 161 | children = ( 162 | 07BEC06C2373B8DA00A94E7A /* Public */, 163 | 07CABF4F236FF4FB00A50B58 /* XMindSDK-Demo-iOS */, 164 | 07BEC05A2373B73C00A94E7A /* XMindSDK-Demo-macOS */, 165 | 07CABF19236FF13C00A50B58 /* Products */, 166 | 07CABF2D236FF19700A50B58 /* Frameworks */, 167 | ); 168 | sourceTree = ""; 169 | }; 170 | 07CABF19236FF13C00A50B58 /* Products */ = { 171 | isa = PBXGroup; 172 | children = ( 173 | 07CABF4E236FF4FB00A50B58 /* XMindSDK-Demo-iOS.app */, 174 | 07BEC0592373B73C00A94E7A /* XMindSDK-Demo-macOS.app */, 175 | ); 176 | name = Products; 177 | sourceTree = ""; 178 | }; 179 | 07CABF2D236FF19700A50B58 /* Frameworks */ = { 180 | isa = PBXGroup; 181 | children = ( 182 | 0705DF2123CC422400BABCEC /* ZIPFoundation.framework */, 183 | 0777280323CC425200EDE052 /* ZIPFoundation.framework */, 184 | 07E1173E2398E78D0042C083 /* CryptoSwift.framework */, 185 | 0705DF1E23CC421F00BABCEC /* CryptoSwift.framework */, 186 | 07BEC0832374095800A94E7A /* ZipArchive.framework */, 187 | 076F370823740AE500565A92 /* ZipArchive.framework */, 188 | 07BEC0792373BDD200A94E7A /* Zip.framework */, 189 | 07BEC07C2373BDDB00A94E7A /* Zip.framework */, 190 | 07BEC0752373BD5500A94E7A /* XMindSDK.framework */, 191 | 07CABF62236FF51B00A50B58 /* XMindSDK.framework */, 192 | ); 193 | name = Frameworks; 194 | sourceTree = ""; 195 | }; 196 | 07CABF4F236FF4FB00A50B58 /* XMindSDK-Demo-iOS */ = { 197 | isa = PBXGroup; 198 | children = ( 199 | 07CABF50236FF4FB00A50B58 /* AppDelegate.swift */, 200 | 07CABF52236FF4FB00A50B58 /* SceneDelegate.swift */, 201 | 07CABF59236FF4FB00A50B58 /* Assets.xcassets */, 202 | 07CABF5B236FF4FB00A50B58 /* LaunchScreen.storyboard */, 203 | 07CABF5E236FF4FB00A50B58 /* Info.plist */, 204 | ); 205 | path = "XMindSDK-Demo-iOS"; 206 | sourceTree = ""; 207 | }; 208 | /* End PBXGroup section */ 209 | 210 | /* Begin PBXNativeTarget section */ 211 | 07BEC0582373B73C00A94E7A /* XMindSDK-Demo-macOS */ = { 212 | isa = PBXNativeTarget; 213 | buildConfigurationList = 07BEC06B2373B73D00A94E7A /* Build configuration list for PBXNativeTarget "XMindSDK-Demo-macOS" */; 214 | buildPhases = ( 215 | 07BEC0552373B73C00A94E7A /* Sources */, 216 | 07BEC0562373B73C00A94E7A /* Frameworks */, 217 | 07BEC0572373B73C00A94E7A /* Resources */, 218 | 07BEC0782373BD5500A94E7A /* Embed Frameworks */, 219 | 076F370B237410FC00565A92 /* Carthage */, 220 | ); 221 | buildRules = ( 222 | ); 223 | dependencies = ( 224 | ); 225 | name = "XMindSDK-Demo-macOS"; 226 | productName = "XMindSDK-Demo-macOS"; 227 | productReference = 07BEC0592373B73C00A94E7A /* XMindSDK-Demo-macOS.app */; 228 | productType = "com.apple.product-type.application"; 229 | }; 230 | 07CABF4D236FF4FB00A50B58 /* XMindSDK-Demo-iOS */ = { 231 | isa = PBXNativeTarget; 232 | buildConfigurationList = 07CABF61236FF4FB00A50B58 /* Build configuration list for PBXNativeTarget "XMindSDK-Demo-iOS" */; 233 | buildPhases = ( 234 | 07CABF4A236FF4FB00A50B58 /* Sources */, 235 | 07CABF4B236FF4FB00A50B58 /* Frameworks */, 236 | 07CABF4C236FF4FB00A50B58 /* Resources */, 237 | 07CABF68236FF59400A50B58 /* Embed Frameworks */, 238 | 07BEC0822373E72F00A94E7A /* Carthage */, 239 | ); 240 | buildRules = ( 241 | ); 242 | dependencies = ( 243 | ); 244 | name = "XMindSDK-Demo-iOS"; 245 | productName = "XMindSDK-Demo-iOS"; 246 | productReference = 07CABF4E236FF4FB00A50B58 /* XMindSDK-Demo-iOS.app */; 247 | productType = "com.apple.product-type.application"; 248 | }; 249 | /* End PBXNativeTarget section */ 250 | 251 | /* Begin PBXProject section */ 252 | 07CABED6236FEFF700A50B58 /* Project object */ = { 253 | isa = PBXProject; 254 | attributes = { 255 | LastSwiftUpdateCheck = 1120; 256 | LastUpgradeCheck = 1120; 257 | TargetAttributes = { 258 | 07BEC0582373B73C00A94E7A = { 259 | CreatedOnToolsVersion = 11.2; 260 | }; 261 | 07CABF4D236FF4FB00A50B58 = { 262 | CreatedOnToolsVersion = 11.1; 263 | }; 264 | }; 265 | }; 266 | buildConfigurationList = 07CABED9236FEFF700A50B58 /* Build configuration list for PBXProject "Demo" */; 267 | compatibilityVersion = "Xcode 9.3"; 268 | developmentRegion = en; 269 | hasScannedForEncodings = 0; 270 | knownRegions = ( 271 | en, 272 | Base, 273 | ); 274 | mainGroup = 07CABED5236FEFF700A50B58; 275 | productRefGroup = 07CABF19236FF13C00A50B58 /* Products */; 276 | projectDirPath = ""; 277 | projectRoot = ""; 278 | targets = ( 279 | 07CABF4D236FF4FB00A50B58 /* XMindSDK-Demo-iOS */, 280 | 07BEC0582373B73C00A94E7A /* XMindSDK-Demo-macOS */, 281 | ); 282 | }; 283 | /* End PBXProject section */ 284 | 285 | /* Begin PBXResourcesBuildPhase section */ 286 | 07BEC0572373B73C00A94E7A /* Resources */ = { 287 | isa = PBXResourcesBuildPhase; 288 | buildActionMask = 2147483647; 289 | files = ( 290 | 07BEC0712373BA6700A94E7A /* example0.xmind in Resources */, 291 | 07BEC0662373B73D00A94E7A /* Main.storyboard in Resources */, 292 | 07BEC0632373B73D00A94E7A /* Preview Assets.xcassets in Resources */, 293 | 07E117352398A5EA0042C083 /* example1.xmind in Resources */, 294 | 07BEC0602373B73D00A94E7A /* Assets.xcassets in Resources */, 295 | ); 296 | runOnlyForDeploymentPostprocessing = 0; 297 | }; 298 | 07CABF4C236FF4FB00A50B58 /* Resources */ = { 299 | isa = PBXResourcesBuildPhase; 300 | buildActionMask = 2147483647; 301 | files = ( 302 | 07BEC0702373BA6700A94E7A /* example0.xmind in Resources */, 303 | 07E117342398A5EA0042C083 /* example1.xmind in Resources */, 304 | 07CABF5D236FF4FB00A50B58 /* LaunchScreen.storyboard in Resources */, 305 | 07CABF5A236FF4FB00A50B58 /* Assets.xcassets in Resources */, 306 | ); 307 | runOnlyForDeploymentPostprocessing = 0; 308 | }; 309 | /* End PBXResourcesBuildPhase section */ 310 | 311 | /* Begin PBXShellScriptBuildPhase section */ 312 | 076F370B237410FC00565A92 /* Carthage */ = { 313 | isa = PBXShellScriptBuildPhase; 314 | buildActionMask = 2147483647; 315 | files = ( 316 | ); 317 | inputFileListPaths = ( 318 | ); 319 | inputPaths = ( 320 | "$(SRCROOT)/../Carthage/Build/Mac/ZIPFoundation.framework", 321 | "$(SRCROOT)/../Carthage/Build/Mac/CryptoSwift.framework", 322 | ); 323 | name = Carthage; 324 | outputFileListPaths = ( 325 | ); 326 | outputPaths = ( 327 | "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/ZIPFoundation.framework", 328 | "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/CryptoSwift.framework", 329 | ); 330 | runOnlyForDeploymentPostprocessing = 0; 331 | shellPath = /bin/sh; 332 | shellScript = "/usr/local/bin/carthage copy-frameworks\n"; 333 | }; 334 | 07BEC0822373E72F00A94E7A /* Carthage */ = { 335 | isa = PBXShellScriptBuildPhase; 336 | buildActionMask = 2147483647; 337 | files = ( 338 | ); 339 | inputFileListPaths = ( 340 | ); 341 | inputPaths = ( 342 | "$(SRCROOT)/../Carthage/Build/iOS/ZIPFoundation.framework", 343 | "$(SRCROOT)/../Carthage/Build/iOS/CryptoSwift.framework", 344 | ); 345 | name = Carthage; 346 | outputFileListPaths = ( 347 | ); 348 | outputPaths = ( 349 | "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/ZIPFoundation.framework", 350 | "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/CryptoSwift.framework", 351 | ); 352 | runOnlyForDeploymentPostprocessing = 0; 353 | shellPath = /bin/sh; 354 | shellScript = "/usr/local/bin/carthage copy-frameworks\n"; 355 | }; 356 | /* End PBXShellScriptBuildPhase section */ 357 | 358 | /* Begin PBXSourcesBuildPhase section */ 359 | 07BEC0552373B73C00A94E7A /* Sources */ = { 360 | isa = PBXSourcesBuildPhase; 361 | buildActionMask = 2147483647; 362 | files = ( 363 | 077E01B4237505E1000016BB /* ContentView.swift in Sources */, 364 | 07BEC05C2373B73C00A94E7A /* AppDelegate.swift in Sources */, 365 | ); 366 | runOnlyForDeploymentPostprocessing = 0; 367 | }; 368 | 07CABF4A236FF4FB00A50B58 /* Sources */ = { 369 | isa = PBXSourcesBuildPhase; 370 | buildActionMask = 2147483647; 371 | files = ( 372 | 077E01B3237505E1000016BB /* ContentView.swift in Sources */, 373 | 07CABF51236FF4FB00A50B58 /* AppDelegate.swift in Sources */, 374 | 07CABF53236FF4FB00A50B58 /* SceneDelegate.swift in Sources */, 375 | ); 376 | runOnlyForDeploymentPostprocessing = 0; 377 | }; 378 | /* End PBXSourcesBuildPhase section */ 379 | 380 | /* Begin PBXVariantGroup section */ 381 | 07BEC0642373B73D00A94E7A /* Main.storyboard */ = { 382 | isa = PBXVariantGroup; 383 | children = ( 384 | 07BEC0652373B73D00A94E7A /* Base */, 385 | ); 386 | name = Main.storyboard; 387 | sourceTree = ""; 388 | }; 389 | 07CABF5B236FF4FB00A50B58 /* LaunchScreen.storyboard */ = { 390 | isa = PBXVariantGroup; 391 | children = ( 392 | 07CABF5C236FF4FB00A50B58 /* Base */, 393 | ); 394 | name = LaunchScreen.storyboard; 395 | sourceTree = ""; 396 | }; 397 | /* End PBXVariantGroup section */ 398 | 399 | /* Begin XCBuildConfiguration section */ 400 | 07BEC0692373B73D00A94E7A /* Debug */ = { 401 | isa = XCBuildConfiguration; 402 | buildSettings = { 403 | ALWAYS_SEARCH_USER_PATHS = NO; 404 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 405 | CLANG_ANALYZER_NONNULL = YES; 406 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 407 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 408 | CLANG_CXX_LIBRARY = "libc++"; 409 | CLANG_ENABLE_MODULES = YES; 410 | CLANG_ENABLE_OBJC_ARC = YES; 411 | CLANG_ENABLE_OBJC_WEAK = YES; 412 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 413 | CLANG_WARN_BOOL_CONVERSION = YES; 414 | CLANG_WARN_COMMA = YES; 415 | CLANG_WARN_CONSTANT_CONVERSION = YES; 416 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 417 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 418 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 419 | CLANG_WARN_EMPTY_BODY = YES; 420 | CLANG_WARN_ENUM_CONVERSION = YES; 421 | CLANG_WARN_INFINITE_RECURSION = YES; 422 | CLANG_WARN_INT_CONVERSION = YES; 423 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 424 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 425 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 426 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 427 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 428 | CLANG_WARN_STRICT_PROTOTYPES = YES; 429 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 430 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 431 | CLANG_WARN_UNREACHABLE_CODE = YES; 432 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 433 | CODE_SIGN_ENTITLEMENTS = "XMindSDK-Demo-macOS/XMindSDK_Demo_macOS.entitlements"; 434 | CODE_SIGN_IDENTITY = "Apple Development"; 435 | CODE_SIGN_STYLE = Automatic; 436 | COMBINE_HIDPI_IMAGES = YES; 437 | COPY_PHASE_STRIP = NO; 438 | DEBUG_INFORMATION_FORMAT = dwarf; 439 | DEVELOPMENT_ASSET_PATHS = "\"XMindSDK-Demo-macOS/Preview Content\""; 440 | DEVELOPMENT_TEAM = 4WV38P2X5K; 441 | ENABLE_HARDENED_RUNTIME = YES; 442 | ENABLE_PREVIEWS = YES; 443 | ENABLE_STRICT_OBJC_MSGSEND = YES; 444 | ENABLE_TESTABILITY = YES; 445 | FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../Carthage/Build/Mac"; 446 | GCC_C_LANGUAGE_STANDARD = gnu11; 447 | GCC_DYNAMIC_NO_PIC = NO; 448 | GCC_NO_COMMON_BLOCKS = YES; 449 | GCC_OPTIMIZATION_LEVEL = 0; 450 | GCC_PREPROCESSOR_DEFINITIONS = ( 451 | "DEBUG=1", 452 | "$(inherited)", 453 | ); 454 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 455 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 456 | GCC_WARN_UNDECLARED_SELECTOR = YES; 457 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 458 | GCC_WARN_UNUSED_FUNCTION = YES; 459 | GCC_WARN_UNUSED_VARIABLE = YES; 460 | INFOPLIST_FILE = "XMindSDK-Demo-macOS/Info.plist"; 461 | LD_RUNPATH_SEARCH_PATHS = ( 462 | "$(inherited)", 463 | "@executable_path/../Frameworks", 464 | ); 465 | MACOSX_DEPLOYMENT_TARGET = 10.15; 466 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 467 | MTL_FAST_MATH = YES; 468 | ONLY_ACTIVE_ARCH = YES; 469 | PRODUCT_BUNDLE_IDENTIFIER = "net.xmind.XMindSDK-Demo-macOS"; 470 | PRODUCT_NAME = "$(TARGET_NAME)"; 471 | SDKROOT = macosx; 472 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 473 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 474 | SWIFT_VERSION = 5.0; 475 | }; 476 | name = Debug; 477 | }; 478 | 07BEC06A2373B73D00A94E7A /* Release */ = { 479 | isa = XCBuildConfiguration; 480 | buildSettings = { 481 | ALWAYS_SEARCH_USER_PATHS = NO; 482 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 483 | CLANG_ANALYZER_NONNULL = YES; 484 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 485 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 486 | CLANG_CXX_LIBRARY = "libc++"; 487 | CLANG_ENABLE_MODULES = YES; 488 | CLANG_ENABLE_OBJC_ARC = YES; 489 | CLANG_ENABLE_OBJC_WEAK = YES; 490 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 491 | CLANG_WARN_BOOL_CONVERSION = YES; 492 | CLANG_WARN_COMMA = YES; 493 | CLANG_WARN_CONSTANT_CONVERSION = YES; 494 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 495 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 496 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 497 | CLANG_WARN_EMPTY_BODY = YES; 498 | CLANG_WARN_ENUM_CONVERSION = YES; 499 | CLANG_WARN_INFINITE_RECURSION = YES; 500 | CLANG_WARN_INT_CONVERSION = YES; 501 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 502 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 503 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 504 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 505 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 506 | CLANG_WARN_STRICT_PROTOTYPES = YES; 507 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 508 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 509 | CLANG_WARN_UNREACHABLE_CODE = YES; 510 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 511 | CODE_SIGN_ENTITLEMENTS = "XMindSDK-Demo-macOS/XMindSDK_Demo_macOS.entitlements"; 512 | CODE_SIGN_IDENTITY = "Apple Development"; 513 | CODE_SIGN_STYLE = Automatic; 514 | COMBINE_HIDPI_IMAGES = YES; 515 | COPY_PHASE_STRIP = NO; 516 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 517 | DEVELOPMENT_ASSET_PATHS = "\"XMindSDK-Demo-macOS/Preview Content\""; 518 | DEVELOPMENT_TEAM = 4WV38P2X5K; 519 | ENABLE_HARDENED_RUNTIME = YES; 520 | ENABLE_NS_ASSERTIONS = NO; 521 | ENABLE_PREVIEWS = YES; 522 | ENABLE_STRICT_OBJC_MSGSEND = YES; 523 | FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../Carthage/Build/Mac"; 524 | GCC_C_LANGUAGE_STANDARD = gnu11; 525 | GCC_NO_COMMON_BLOCKS = YES; 526 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 527 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 528 | GCC_WARN_UNDECLARED_SELECTOR = YES; 529 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 530 | GCC_WARN_UNUSED_FUNCTION = YES; 531 | GCC_WARN_UNUSED_VARIABLE = YES; 532 | INFOPLIST_FILE = "XMindSDK-Demo-macOS/Info.plist"; 533 | LD_RUNPATH_SEARCH_PATHS = ( 534 | "$(inherited)", 535 | "@executable_path/../Frameworks", 536 | ); 537 | MACOSX_DEPLOYMENT_TARGET = 10.15; 538 | MTL_ENABLE_DEBUG_INFO = NO; 539 | MTL_FAST_MATH = YES; 540 | PRODUCT_BUNDLE_IDENTIFIER = "net.xmind.XMindSDK-Demo-macOS"; 541 | PRODUCT_NAME = "$(TARGET_NAME)"; 542 | SDKROOT = macosx; 543 | SWIFT_COMPILATION_MODE = wholemodule; 544 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 545 | SWIFT_VERSION = 5.0; 546 | }; 547 | name = Release; 548 | }; 549 | 07CABEDA236FEFF700A50B58 /* Debug */ = { 550 | isa = XCBuildConfiguration; 551 | buildSettings = { 552 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 553 | CLANG_WARN_BOOL_CONVERSION = YES; 554 | CLANG_WARN_COMMA = YES; 555 | CLANG_WARN_CONSTANT_CONVERSION = YES; 556 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 557 | CLANG_WARN_EMPTY_BODY = YES; 558 | CLANG_WARN_ENUM_CONVERSION = YES; 559 | CLANG_WARN_INFINITE_RECURSION = YES; 560 | CLANG_WARN_INT_CONVERSION = YES; 561 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 562 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 563 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 564 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 565 | CLANG_WARN_STRICT_PROTOTYPES = YES; 566 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 567 | CLANG_WARN_UNREACHABLE_CODE = YES; 568 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 569 | ENABLE_STRICT_OBJC_MSGSEND = YES; 570 | ENABLE_TESTABILITY = YES; 571 | GCC_NO_COMMON_BLOCKS = YES; 572 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 573 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 574 | GCC_WARN_UNDECLARED_SELECTOR = YES; 575 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 576 | GCC_WARN_UNUSED_FUNCTION = YES; 577 | GCC_WARN_UNUSED_VARIABLE = YES; 578 | ONLY_ACTIVE_ARCH = YES; 579 | }; 580 | name = Debug; 581 | }; 582 | 07CABEDB236FEFF700A50B58 /* Release */ = { 583 | isa = XCBuildConfiguration; 584 | buildSettings = { 585 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 586 | CLANG_WARN_BOOL_CONVERSION = YES; 587 | CLANG_WARN_COMMA = YES; 588 | CLANG_WARN_CONSTANT_CONVERSION = YES; 589 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 590 | CLANG_WARN_EMPTY_BODY = YES; 591 | CLANG_WARN_ENUM_CONVERSION = YES; 592 | CLANG_WARN_INFINITE_RECURSION = YES; 593 | CLANG_WARN_INT_CONVERSION = YES; 594 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 595 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 596 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 597 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 598 | CLANG_WARN_STRICT_PROTOTYPES = YES; 599 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 600 | CLANG_WARN_UNREACHABLE_CODE = YES; 601 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 602 | ENABLE_STRICT_OBJC_MSGSEND = YES; 603 | GCC_NO_COMMON_BLOCKS = YES; 604 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 605 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 606 | GCC_WARN_UNDECLARED_SELECTOR = YES; 607 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 608 | GCC_WARN_UNUSED_FUNCTION = YES; 609 | GCC_WARN_UNUSED_VARIABLE = YES; 610 | }; 611 | name = Release; 612 | }; 613 | 07CABF5F236FF4FB00A50B58 /* Debug */ = { 614 | isa = XCBuildConfiguration; 615 | buildSettings = { 616 | ALWAYS_SEARCH_USER_PATHS = NO; 617 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 618 | CLANG_ANALYZER_NONNULL = YES; 619 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 620 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 621 | CLANG_CXX_LIBRARY = "libc++"; 622 | CLANG_ENABLE_MODULES = YES; 623 | CLANG_ENABLE_OBJC_ARC = YES; 624 | CLANG_ENABLE_OBJC_WEAK = YES; 625 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 626 | CLANG_WARN_BOOL_CONVERSION = YES; 627 | CLANG_WARN_COMMA = YES; 628 | CLANG_WARN_CONSTANT_CONVERSION = YES; 629 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 630 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 631 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 632 | CLANG_WARN_EMPTY_BODY = YES; 633 | CLANG_WARN_ENUM_CONVERSION = YES; 634 | CLANG_WARN_INFINITE_RECURSION = YES; 635 | CLANG_WARN_INT_CONVERSION = YES; 636 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 637 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 638 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 639 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 640 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 641 | CLANG_WARN_STRICT_PROTOTYPES = YES; 642 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 643 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 644 | CLANG_WARN_UNREACHABLE_CODE = YES; 645 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 646 | CODE_SIGN_STYLE = Automatic; 647 | COPY_PHASE_STRIP = NO; 648 | DEBUG_INFORMATION_FORMAT = dwarf; 649 | DEVELOPMENT_TEAM = 4WV38P2X5K; 650 | ENABLE_STRICT_OBJC_MSGSEND = YES; 651 | ENABLE_TESTABILITY = YES; 652 | FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../Carthage/Build/iOS"; 653 | GCC_C_LANGUAGE_STANDARD = gnu11; 654 | GCC_DYNAMIC_NO_PIC = NO; 655 | GCC_NO_COMMON_BLOCKS = YES; 656 | GCC_OPTIMIZATION_LEVEL = 0; 657 | GCC_PREPROCESSOR_DEFINITIONS = ( 658 | "DEBUG=1", 659 | "$(inherited)", 660 | ); 661 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 662 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 663 | GCC_WARN_UNDECLARED_SELECTOR = YES; 664 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 665 | GCC_WARN_UNUSED_FUNCTION = YES; 666 | GCC_WARN_UNUSED_VARIABLE = YES; 667 | INFOPLIST_FILE = "XMindSDK-Demo-iOS/Info.plist"; 668 | IPHONEOS_DEPLOYMENT_TARGET = 13.1; 669 | LD_RUNPATH_SEARCH_PATHS = ( 670 | "$(inherited)", 671 | "@executable_path/Frameworks", 672 | ); 673 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 674 | MTL_FAST_MATH = YES; 675 | ONLY_ACTIVE_ARCH = YES; 676 | PRODUCT_BUNDLE_IDENTIFIER = "net.xmind.XMindSDK-Demo-iOS"; 677 | PRODUCT_NAME = "$(TARGET_NAME)"; 678 | SDKROOT = iphoneos; 679 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 680 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 681 | SWIFT_VERSION = 5.0; 682 | TARGETED_DEVICE_FAMILY = "1,2"; 683 | }; 684 | name = Debug; 685 | }; 686 | 07CABF60236FF4FB00A50B58 /* Release */ = { 687 | isa = XCBuildConfiguration; 688 | buildSettings = { 689 | ALWAYS_SEARCH_USER_PATHS = NO; 690 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 691 | CLANG_ANALYZER_NONNULL = YES; 692 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 693 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 694 | CLANG_CXX_LIBRARY = "libc++"; 695 | CLANG_ENABLE_MODULES = YES; 696 | CLANG_ENABLE_OBJC_ARC = YES; 697 | CLANG_ENABLE_OBJC_WEAK = YES; 698 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 699 | CLANG_WARN_BOOL_CONVERSION = YES; 700 | CLANG_WARN_COMMA = YES; 701 | CLANG_WARN_CONSTANT_CONVERSION = YES; 702 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 703 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 704 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 705 | CLANG_WARN_EMPTY_BODY = YES; 706 | CLANG_WARN_ENUM_CONVERSION = YES; 707 | CLANG_WARN_INFINITE_RECURSION = YES; 708 | CLANG_WARN_INT_CONVERSION = YES; 709 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 710 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 711 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 712 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 713 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 714 | CLANG_WARN_STRICT_PROTOTYPES = YES; 715 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 716 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 717 | CLANG_WARN_UNREACHABLE_CODE = YES; 718 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 719 | CODE_SIGN_STYLE = Automatic; 720 | COPY_PHASE_STRIP = NO; 721 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 722 | DEVELOPMENT_TEAM = 4WV38P2X5K; 723 | ENABLE_NS_ASSERTIONS = NO; 724 | ENABLE_STRICT_OBJC_MSGSEND = YES; 725 | FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../Carthage/Build/iOS"; 726 | GCC_C_LANGUAGE_STANDARD = gnu11; 727 | GCC_NO_COMMON_BLOCKS = YES; 728 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 729 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 730 | GCC_WARN_UNDECLARED_SELECTOR = YES; 731 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 732 | GCC_WARN_UNUSED_FUNCTION = YES; 733 | GCC_WARN_UNUSED_VARIABLE = YES; 734 | INFOPLIST_FILE = "XMindSDK-Demo-iOS/Info.plist"; 735 | IPHONEOS_DEPLOYMENT_TARGET = 13.1; 736 | LD_RUNPATH_SEARCH_PATHS = ( 737 | "$(inherited)", 738 | "@executable_path/Frameworks", 739 | ); 740 | MTL_ENABLE_DEBUG_INFO = NO; 741 | MTL_FAST_MATH = YES; 742 | PRODUCT_BUNDLE_IDENTIFIER = "net.xmind.XMindSDK-Demo-iOS"; 743 | PRODUCT_NAME = "$(TARGET_NAME)"; 744 | SDKROOT = iphoneos; 745 | SWIFT_COMPILATION_MODE = wholemodule; 746 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 747 | SWIFT_VERSION = 5.0; 748 | TARGETED_DEVICE_FAMILY = "1,2"; 749 | VALIDATE_PRODUCT = YES; 750 | }; 751 | name = Release; 752 | }; 753 | /* End XCBuildConfiguration section */ 754 | 755 | /* Begin XCConfigurationList section */ 756 | 07BEC06B2373B73D00A94E7A /* Build configuration list for PBXNativeTarget "XMindSDK-Demo-macOS" */ = { 757 | isa = XCConfigurationList; 758 | buildConfigurations = ( 759 | 07BEC0692373B73D00A94E7A /* Debug */, 760 | 07BEC06A2373B73D00A94E7A /* Release */, 761 | ); 762 | defaultConfigurationIsVisible = 0; 763 | defaultConfigurationName = Release; 764 | }; 765 | 07CABED9236FEFF700A50B58 /* Build configuration list for PBXProject "Demo" */ = { 766 | isa = XCConfigurationList; 767 | buildConfigurations = ( 768 | 07CABEDA236FEFF700A50B58 /* Debug */, 769 | 07CABEDB236FEFF700A50B58 /* Release */, 770 | ); 771 | defaultConfigurationIsVisible = 0; 772 | defaultConfigurationName = Release; 773 | }; 774 | 07CABF61236FF4FB00A50B58 /* Build configuration list for PBXNativeTarget "XMindSDK-Demo-iOS" */ = { 775 | isa = XCConfigurationList; 776 | buildConfigurations = ( 777 | 07CABF5F236FF4FB00A50B58 /* Debug */, 778 | 07CABF60236FF4FB00A50B58 /* Release */, 779 | ); 780 | defaultConfigurationIsVisible = 0; 781 | defaultConfigurationName = Release; 782 | }; 783 | /* End XCConfigurationList section */ 784 | }; 785 | rootObject = 07CABED6236FEFF700A50B58 /* Project object */; 786 | } 787 | -------------------------------------------------------------------------------- /Demo/Demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Demo/Demo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Demo/Public/Examples/example0.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xmindltd/xmind-sdk-swift/9c23622c6712b43db4361ecd0f33f768b474a685/Demo/Public/Examples/example0.xmind -------------------------------------------------------------------------------- /Demo/Public/Examples/example1.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xmindltd/xmind-sdk-swift/9c23622c6712b43db4361ecd0f33f768b474a685/Demo/Public/Examples/example1.xmind -------------------------------------------------------------------------------- /Demo/Public/Sources/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // Demo 4 | // 5 | // Created by CY H on 2019/11/8. 6 | // 7 | // Copyright © 2019 XMind. 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | 28 | import SwiftUI 29 | import XMindSDK 30 | 31 | /// 32 | /// The example0.xmind file has no password. 33 | /// The password of example1.xmind file is "123456". 34 | 35 | struct Row: Identifiable { 36 | let id: String 37 | let title: String 38 | let indentLevel: Int 39 | } 40 | 41 | struct TopicCell: View { 42 | 43 | let row: Row 44 | 45 | private var _title: String { 46 | return "| " + String(repeating: " - ", count: row.indentLevel) + row.title 47 | } 48 | 49 | var body: some View { 50 | Text(_title) 51 | } 52 | } 53 | 54 | struct WorkbookView: View { 55 | 56 | let loadedWorkbook: Workbook 57 | 58 | private func makeRows(from topic: Topic, indentLevel: Int) -> [Row] { 59 | var rows = [Row]() 60 | rows.append(Row(id: topic.id, title: topic.title ?? "", indentLevel: indentLevel)) 61 | if let attachedChildren = topic.children?.attached { 62 | for topic in attachedChildren { 63 | rows.append(contentsOf: makeRows(from: topic, indentLevel: indentLevel + 1)) 64 | } 65 | } 66 | return rows 67 | } 68 | 69 | private func makeRows(from sheet: Sheet) -> [Row] { 70 | var rows = [Row]() 71 | rows.append(Row(id: sheet.id, title: sheet.title, indentLevel: 0)) 72 | rows.append(contentsOf: makeRows(from: sheet.rootTopic, indentLevel: 1)) 73 | return rows 74 | } 75 | 76 | private func makeRows() -> [Row] { 77 | var rows = [Row]() 78 | 79 | for sheet in loadedWorkbook.allSheets { 80 | rows.append(contentsOf: makeRows(from: sheet)) 81 | } 82 | 83 | return rows 84 | } 85 | 86 | var body: some View { 87 | List(makeRows()) { 88 | TopicCell(row: $0) 89 | } 90 | } 91 | } 92 | 93 | struct ContentView: View { 94 | 95 | private var example0Workbook: Workbook { 96 | guard let filePath = Bundle.main.path(forResource: "example0", ofType: "xmind") else { fatalError() } 97 | do { 98 | let wb = try Workbook.open(filePath: filePath) 99 | try wb.loadManifest() 100 | try wb.loadContent() 101 | 102 | return wb 103 | 104 | } catch let error { 105 | print(error) 106 | fatalError() 107 | } 108 | } 109 | 110 | private var builtWorkbook: Workbook { 111 | return try! workbook { 112 | topic(title: "Apple") { 113 | topic(title: "Hardware") { 114 | topic(title: "iPhone") { 115 | topic(title: "iPhone 6") 116 | topic(title: "iPhone 7 Plus") 117 | topic(title: "iPhone 8") 118 | topic(title: "iPhone XS Max") 119 | } 120 | topic(title: "Mac") { 121 | topic(title: "MacBook Pro") 122 | topic(title: "Mac mini") 123 | topic(title: "Mac Pro") 124 | } 125 | } 126 | 127 | topic(title: "Software") { 128 | topic(title: "Xcode") 129 | topic(title: "Siri") 130 | } 131 | } 132 | } 133 | } 134 | 135 | var body: some View { 136 | WorkbookView(loadedWorkbook: builtWorkbook) 137 | } 138 | } 139 | 140 | 141 | struct ContentView_Previews: PreviewProvider { 142 | static var previews: some View { 143 | ContentView() 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /Demo/XMindSDK-Demo-iOS/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // XMindSDK-Demo-iOS 4 | // 5 | // Created by CY H on 2019/11/4. 6 | // 7 | // Copyright © 2019 XMind. 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | 28 | import UIKit 29 | 30 | @UIApplicationMain 31 | class AppDelegate: UIResponder, UIApplicationDelegate { 32 | 33 | 34 | 35 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 36 | // Override point for customization after application launch. 37 | return true 38 | } 39 | 40 | // MARK: UISceneSession Lifecycle 41 | 42 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 43 | // Called when a new scene session is being created. 44 | // Use this method to select a configuration to create the new scene with. 45 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 46 | } 47 | 48 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 49 | // Called when the user discards a scene session. 50 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 51 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 52 | } 53 | 54 | 55 | } 56 | 57 | -------------------------------------------------------------------------------- /Demo/XMindSDK-Demo-iOS/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /Demo/XMindSDK-Demo-iOS/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Demo/XMindSDK-Demo-iOS/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Demo/XMindSDK-Demo-iOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | UISceneConfigurations 28 | 29 | UIWindowSceneSessionRoleApplication 30 | 31 | 32 | UISceneConfigurationName 33 | Default Configuration 34 | UISceneDelegateClassName 35 | $(PRODUCT_MODULE_NAME).SceneDelegate 36 | 37 | 38 | 39 | 40 | UILaunchStoryboardName 41 | LaunchScreen 42 | UIRequiredDeviceCapabilities 43 | 44 | armv7 45 | 46 | UISupportedInterfaceOrientations 47 | 48 | UIInterfaceOrientationPortrait 49 | UIInterfaceOrientationLandscapeLeft 50 | UIInterfaceOrientationLandscapeRight 51 | 52 | UISupportedInterfaceOrientations~ipad 53 | 54 | UIInterfaceOrientationPortrait 55 | UIInterfaceOrientationPortraitUpsideDown 56 | UIInterfaceOrientationLandscapeLeft 57 | UIInterfaceOrientationLandscapeRight 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Demo/XMindSDK-Demo-iOS/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.swift 3 | // XMindSDK-Demo-iOS 4 | // 5 | // Created by CY H on 2019/11/4. 6 | // 7 | // Copyright © 2019 XMind. 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | 28 | import UIKit 29 | import SwiftUI 30 | 31 | class SceneDelegate: UIResponder, UIWindowSceneDelegate { 32 | 33 | var window: UIWindow? 34 | 35 | 36 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 37 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. 38 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. 39 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). 40 | 41 | // Create the SwiftUI view that provides the window contents. 42 | let contentView = ContentView() 43 | 44 | // Use a UIHostingController as window root view controller. 45 | if let windowScene = scene as? UIWindowScene { 46 | let window = UIWindow(windowScene: windowScene) 47 | window.rootViewController = UIHostingController(rootView: contentView) 48 | self.window = window 49 | window.makeKeyAndVisible() 50 | } 51 | } 52 | 53 | func sceneDidDisconnect(_ scene: UIScene) { 54 | // Called as the scene is being released by the system. 55 | // This occurs shortly after the scene enters the background, or when its session is discarded. 56 | // Release any resources associated with this scene that can be re-created the next time the scene connects. 57 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). 58 | } 59 | 60 | func sceneDidBecomeActive(_ scene: UIScene) { 61 | // Called when the scene has moved from an inactive state to an active state. 62 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 63 | } 64 | 65 | func sceneWillResignActive(_ scene: UIScene) { 66 | // Called when the scene will move from an active state to an inactive state. 67 | // This may occur due to temporary interruptions (ex. an incoming phone call). 68 | } 69 | 70 | func sceneWillEnterForeground(_ scene: UIScene) { 71 | // Called as the scene transitions from the background to the foreground. 72 | // Use this method to undo the changes made on entering the background. 73 | } 74 | 75 | func sceneDidEnterBackground(_ scene: UIScene) { 76 | // Called as the scene transitions from the foreground to the background. 77 | // Use this method to save data, release shared resources, and store enough scene-specific state information 78 | // to restore the scene back to its current state. 79 | } 80 | 81 | 82 | } 83 | 84 | -------------------------------------------------------------------------------- /Demo/XMindSDK-Demo-macOS/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // XMindSDK-Demo-macOS 4 | // 5 | // Created by CY H on 2019/11/7. 6 | // 7 | // Copyright © 2019 XMind. 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | 28 | import Cocoa 29 | import SwiftUI 30 | 31 | @NSApplicationMain 32 | class AppDelegate: NSObject, NSApplicationDelegate { 33 | 34 | var window: NSWindow! 35 | 36 | 37 | func applicationDidFinishLaunching(_ aNotification: Notification) { 38 | // Create the SwiftUI view that provides the window contents. 39 | let contentView = ContentView() 40 | 41 | // Create the window and set the content view. 42 | window = NSWindow( 43 | contentRect: NSRect(x: 0, y: 0, width: 480, height: 300), 44 | styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView], 45 | backing: .buffered, defer: false) 46 | window.center() 47 | window.setFrameAutosaveName("Main Window") 48 | window.contentView = NSHostingView(rootView: contentView) 49 | window.makeKeyAndOrderFront(nil) 50 | } 51 | 52 | func applicationWillTerminate(_ aNotification: Notification) { 53 | // Insert code here to tear down your application 54 | } 55 | 56 | 57 | } 58 | 59 | -------------------------------------------------------------------------------- /Demo/XMindSDK-Demo-macOS/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /Demo/XMindSDK-Demo-macOS/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Demo/XMindSDK-Demo-macOS/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | Default 529 | 530 | 531 | 532 | 533 | 534 | 535 | Left to Right 536 | 537 | 538 | 539 | 540 | 541 | 542 | Right to Left 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | Default 554 | 555 | 556 | 557 | 558 | 559 | 560 | Left to Right 561 | 562 | 563 | 564 | 565 | 566 | 567 | Right to Left 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | -------------------------------------------------------------------------------- /Demo/XMindSDK-Demo-macOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSMainStoryboardFile 26 | Main 27 | NSPrincipalClass 28 | NSApplication 29 | NSSupportsAutomaticTermination 30 | 31 | NSSupportsSuddenTermination 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /Demo/XMindSDK-Demo-macOS/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Demo/XMindSDK-Demo-macOS/XMindSDK_Demo_macOS.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandcontainer 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright © 2019 XMind. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "object": { 3 | "pins": [ 4 | { 5 | "package": "CryptoSwift", 6 | "repositoryURL": "https://github.com/krzyzanowskim/CryptoSwift.git", 7 | "state": { 8 | "branch": null, 9 | "revision": "a44caef0550c346e0ab9172f7c9a3852c1833599", 10 | "version": "1.3.0" 11 | } 12 | }, 13 | { 14 | "package": "ZIPFoundation", 15 | "repositoryURL": "https://github.com/weichsel/ZIPFoundation.git", 16 | "state": { 17 | "branch": null, 18 | "revision": "3f38d518c5e41f1cf25ff6a1d28c46db5e79a0b9", 19 | "version": "0.9.10" 20 | } 21 | } 22 | ] 23 | }, 24 | "version": 1 25 | } 26 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.1 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "XMindSDK", 8 | platforms: [ 9 | .iOS(.v9), 10 | .macOS(.v10_11), 11 | ], 12 | products: [ 13 | .library( 14 | name: "XMindSDK", 15 | targets: ["XMindSDK"]), 16 | ], 17 | dependencies: [ 18 | .package(url: "https://github.com/weichsel/ZIPFoundation.git", .upToNextMajor(from: "0.9.0")), 19 | .package(url: "https://github.com/krzyzanowskim/CryptoSwift.git", .upToNextMinor(from: "1.3.0")) 20 | ], 21 | targets: [ 22 | .target( 23 | name: "XMindSDK", 24 | dependencies:[ 25 | "ZIPFoundation", 26 | "CryptoSwift" 27 | ], 28 | path: "Sources"), 29 | ] 30 | ) 31 | 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # XMind SDK in Swift 2 | 3 | [![Swift Package Manager compatible](https://img.shields.io/badge/Swift%20Package%20Manager-compatible-brightgreen.svg)](https://github.com/apple/swift-package-manager) 4 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 5 | [![Language](https://img.shields.io/badge/language-Swift-orange.svg)]() 6 | 7 | This SDK enables you to create and modify xmind(`.xmind`) files, and it's written in swift. 8 | 9 | Supported Platforms: 10 | 11 | - iOS 9+ 12 | 13 | - macOS 10.11+ 14 | 15 | 16 | 17 | ## Structure of XMind files 18 | 19 | XMind file is a zip file which contains several components, including manifest, metadata, sheets and resources. 20 | 21 | Resources contains all the resources of this xmind file that like images. 22 | 23 | Metadata represents the version of xmind file and the creator. 24 | 25 | Sheets contains all of the topics that belong to the each sheets(canvas). 26 | 27 | Manifest lists primary files that contained in this xmind file. 28 | 29 | 30 | 31 | ## Usage 32 | 33 | If you create a new xmind file, you can directly operate sheets and topics after initializing a `Workbook` instance that represents a xmind file. 34 | 35 | If you open an existing xmind file. You need call `public func loadManifest()` of `Workbook` after initializing a workbook to load some base informations. And now you can access the `passwordHint` to read and write the password hint. then, you need call `public func loadContent(password: String? = nil)` to load the metadata and sheets. When it's loaded, you can operate sheets and topics. 36 | 37 | 38 | 39 | ### Simple 40 | 41 | ```swift 42 | import XMindSDK 43 | 44 | ... 45 | ... 46 | 47 | let wb = try Workbook.open(filePath: filePath)// This file path which contains an existing xmind file. 48 | try wb.loadManifest() 49 | try wb.loadContent(password: "123456") 50 | 51 | let root = wb.allSheets.first!.rootTopic 52 | 53 | let sub1 = root.addSubTopic("Sub Topic 1") 54 | let sub2 = root.addSubTopic("Sub Topic 2") 55 | let sub3 = root.addSubTopic("Sub Topic 3") 56 | 57 | sub3.addSubTopic("Topic 4") 58 | sub3.addSubTopic("Topic 5") 59 | 60 | sub2.addMarker(Marker.Arrow.refresh) 61 | root.addMarker(Marker.Flag.darkBlue) 62 | sub1.addMarker(Marker.Priority.p2) 63 | 64 | try wb.save(to: filePath, password: "123456") 65 | ``` 66 | 67 | 68 | ### Fast Creating 69 | 70 | ```swift 71 | import XMindSDK 72 | 73 | ... 74 | ... 75 | 76 | let wb = try! workbook { 77 | topic(title: "Apple") { 78 | topic(title: "Hardware") { 79 | topic(title: "iPhone") { 80 | topic(title: "iPhone 6") 81 | topic(title: "iPhone 7 Plus") 82 | topic(title: "iPhone 8") 83 | topic(title: "iPhone XS Max") 84 | } 85 | topic(title: "Mac") { 86 | topic(title: "MacBook Pro") 87 | topic(title: "Mac mini") 88 | topic(title: "Mac Pro") 89 | } 90 | } 91 | 92 | topic(title: "Software") { 93 | topic(title: "Xcode") 94 | topic(title: "Siri") 95 | } 96 | } 97 | } 98 | 99 | try wb.save(to: filePath) 100 | ``` 101 | 102 | 103 | 104 | **Read the [Documents](doc/main.md) for all details.** 105 | 106 | 107 | 108 | ### Installation 109 | 110 | - Carthage 111 | 112 | ``` 113 | github "xmindltd/xmind-sdk-swift" 114 | ``` 115 | 116 | - Swift Package Manager 117 | 118 | ``` 119 | .package(url: "https://github.com/xmindltd/xmind-sdk-swift.git", .upToNextMinor(from: "1.1.0")) 120 | ``` 121 | 122 | 123 | 124 | ## License 125 | 126 | This SDK is released under the MIT license. See LICENSE for details. 127 | -------------------------------------------------------------------------------- /Sources/Builder/Builders.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Builders.swift 3 | // XMindSDK 4 | // 5 | // Created by h on 2020/4/4. 6 | // 7 | // Copyright © 2020 XMind. 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | import Foundation 28 | 29 | /// Create a new topic with the title. 30 | public func topic(title: String) -> Elements { 31 | return Elements(Topic(title: title)) 32 | } 33 | 34 | /// Create a new topic with the title and the childen. 35 | public func topic(title: String, @ElementsBuilder childen: () -> Elements) -> Elements { 36 | let topic = Topic(title: title) 37 | childen().forEach { topic.addSubTopic($0) } 38 | return Elements(topic) 39 | } 40 | 41 | /// Create a new sheet by a root topic. 42 | public func sheet(title: String, rootTopic: () -> Elements) -> Elements { 43 | guard let first = rootTopic().first else { return Elements() } 44 | return Elements(Sheet(title: title, rootTopic: first)) 45 | } 46 | 47 | /// Create a new Workbook object by sheets. 48 | public func workbook(@ElementsBuilder sheets: () -> Elements) throws -> Workbook { 49 | let workbook = try Workbook.new() 50 | sheets().forEach { workbook.add(sheet: $0) } 51 | return workbook 52 | } 53 | 54 | /// Create a new Workbook object by topics. 55 | /// This function will make sheets for each root topics. 56 | public func workbook(@ElementsBuilder childen: () -> Elements) throws -> Workbook { 57 | try workbook { 58 | Elements(childen().map { Elements(Sheet(title: "Sheet", rootTopic: $0)) }) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Sources/Builder/ElementsBuilder.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ElementsBuilder.swift 3 | // XMindSDK 4 | // 5 | // Created by h on 2020/4/4. 6 | // 7 | // Copyright © 2020 XMind. 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | import Foundation 28 | 29 | public struct Elements: Sequence { 30 | 31 | public func makeIterator() -> IndexingIterator<[Element]> { 32 | return elements.makeIterator() 33 | } 34 | 35 | private var elements: [Element] 36 | 37 | internal var first: Element? { 38 | elements.first 39 | } 40 | 41 | internal init(_ elements: [Elements]) { 42 | self.elements = elements.flatMap { $0.elements } 43 | } 44 | 45 | internal init(_ element: Element) { 46 | elements = [element] 47 | } 48 | 49 | internal init() { 50 | elements = [] 51 | } 52 | 53 | } 54 | 55 | @_functionBuilder 56 | public struct ElementsBuilder { 57 | 58 | public static func buildBlock() -> Elements { 59 | return Elements() 60 | } 61 | 62 | public static func buildBlock(_ elements: Elements) -> Elements { 63 | return elements 64 | } 65 | 66 | public static func buildBlock(_ elements: Elements...) -> Elements { 67 | return Elements(elements) 68 | } 69 | 70 | public static func buildIf(_ elements: Elements?) -> Elements { 71 | if let elements = elements { 72 | return buildBlock(elements) 73 | } else { 74 | return buildBlock() 75 | } 76 | } 77 | 78 | public static func buildEither(first: Elements) -> Elements { 79 | return first 80 | } 81 | 82 | public static func buildEither(second: Elements) -> Elements { 83 | return second 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Sources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | $(MARKETING_VERSION) 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | 22 | 23 | -------------------------------------------------------------------------------- /Sources/Internal/Constants.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Constants.swift 3 | // XMindSDK 4 | // 5 | // Created by h on 2019/12/6. 6 | // 7 | // Copyright © 2019 XMind. 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | import Foundation 28 | 29 | struct Constants { 30 | static let manifestPath = "manifest.json" 31 | static let metadataPath = "metadata.json" 32 | static let sheetsPath = "content.json" 33 | } 34 | -------------------------------------------------------------------------------- /Sources/Internal/Crypto.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Crypto.swift 3 | // XMindSDK 4 | // 5 | // Created by h on 2019/12/5. 6 | // 7 | // Copyright © 2019 XMind. 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | import Foundation 28 | import CryptoSwift 29 | 30 | class Crypto { 31 | 32 | static let algorithmName = "AES/CBC/PKCS5Padding" 33 | static let keyDerivationName = "PBKDF2WithHmacSHA512" 34 | 35 | private let password: String 36 | 37 | init(password: String) { 38 | self.password = password 39 | } 40 | 41 | func decrypt(data: Data, encryptionData: EncryptionData) throws -> Data { 42 | 43 | guard let salt = Data(base64Encoded: encryptionData.salt) else { throw Error.encryptionDataDamaged } 44 | guard let iv = Data(base64Encoded: encryptionData.iv) else { throw Error.encryptionDataDamaged } 45 | 46 | let PBKDF2 = try PKCS5.PBKDF2(password: password.bytes, 47 | salt: salt.bytes, 48 | iterations: encryptionData.iterationCount, 49 | keyLength: encryptionData.size / 8, 50 | variant: .sha512) 51 | let key = try PBKDF2.calculate() 52 | 53 | 54 | let aes = try AES(key: key, blockMode: CBC(iv: iv.bytes), padding: .pkcs5) 55 | return Data(try aes.decrypt(data.bytes)) 56 | } 57 | 58 | func encrypt(data: Data) throws -> (data: Data, encryptionData: EncryptionData) { 59 | let salt = generateSaltData() 60 | let iv = generateIVData() 61 | 62 | let encryptionData = EncryptionData(iterationCount: 1024, 63 | size: 128, 64 | algorithmName: Crypto.algorithmName, 65 | keyDerivationName: Crypto.keyDerivationName, 66 | salt: salt.base64EncodedString(), 67 | iv: iv.base64EncodedString()) 68 | 69 | let PBKDF2 = try PKCS5.PBKDF2(password: password.bytes, 70 | salt: salt.bytes, 71 | iterations: encryptionData.iterationCount, 72 | keyLength: encryptionData.size / 8, 73 | variant: .sha512) 74 | 75 | let key = try PBKDF2.calculate() 76 | 77 | let aes = try AES(key: key, blockMode: CBC(iv: iv.bytes), padding: .pkcs5) 78 | 79 | let encryptedData = Data(try aes.encrypt(data.bytes)) 80 | 81 | return (data: encryptedData, encryptionData: encryptionData) 82 | } 83 | 84 | private func generateIVData() -> Data { 85 | randomData(size: 16) 86 | } 87 | 88 | private func generateSaltData() -> Data { 89 | randomData(size: 8) 90 | } 91 | 92 | private func randomData(size: Int) -> Data { 93 | var data = Data(capacity: size) 94 | for _ in 0.. EncryptionData? { 59 | return fileEntries[fileEntry]?.encryptionData 60 | } 61 | 62 | static func makeDefault() -> Manifest { 63 | var manifest = Manifest() 64 | manifest.insert(fileEntry: Constants.sheetsPath) 65 | manifest.insert(fileEntry: Constants.metadataPath) 66 | return manifest 67 | } 68 | } 69 | 70 | extension Manifest { 71 | struct Description: Codable { 72 | public let encryptionData: EncryptionData? 73 | 74 | enum CodingKeys: String, CodingKey { 75 | case encryptionData = "encryption-data" 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Sources/Internal/Metadata.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Metadata.swift 3 | // XMindSDK 4 | // 5 | // Created by h on 2019/11/13. 6 | // 7 | // Copyright © 2019 XMind. 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | import Foundation 28 | 29 | struct Metadata: Codable { 30 | 31 | /// The creator contains the creator's name and the version of the creator. 32 | struct Creator: Codable { 33 | let name: String 34 | let version: String 35 | } 36 | 37 | var activeSheetId: String 38 | 39 | let creator: Creator 40 | 41 | static func makeDefault(activeSheetId: String) -> Metadata { 42 | return Metadata(activeSheetId: activeSheetId, creator: Creator(name: "XMindSDK", version: "1.0")) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Sources/Internal/TemporaryStorge.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TemporaryStorge.swift 3 | // XMindSDK 4 | // 5 | // Created by h on 2019/12/5. 6 | // 7 | // Copyright © 2019 XMind. 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | import Foundation 28 | 29 | class TemporaryStorge { 30 | 31 | private let fileManager = FileManager() 32 | let temporaryPath: String 33 | 34 | init(temporaryPath: String) { 35 | self.temporaryPath = temporaryPath 36 | } 37 | 38 | private func makeAbsolutelyPath(path: String) -> String { 39 | return (temporaryPath as NSString).appendingPathComponent(path) 40 | } 41 | 42 | func read(path: String) throws -> Data { 43 | if let data = fileManager.contents(atPath: makeAbsolutelyPath(path: path)) { 44 | return data 45 | } 46 | throw Error.fileNotFound 47 | } 48 | 49 | func write(path: String, data: Data) throws { 50 | fileManager.createFile(atPath: makeAbsolutelyPath(path: path), contents: data, attributes: nil) 51 | } 52 | 53 | func clear() { 54 | do { 55 | try fileManager.removeItem(atPath: temporaryPath) 56 | } catch { 57 | print("XMindSDK: Fail to clean the temporary file. The temporary directory is \"\(temporaryPath)\".") 58 | } 59 | } 60 | 61 | static func makeTemporaryDirectory() -> String { 62 | return (NSTemporaryDirectory() as NSString).appendingPathComponent(UUID().uuidString) 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Sources/XMind/Error.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Error.swift 3 | // XMindSDK 4 | // 5 | // Created by CY H on 2019/11/4. 6 | // 7 | // Copyright © 2019 XMind. 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | import Foundation 28 | 29 | public enum Error: Swift.Error { 30 | case fileNotFound 31 | case fileIsEncrypted 32 | case encryptionDataDamaged 33 | } 34 | -------------------------------------------------------------------------------- /Sources/XMind/Marker.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Marker.swift 3 | // XMindSDK 4 | // 5 | // Created by h on 2019/11/13. 6 | // 7 | // Copyright © 2019 XMind. 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | import Foundation 28 | 29 | public struct Marker: Codable { 30 | let markerId: String 31 | } 32 | 33 | extension Marker { 34 | public struct Priority { 35 | public static let p1 = Marker(markerId: "priority-1") 36 | public static let p2 = Marker(markerId: "priority-2") 37 | public static let p3 = Marker(markerId: "priority-3") 38 | public static let p4 = Marker(markerId: "priority-4") 39 | public static let p5 = Marker(markerId: "priority-5") 40 | public static let p6 = Marker(markerId: "priority-6") 41 | public static let p7 = Marker(markerId: "priority-7") 42 | } 43 | 44 | public struct Smiley { 45 | public static let laugh = Marker(markerId: "smiley-laugh") 46 | public static let smile = Marker(markerId: "smiley-smile") 47 | public static let cry = Marker(markerId: "smiley-cry") 48 | public static let surprise = Marker(markerId: "smiley-surprise") 49 | public static let boring = Marker(markerId: "smiley-boring") 50 | public static let angry = Marker(markerId: "smiley-angry") 51 | public static let embarrass = Marker(markerId: "smiley-embarrass") 52 | } 53 | 54 | public struct Task { 55 | public static let start = Marker(markerId: "task-start") 56 | public static let oct = Marker(markerId: "task-oct") 57 | public static let quarter = Marker(markerId: "task-quarter") 58 | public static let half = Marker(markerId: "task-half") 59 | public static let done = Marker(markerId: "task-done") 60 | public static let pause = Marker(markerId: "task-pause") 61 | } 62 | 63 | public struct Flag { 64 | public static let red = Marker(markerId: "flag-red") 65 | public static let orange = Marker(markerId: "flag-orange") 66 | public static let darkBlue = Marker(markerId: "flag-dark-blue") 67 | public static let purple = Marker(markerId: "flag-purple") 68 | public static let green = Marker(markerId: "flag-green") 69 | public static let blue = Marker(markerId: "flag-blue") 70 | public static let gray = Marker(markerId: "flag-gray") 71 | } 72 | 73 | public struct Star { 74 | public static let red = Marker(markerId: "star-red") 75 | public static let orange = Marker(markerId: "star-orange") 76 | public static let darkBlue = Marker(markerId: "star-dark-blue") 77 | public static let purple = Marker(markerId: "star-purple") 78 | public static let green = Marker(markerId: "star-green") 79 | public static let blue = Marker(markerId: "star-blue") 80 | public static let gray = Marker(markerId: "star-gray") 81 | } 82 | 83 | public struct People { 84 | public static let red = Marker(markerId: "people-red") 85 | public static let orange = Marker(markerId: "people-orange") 86 | public static let darkBlue = Marker(markerId: "people-dark-blue") 87 | public static let purple = Marker(markerId: "people-purple") 88 | public static let green = Marker(markerId: "people-green") 89 | public static let blue = Marker(markerId: "people-blue") 90 | public static let gray = Marker(markerId: "people-gray") 91 | } 92 | 93 | public struct Arrow { 94 | public static let left = Marker(markerId: "arrow-left") 95 | public static let right = Marker(markerId: "arrow-right") 96 | public static let up = Marker(markerId: "arrow-up") 97 | public static let down = Marker(markerId: "arrow-down") 98 | public static let leftRight = Marker(markerId: "arrow-left-right") 99 | public static let upDown = Marker(markerId: "arrow-up-down") 100 | public static let refresh = Marker(markerId: "arrow-refresh") 101 | } 102 | 103 | public struct Month { 104 | public static let jan = Marker(markerId: "month-jan") 105 | public static let feb = Marker(markerId: "month-feb") 106 | public static let mar = Marker(markerId: "month-mar") 107 | public static let apr = Marker(markerId: "month-apr") 108 | public static let may = Marker(markerId: "month-may") 109 | public static let jun = Marker(markerId: "month-jun") 110 | public static let jul = Marker(markerId: "month-jul") 111 | public static let aug = Marker(markerId: "month-aug") 112 | public static let sep = Marker(markerId: "month-sep") 113 | public static let oct = Marker(markerId: "month-oct") 114 | public static let nov = Marker(markerId: "month-nov") 115 | public static let dec = Marker(markerId: "month-dec") 116 | } 117 | 118 | public struct Week { 119 | public static let sun = Marker(markerId: "week-sun") 120 | public static let mon = Marker(markerId: "week-mon") 121 | public static let tue = Marker(markerId: "week-tue") 122 | public static let wed = Marker(markerId: "week-wed") 123 | public static let thu = Marker(markerId: "week-thu") 124 | public static let fri = Marker(markerId: "week-fri") 125 | public static let sat = Marker(markerId: "week-sat") 126 | } 127 | } 128 | 129 | extension Marker: Equatable { 130 | public static func == (lhs: Marker, rhs: Marker) -> Bool { 131 | return lhs.markerId == rhs.markerId 132 | } 133 | } 134 | 135 | extension Marker { 136 | func isSameGroup(with marker: Marker) -> Bool { 137 | return marker.markerId.split(separator: "-").first == self.markerId.split(separator: "-").first 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /Sources/XMind/Point.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Point.swift 3 | // XMindSDK 4 | // 5 | // Created by h on 2019/11/13. 6 | // 7 | // Copyright © 2019 XMind. 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | import Foundation 28 | 29 | public struct Point: Codable { 30 | public var x: Double 31 | public var y: Double 32 | } 33 | -------------------------------------------------------------------------------- /Sources/XMind/Relationship.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Relationship.swift 3 | // XMindSDK 4 | // 5 | // Created by h on 2019/11/13. 6 | // 7 | // Copyright © 2019 XMind. 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | import Foundation 28 | 29 | public struct Relationship: Codable { 30 | 31 | public let id: String 32 | 33 | public let end1Id: String 34 | public let end2Id: String 35 | 36 | public let titleUnedited: Bool 37 | 38 | public let controlPoints: [String: Point] 39 | } 40 | -------------------------------------------------------------------------------- /Sources/XMind/Sheet.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Sheet.swift 3 | // XMindSDK 4 | // 5 | // Created by h on 2019/11/8. 6 | // 7 | // Copyright © 2019 XMind. 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | import Foundation 28 | 29 | /// Sheet represents a mind map panel 30 | /// which contains a root topic. 31 | public class Sheet: Codable { 32 | 33 | 34 | /// The unique ID of this sheet. 35 | public let id: String 36 | 37 | /// The class of this sheet. 38 | public let `class`: String 39 | 40 | /// Title of this sheet which represents the name of this panel. 41 | public var title: String 42 | 43 | /// The root topic of this panel. 44 | /// A sheet only can contains a root topic, 45 | public let rootTopic: Topic 46 | 47 | /// The topic positioning function. 48 | public let topicPositioning: String 49 | 50 | /// The relationships of this panel. 51 | public let relationships: [Relationship]? 52 | 53 | /// Theme of this panel. 54 | public let theme: Theme 55 | 56 | public init(title: String, rootTopic: Topic) { 57 | self.id = UUID().uuidString 58 | self.class = "sheet" 59 | self.title = title 60 | self.rootTopic = rootTopic 61 | self.topicPositioning = "fixed" 62 | self.relationships = nil 63 | self.theme = Theme.snowbrush 64 | } 65 | 66 | } 67 | 68 | extension Sheet: Equatable { 69 | public static func == (lhs: Sheet, rhs: Sheet) -> Bool { 70 | return lhs === rhs 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Sources/XMind/Theme.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Theme.swift 3 | // XMindSDK 4 | // 5 | // Created by h on 2019/11/13. 6 | // 7 | // Copyright © 2019 XMind. 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | import Foundation 28 | 29 | public struct Theme: Codable { 30 | 31 | public struct Item: Codable { 32 | public let styleId: String? 33 | public let type: String? 34 | public let properties: [String: String]? 35 | } 36 | 37 | public let id: String? 38 | 39 | public let importantTopic: Item? 40 | public let minorTopic: Item? 41 | public let expiredTopic: Item? 42 | public let centralTopic: Item? 43 | public let boundary: Item? 44 | public let floatingTopic: Item? 45 | public let subTopic: Item? 46 | public let mainTopic: Item? 47 | public let calloutTopic: Item? 48 | public let summary: Item? 49 | public let summaryTopic: Item? 50 | public let relationship: Item? 51 | public let map: Item? 52 | public let level3: Item? 53 | 54 | } 55 | 56 | extension Theme { 57 | 58 | static let snowbrush: Theme = { 59 | return try! JSONDecoder().decode(Theme.self, from: Theme.theme_snowbrush.data(using: .utf8)!) 60 | }() 61 | 62 | private static let theme_snowbrush = """ 63 | { 64 | "id":"f7f73af7-90f2-4afe-854b-d4a569205111", 65 | "importantTopic": { 66 | "type": "topic", 67 | "properties": { 68 | "fo:font-weight": "bold", 69 | "fo:color": "#F04137", 70 | "svg:fill": "none" 71 | } 72 | }, 73 | "minorTopic": { 74 | "type": "topic", 75 | "properties": { 76 | "svg:fill": "none", 77 | "fo:font-weight": "bold", 78 | "fo:color": "#06ABD0" 79 | } 80 | }, 81 | "expiredTopic": { 82 | "type": "topic", 83 | "properties": { 84 | "fo:font-style": "italic", 85 | "fo:text-decoration": " line-through" 86 | } 87 | }, 88 | "centralTopic": { 89 | "properties": { 90 | "fo:color": "#000000", 91 | "fo:font-family": "Avenir Next", 92 | "fo:font-weight": "600", 93 | "fo:font-size": "24pt", 94 | "fo:font-style": "normal", 95 | "border-line-width": "0", 96 | "border-line-color": "#374C75", 97 | "line-color": "#374C75", 98 | "line-width": "3pt", 99 | "svg:fill": "#FFFFFF" 100 | }, 101 | "styleId": "39687c955b998eedc81008bf3f", 102 | "type": "topic" 103 | }, 104 | "boundary": { 105 | "properties": { 106 | "fo:font-style": "normal", 107 | "fo:color": "#FFFFFF", 108 | "fo:font-family": "Avenir Next", 109 | "fo:font-weight": "600", 110 | "fo:font-size": "14pt", 111 | "svg:fill": "#E9E9E8", 112 | "line-color": "#5E5E5E", 113 | "line-pattern": "dot" 114 | }, 115 | "styleId": "29f9b72a43c95e2d17c1ebd6c8", 116 | "type": "boundary" 117 | }, 118 | "floatingTopic": { 119 | "properties": { 120 | "svg:fill": "#EBEBEB", 121 | "shape-class": "org.xmind.topicShape.roundedRect", 122 | "border-line-width": "0pt", 123 | "border-line-color": "#374C75", 124 | "fo:color": "#332F2E", 125 | "fo:font-family": "Avenir Next", 126 | "fo:font-size": "14pt", 127 | "fo:font-weight": "600", 128 | "fo:font-style": "normal", 129 | "line-class": "org.xmind.branchConnection.bight", 130 | "line-color": "#5E5E5E", 131 | "line-width": "2pt" 132 | }, 133 | "styleId": "8edb0655eed84223023988f896", 134 | "type": "topic" 135 | }, 136 | "subTopic": { 137 | "type": "topic", 138 | "properties": { 139 | "line-class": "org.xmind.branchConnection.bight", 140 | "line-width": "1pt", 141 | "fo:font-family": "Avenir Next", 142 | "fo:font-size": "14pt", 143 | "fo:color": "#091C34", 144 | "fo:text-align": "left" 145 | } 146 | }, 147 | "mainTopic": { 148 | "type": "topic", 149 | "properties": { 150 | "border-line-width": "2pt", 151 | "line-class": "org.xmind.branchConnection.bight", 152 | "line-width": "2pt", 153 | "svg:fill": "none", 154 | "shape-class": "org.xmind.topicShape.underline", 155 | "fo:color": "#091C34", 156 | "fo:font-size": "16pt", 157 | "fo:font-family": "Avenir Next", 158 | "fo:font-weight": "500" 159 | } 160 | }, 161 | "calloutTopic": { 162 | "properties": { 163 | "fo:font-weight": "600", 164 | "fo:font-style": "normal", 165 | "fo:font-size": "14pt", 166 | "fo:font-family": "Avenir Next", 167 | "border-line-width": "0", 168 | "svg:fill": "#5E5E5E", 169 | "fo:color": "#FFFFFF" 170 | }, 171 | "styleId": "4379160bdc98a456dd60a8721d", 172 | "type": "topic" 173 | }, 174 | "summary": { 175 | "properties": { 176 | "shape-class": "org.xmind.summaryShape.square", 177 | "line-width": "2pt", 178 | "line-color": "#5E5E5E" 179 | }, 180 | "styleId": "14394c4b1a5b6b534182699edf", 181 | "type": "summary" 182 | }, 183 | "summaryTopic": { 184 | "properties": { 185 | "line-class": "org.xmind.branchConnection.bight", 186 | "line-width": "1pt", 187 | "line-color": "#5E5E5E", 188 | "shape-class": "org.xmind.topicShape.roundedRect", 189 | "svg:fill": "#EBEBEB", 190 | "fo:color": "#091C34", 191 | "fo:font-weight": "600", 192 | "fo:font-style": "normal", 193 | "fo:font-family": "Avenir Next", 194 | "fo:font-size": "14pt", 195 | "border-line-width": "0pt", 196 | "border-line-color": "#5E5E5E" 197 | }, 198 | "styleId": "963bfcbd450931f641aef94ec5", 199 | "type": "topic" 200 | }, 201 | "relationship": { 202 | "properties": { 203 | "line-width": "2pt", 204 | "line-pattern": "dot", 205 | "line-color": "#5E5E5E", 206 | "fo:font-weight": "600", 207 | "fo:font-style": "normal", 208 | "fo:color": "#5E5E5E", 209 | "fo:font-family": "Avenir Next", 210 | "fo:font-size": "14pt", 211 | "arrow-begin-class": "org.xmind.arrowShape.attached" 212 | }, 213 | "styleId": "67596f401d995d448791686b97", 214 | "type": "relationship" 215 | }, 216 | "map": { 217 | "properties": { 218 | "multi-line-colors": "#F04137 #F8932E #FEC938 #A0C347 #06ABD0 #832A96", 219 | "line-tapered": "tapered", 220 | "svg:fill": "#F5F5FA" 221 | }, 222 | "styleId": "c9c904312f6968e676f4fafd22", 223 | "type": "map" 224 | }, 225 | "level3": { 226 | "type": "topic", 227 | "properties": { 228 | "line-class": "org.xmind.branchConnection.bight", 229 | "line-width": "1pt", 230 | "border-line-width": "2pt", 231 | "fo:font-family": "Avenir Next", 232 | "fo:font-size": "14pt", 233 | "fo:color": "#091C34", 234 | "fo:text-align": "left" 235 | } 236 | } 237 | } 238 | """ 239 | 240 | 241 | } 242 | -------------------------------------------------------------------------------- /Sources/XMind/Topic.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Topic.swift 3 | // XMindSDK 4 | // 5 | // Created by CY H on 2019/11/4. 6 | // 7 | // Copyright © 2019 XMind. 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | 28 | import Foundation 29 | 30 | public class Topic: Codable { 31 | 32 | /// The unique ID of this topic. 33 | public let id: String 34 | 35 | public let `class`: String? 36 | 37 | /// The title of this topic. 38 | public var title: String? 39 | 40 | public let structureClass: String? 41 | 42 | public let titleUnedited: Bool? 43 | 44 | public private(set) var markers: [Marker]? 45 | 46 | public private(set) var children: Children? 47 | 48 | private var image: Image? 49 | 50 | internal private(set) weak var superTopic: Topic? = nil 51 | 52 | 53 | public init(title: String? = nil) { 54 | self.id = UUID().uuidString 55 | self.class = "topic" 56 | self.title = title 57 | self.structureClass = "org.xmind.ui.map.unbalanced" 58 | self.titleUnedited = true 59 | self.markers = nil 60 | self.children = nil 61 | } 62 | 63 | } 64 | 65 | extension Topic { 66 | public struct Children: Codable { 67 | public var attached: [Topic]? 68 | public var detached: [Topic]? 69 | 70 | init() { 71 | attached = [] 72 | detached = [] 73 | } 74 | } 75 | } 76 | 77 | extension Topic { 78 | 79 | struct Image: Codable { 80 | let src: String 81 | } 82 | 83 | enum CodingKeys: String, CodingKey { 84 | case id 85 | case `class` 86 | case title 87 | case structureClass 88 | case titleUnedited 89 | case markers 90 | case children 91 | case image 92 | } 93 | } 94 | 95 | extension Topic { 96 | /// Add a topic to self. 97 | /// You cant add an ancestor topic, It do nothing. 98 | /// If the topic that to be added was alredy contained by self. it will not add twice. 99 | /// If the topic had a super topic, it will remove from origin super topic,then add to self. 100 | /// - Parameter topic: The topic to be added. 101 | public func addSubTopic(_ topic: Topic) { 102 | 103 | var _topic: Topic? = self 104 | 105 | while let t = _topic { 106 | if t == topic { 107 | print("XMindSDK: Can't add an ancestor as a sub topic.") 108 | return 109 | } 110 | _topic = t.superTopic 111 | } 112 | 113 | 114 | if children == nil { 115 | children = Children() 116 | } 117 | 118 | if children?.attached == nil { 119 | children?.attached = [] 120 | } 121 | 122 | if children!.attached!.contains(where: { $0 === topic }) { 123 | return 124 | } 125 | 126 | topic.removeFromSuperTopic() 127 | children!.attached!.append(topic) 128 | topic.superTopic = self 129 | } 130 | 131 | /// A convenience function for add a topic. 132 | /// The behave is same as "addSubTopic(_ topic: Topic)". 133 | /// The returned topic is the new created topic. 134 | /// - Parameter title: Title of the new topic. 135 | public func addSubTopic(_ title: String) -> Topic { 136 | let topic = Topic(title: title) 137 | addSubTopic(topic) 138 | return topic 139 | } 140 | 141 | /// Remove a sub topic. 142 | /// - Parameter topic: The sub topic. 143 | public func removeSubTopic(_ topic: Topic) { 144 | 145 | guard let droped = children?.attached?.drop(while: { $0 === topic }) else { return } 146 | 147 | for topic in droped { 148 | topic.superTopic = nil 149 | } 150 | } 151 | 152 | /// If the topic has a super topic, it will remove from the super topic. 153 | public func removeFromSuperTopic() { 154 | superTopic?.removeSubTopic(self) 155 | } 156 | 157 | /// Add a marker to the topic, The same class marker can only add once. 158 | /// - Parameter marker: Marker to be added. 159 | public func addMarker(_ marker: Marker) { 160 | if markers == nil { 161 | markers = [marker] 162 | } else { 163 | markers!.removeAll { $0.isSameGroup(with: marker) } 164 | markers!.append(marker) 165 | } 166 | } 167 | 168 | /// Remove a marker. 169 | /// - Parameter marker: Marker to be removed. 170 | public func removeMarker(_ marker: Marker) { 171 | markers?.removeAll { $0 == marker } 172 | } 173 | } 174 | 175 | 176 | extension Topic: Equatable { 177 | public static func == (lhs: Topic, rhs: Topic) -> Bool { 178 | return lhs === rhs 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /Sources/XMind/Workbook.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Workbook.swift 3 | // XMindSDK 4 | // 5 | // Created by CY H on 2019/11/4. 6 | // 7 | // Copyright © 2019 XMind. 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | 28 | import Foundation 29 | import ZIPFoundation 30 | 31 | /// A workbook is as a xmind file. 32 | /// You can open or new a workbook(xmind file). 33 | /// To opera a xmind file, workbook use a temporary storge at temporary path on the disk. 34 | /// The temporary content will be deleted while the workbook object deinited. 35 | /// If open an existing file, first you need call 'loadManifest()' , second call 'loadContent(password: String?)'. 36 | /// 37 | public final class Workbook { 38 | 39 | private let jsonDecoder = JSONDecoder() 40 | private let jsonEncoder = JSONEncoder() 41 | 42 | private let temporaryStorge: TemporaryStorge 43 | 44 | private lazy var manifest: Manifest = Manifest.makeDefault() 45 | 46 | private lazy var sheets: [Sheet] = [] 47 | 48 | private lazy var metadata: Metadata = Metadata.makeDefault(activeSheetId: sheets.last?.id ?? "") 49 | 50 | private init(temporaryStorge: TemporaryStorge) { 51 | self.temporaryStorge = temporaryStorge 52 | } 53 | 54 | deinit { 55 | temporaryStorge.clear() 56 | } 57 | } 58 | 59 | 60 | 61 | extension Workbook { 62 | 63 | public var passwordHint: String? { 64 | get { 65 | return manifest.passwordHint 66 | } 67 | set { 68 | manifest.passwordHint = newValue 69 | } 70 | } 71 | 72 | /// Load the existing manifest. 73 | /// Just only can read passwordHint after called "loadManifest" 74 | public func loadManifest() throws { 75 | manifest = try readManifest() 76 | } 77 | 78 | /// Load the existing content. 79 | /// - Parameter password: Password of the file. 80 | public func loadContent(password: String? = nil) throws { 81 | let crypto = makeCrypto(password: password) 82 | metadata = try readModel(path: Constants.metadataPath, crypto: crypto) 83 | sheets = try readModel(path: Constants.sheetsPath, crypto: crypto) 84 | } 85 | 86 | public var allSheets: [Sheet] { 87 | return sheets 88 | } 89 | 90 | public func add(sheet: Sheet) { 91 | sheets.removeAll { $0 == sheet } 92 | sheets.append(sheet) 93 | } 94 | 95 | public func remove(sheet: Sheet) { 96 | sheets.removeAll { $0 == sheet } 97 | } 98 | 99 | /// Save as a xmind file at the given path. 100 | /// If a file already exists with this path, This method will throw an error that indicates this csae. 101 | /// - Parameter path: Path will save to. 102 | public func save(to path: String, password: String? = nil) throws { 103 | let crypto = makeCrypto(password: password) 104 | try writeWorkbook(crypto: crypto) 105 | try FileManager.default.zipItem(at: URL(fileURLWithPath: temporaryStorge.temporaryPath), to: URL(fileURLWithPath: path), shouldKeepParent: false) 106 | } 107 | } 108 | 109 | 110 | extension Workbook { 111 | 112 | /// Open a xmind file at the given file path. 113 | /// It will make a random temporary path by default. 114 | /// - Parameter filePath: The location of a xmind file which will be opened. 115 | public static func open(filePath: String) throws -> Workbook { 116 | return try open(filePath: filePath, temporaryPath: TemporaryStorge.makeTemporaryDirectory()) 117 | } 118 | 119 | /// Open a xmind file at the given file path. 120 | /// - Parameters: 121 | /// - filePath: The location of a xmind file which will be opened. 122 | /// - temporaryPath: The temporary space that use to cache and opera temporary files. 123 | public static func open(filePath: String, temporaryPath: String) throws -> Workbook { 124 | guard FileManager.default.fileExists(atPath: filePath) else { 125 | throw Error.fileNotFound 126 | } 127 | 128 | try FileManager.default.createDirectory(atPath: temporaryPath, withIntermediateDirectories: true, attributes: nil) 129 | 130 | try FileManager.default.unzipItem(at: URL(fileURLWithPath: filePath), to: URL(fileURLWithPath: temporaryPath)) 131 | 132 | let temporaryStorge = TemporaryStorge(temporaryPath: temporaryPath) 133 | 134 | return Workbook(temporaryStorge: temporaryStorge) 135 | } 136 | 137 | /// Create a new xmind file that is empty. 138 | /// - Parameter temporaryPath: The temporary space that use to cache and opera temporary files. 139 | public static func new(temporaryPath: String) throws -> Workbook { 140 | 141 | try FileManager.default.createDirectory(atPath: temporaryPath, withIntermediateDirectories: true, attributes: nil) 142 | 143 | let temporaryStorge = TemporaryStorge(temporaryPath: temporaryPath) 144 | 145 | return Workbook(temporaryStorge: temporaryStorge) 146 | } 147 | 148 | /// Create a new xmind file that is empty. 149 | /// It will make a random temporary path by default. 150 | public static func new() throws -> Workbook { 151 | return try new(temporaryPath: TemporaryStorge.makeTemporaryDirectory()) 152 | } 153 | } 154 | 155 | private extension Workbook { 156 | 157 | func makeCrypto(password: String?) -> Crypto? { 158 | if let password = password { 159 | return Crypto(password: password) 160 | } else { 161 | return nil 162 | } 163 | } 164 | 165 | func readManifest() throws -> Manifest { 166 | let data = try temporaryStorge.read(path: Constants.manifestPath) 167 | return try jsonDecoder.decode(Manifest.self, from: data) 168 | } 169 | 170 | func writeManifest(manifest: Manifest) throws { 171 | let data = try jsonEncoder.encode(manifest) 172 | try temporaryStorge.write(path: Constants.manifestPath, data: data) 173 | } 174 | 175 | func readFile(path: String, crypto: Crypto?) throws -> Data { 176 | let data = try temporaryStorge.read(path: path) 177 | if let encryptionData = manifest.encryptionData(fileEntry: path) { 178 | if let crypto = crypto { 179 | return try crypto.decrypt(data: data, encryptionData: encryptionData) 180 | } else { 181 | throw Error.fileIsEncrypted 182 | } 183 | } else { 184 | return data 185 | } 186 | 187 | } 188 | 189 | func readModel(path: String, crypto: Crypto?) throws -> T { 190 | let data = try readFile(path: path, crypto: crypto) 191 | return try jsonDecoder.decode(T.self, from: data) 192 | } 193 | 194 | func writeFile(path: String, data: Data, crypto: Crypto?) throws { 195 | if let crypto = crypto { 196 | let (encryptedData, encryptionData) = try crypto.encrypt(data: data) 197 | try temporaryStorge.write(path: path, data: encryptedData) 198 | manifest.insert(fileEntry: path, description: Manifest.Description(encryptionData: encryptionData)) 199 | } else { 200 | try temporaryStorge.write(path: path, data: data) 201 | manifest.insert(fileEntry: path) 202 | } 203 | } 204 | 205 | func writeModel(path: String, model: T, crypto: Crypto?) throws { 206 | let data = try jsonEncoder.encode(model) 207 | try writeFile(path: path, data: data, crypto: crypto) 208 | } 209 | 210 | func writeWorkbook(crypto: Crypto?) throws { 211 | try writeModel(path: Constants.sheetsPath, model: sheets, crypto: crypto) 212 | try writeModel(path: Constants.metadataPath, model: metadata, crypto: crypto) 213 | try writeManifest(manifest: manifest) 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /Sources/XMindSDK.h: -------------------------------------------------------------------------------- 1 | // 2 | // XMindSDK.h 3 | // XMindSDK 4 | // 5 | // Created by CY H on 2019/11/4. 6 | // 7 | // Copyright © 2019 XMind. 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | #import 28 | 29 | //! Project version number for XMindSDK. 30 | FOUNDATION_EXPORT double XMindSDKVersionNumber; 31 | 32 | //! Project version string for XMindSDK. 33 | FOUNDATION_EXPORT const unsigned char XMindSDKVersionString[]; 34 | 35 | // In this header, you should import all the public headers of your framework using statements like #import 36 | 37 | 38 | -------------------------------------------------------------------------------- /XMindSDK.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 07637C9D237BAA4400E05FE9 /* Manifest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07637C9C237BAA4400E05FE9 /* Manifest.swift */; }; 11 | 07637C9F237BB1AB00E05FE9 /* Metadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07637C9E237BB1AB00E05FE9 /* Metadata.swift */; }; 12 | 07637CA1237BCD3300E05FE9 /* Relationship.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07637CA0237BCD3300E05FE9 /* Relationship.swift */; }; 13 | 07637CA3237BCE4200E05FE9 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07637CA2237BCE4200E05FE9 /* Theme.swift */; }; 14 | 07637CA5237BD16600E05FE9 /* Point.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07637CA4237BD16600E05FE9 /* Point.swift */; }; 15 | 07637CA7237BD27E00E05FE9 /* Marker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07637CA6237BD27E00E05FE9 /* Marker.swift */; }; 16 | 0791AF4A2437BD1C00F5ECDC /* Builders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0791AF492437BD1C00F5ECDC /* Builders.swift */; }; 17 | 0791AF522437E38900F5ECDC /* ElementsBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0791AF512437E38900F5ECDC /* ElementsBuilder.swift */; }; 18 | 07B6604023700BE4000FE35A /* Workbook.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B6603F23700BE4000FE35A /* Workbook.swift */; }; 19 | 07B6604223700C9B000FE35A /* Topic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B6604123700C9B000FE35A /* Topic.swift */; }; 20 | 07B6604423701739000FE35A /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B6604323701739000FE35A /* Error.swift */; }; 21 | 07CABF43236FF35C00A50B58 /* XMindSDK.h in Headers */ = {isa = PBXBuildFile; fileRef = 07CABF41236FF35C00A50B58 /* XMindSDK.h */; settings = {ATTRIBUTES = (Public, ); }; }; 22 | 07E117372398A77B0042C083 /* TemporaryStorge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07E117362398A77B0042C083 /* TemporaryStorge.swift */; }; 23 | 07E117392398B0EC0042C083 /* Crypto.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07E117382398B0EC0042C083 /* Crypto.swift */; }; 24 | 07E1173B2398B3E50042C083 /* EncryptionData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07E1173A2398B3E50042C083 /* EncryptionData.swift */; }; 25 | 07E117422399FF800042C083 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07E117412399FF800042C083 /* Constants.swift */; }; 26 | 07FE404B23754B300070DE70 /* Sheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07FE404A23754B300070DE70 /* Sheet.swift */; }; 27 | /* End PBXBuildFile section */ 28 | 29 | /* Begin PBXFileReference section */ 30 | 07637C9C237BAA4400E05FE9 /* Manifest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Manifest.swift; sourceTree = ""; }; 31 | 07637C9E237BB1AB00E05FE9 /* Metadata.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Metadata.swift; sourceTree = ""; }; 32 | 07637CA0237BCD3300E05FE9 /* Relationship.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Relationship.swift; sourceTree = ""; }; 33 | 07637CA2237BCE4200E05FE9 /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = ""; }; 34 | 07637CA4237BD16600E05FE9 /* Point.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Point.swift; sourceTree = ""; }; 35 | 07637CA6237BD27E00E05FE9 /* Marker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Marker.swift; sourceTree = ""; }; 36 | 0791AF492437BD1C00F5ECDC /* Builders.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Builders.swift; sourceTree = ""; }; 37 | 0791AF512437E38900F5ECDC /* ElementsBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementsBuilder.swift; sourceTree = ""; }; 38 | 07B6603F23700BE4000FE35A /* Workbook.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Workbook.swift; sourceTree = ""; }; 39 | 07B6604123700C9B000FE35A /* Topic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Topic.swift; sourceTree = ""; }; 40 | 07B6604323701739000FE35A /* Error.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Error.swift; sourceTree = ""; }; 41 | 07CABF3E236FF35C00A50B58 /* XMindSDK.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = XMindSDK.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 42 | 07CABF41236FF35C00A50B58 /* XMindSDK.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XMindSDK.h; sourceTree = ""; }; 43 | 07CABF42236FF35C00A50B58 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 44 | 07E117362398A77B0042C083 /* TemporaryStorge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemporaryStorge.swift; sourceTree = ""; }; 45 | 07E117382398B0EC0042C083 /* Crypto.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Crypto.swift; sourceTree = ""; }; 46 | 07E1173A2398B3E50042C083 /* EncryptionData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionData.swift; sourceTree = ""; }; 47 | 07E117412399FF800042C083 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; }; 48 | 07FE404A23754B300070DE70 /* Sheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sheet.swift; sourceTree = ""; }; 49 | /* End PBXFileReference section */ 50 | 51 | /* Begin PBXFrameworksBuildPhase section */ 52 | 07CABF3B236FF35C00A50B58 /* Frameworks */ = { 53 | isa = PBXFrameworksBuildPhase; 54 | buildActionMask = 2147483647; 55 | files = ( 56 | ); 57 | runOnlyForDeploymentPostprocessing = 0; 58 | }; 59 | /* End PBXFrameworksBuildPhase section */ 60 | 61 | /* Begin PBXGroup section */ 62 | 075072FB237D2EFD00DC2A3C /* Internal */ = { 63 | isa = PBXGroup; 64 | children = ( 65 | 07637C9E237BB1AB00E05FE9 /* Metadata.swift */, 66 | 07637C9C237BAA4400E05FE9 /* Manifest.swift */, 67 | 07E1173A2398B3E50042C083 /* EncryptionData.swift */, 68 | 07E117362398A77B0042C083 /* TemporaryStorge.swift */, 69 | 07E117382398B0EC0042C083 /* Crypto.swift */, 70 | 07E117412399FF800042C083 /* Constants.swift */, 71 | ); 72 | path = Internal; 73 | sourceTree = ""; 74 | }; 75 | 075072FC237D2F1A00DC2A3C /* XMind */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | 07B6603F23700BE4000FE35A /* Workbook.swift */, 79 | 07B6604123700C9B000FE35A /* Topic.swift */, 80 | 07FE404A23754B300070DE70 /* Sheet.swift */, 81 | 07637CA0237BCD3300E05FE9 /* Relationship.swift */, 82 | 07637CA2237BCE4200E05FE9 /* Theme.swift */, 83 | 07637CA4237BD16600E05FE9 /* Point.swift */, 84 | 07637CA6237BD27E00E05FE9 /* Marker.swift */, 85 | 07B6604323701739000FE35A /* Error.swift */, 86 | ); 87 | path = XMind; 88 | sourceTree = ""; 89 | }; 90 | 0791AF482437BCEF00F5ECDC /* Builder */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | 0791AF492437BD1C00F5ECDC /* Builders.swift */, 94 | 0791AF512437E38900F5ECDC /* ElementsBuilder.swift */, 95 | ); 96 | path = Builder; 97 | sourceTree = ""; 98 | }; 99 | 07CABF32236FF2D900A50B58 = { 100 | isa = PBXGroup; 101 | children = ( 102 | 07CABF40236FF35C00A50B58 /* Sources */, 103 | 07CABF3F236FF35C00A50B58 /* Products */, 104 | 07E19D022372AB9300C9E6E0 /* Frameworks */, 105 | ); 106 | sourceTree = ""; 107 | }; 108 | 07CABF3F236FF35C00A50B58 /* Products */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | 07CABF3E236FF35C00A50B58 /* XMindSDK.framework */, 112 | ); 113 | name = Products; 114 | sourceTree = ""; 115 | }; 116 | 07CABF40236FF35C00A50B58 /* Sources */ = { 117 | isa = PBXGroup; 118 | children = ( 119 | 0791AF482437BCEF00F5ECDC /* Builder */, 120 | 075072FC237D2F1A00DC2A3C /* XMind */, 121 | 075072FB237D2EFD00DC2A3C /* Internal */, 122 | 07CABF41236FF35C00A50B58 /* XMindSDK.h */, 123 | 07CABF42236FF35C00A50B58 /* Info.plist */, 124 | ); 125 | path = Sources; 126 | sourceTree = ""; 127 | }; 128 | 07E19D022372AB9300C9E6E0 /* Frameworks */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | ); 132 | name = Frameworks; 133 | sourceTree = ""; 134 | }; 135 | /* End PBXGroup section */ 136 | 137 | /* Begin PBXHeadersBuildPhase section */ 138 | 07CABF39236FF35C00A50B58 /* Headers */ = { 139 | isa = PBXHeadersBuildPhase; 140 | buildActionMask = 2147483647; 141 | files = ( 142 | 07CABF43236FF35C00A50B58 /* XMindSDK.h in Headers */, 143 | ); 144 | runOnlyForDeploymentPostprocessing = 0; 145 | }; 146 | /* End PBXHeadersBuildPhase section */ 147 | 148 | /* Begin PBXNativeTarget section */ 149 | 07CABF3D236FF35C00A50B58 /* XMindSDK */ = { 150 | isa = PBXNativeTarget; 151 | buildConfigurationList = 07CABF46236FF35C00A50B58 /* Build configuration list for PBXNativeTarget "XMindSDK" */; 152 | buildPhases = ( 153 | 07CABF39236FF35C00A50B58 /* Headers */, 154 | 07CABF3A236FF35C00A50B58 /* Sources */, 155 | 07CABF3B236FF35C00A50B58 /* Frameworks */, 156 | 07CABF3C236FF35C00A50B58 /* Resources */, 157 | ); 158 | buildRules = ( 159 | ); 160 | dependencies = ( 161 | ); 162 | name = XMindSDK; 163 | productName = XMindSDK; 164 | productReference = 07CABF3E236FF35C00A50B58 /* XMindSDK.framework */; 165 | productType = "com.apple.product-type.framework"; 166 | }; 167 | /* End PBXNativeTarget section */ 168 | 169 | /* Begin PBXProject section */ 170 | 07CABF33236FF2D900A50B58 /* Project object */ = { 171 | isa = PBXProject; 172 | attributes = { 173 | LastUpgradeCheck = 1120; 174 | TargetAttributes = { 175 | 07CABF3D236FF35C00A50B58 = { 176 | CreatedOnToolsVersion = 11.1; 177 | LastSwiftMigration = 1110; 178 | }; 179 | }; 180 | }; 181 | buildConfigurationList = 07CABF36236FF2D900A50B58 /* Build configuration list for PBXProject "XMindSDK" */; 182 | compatibilityVersion = "Xcode 9.3"; 183 | developmentRegion = en; 184 | hasScannedForEncodings = 0; 185 | knownRegions = ( 186 | en, 187 | Base, 188 | ); 189 | mainGroup = 07CABF32236FF2D900A50B58; 190 | productRefGroup = 07CABF3F236FF35C00A50B58 /* Products */; 191 | projectDirPath = ""; 192 | projectRoot = ""; 193 | targets = ( 194 | 07CABF3D236FF35C00A50B58 /* XMindSDK */, 195 | ); 196 | }; 197 | /* End PBXProject section */ 198 | 199 | /* Begin PBXResourcesBuildPhase section */ 200 | 07CABF3C236FF35C00A50B58 /* Resources */ = { 201 | isa = PBXResourcesBuildPhase; 202 | buildActionMask = 2147483647; 203 | files = ( 204 | ); 205 | runOnlyForDeploymentPostprocessing = 0; 206 | }; 207 | /* End PBXResourcesBuildPhase section */ 208 | 209 | /* Begin PBXSourcesBuildPhase section */ 210 | 07CABF3A236FF35C00A50B58 /* Sources */ = { 211 | isa = PBXSourcesBuildPhase; 212 | buildActionMask = 2147483647; 213 | files = ( 214 | 07E117422399FF800042C083 /* Constants.swift in Sources */, 215 | 07B6604023700BE4000FE35A /* Workbook.swift in Sources */, 216 | 07637CA3237BCE4200E05FE9 /* Theme.swift in Sources */, 217 | 07637C9D237BAA4400E05FE9 /* Manifest.swift in Sources */, 218 | 07637CA1237BCD3300E05FE9 /* Relationship.swift in Sources */, 219 | 07E117372398A77B0042C083 /* TemporaryStorge.swift in Sources */, 220 | 0791AF522437E38900F5ECDC /* ElementsBuilder.swift in Sources */, 221 | 07B6604423701739000FE35A /* Error.swift in Sources */, 222 | 07E1173B2398B3E50042C083 /* EncryptionData.swift in Sources */, 223 | 07637CA5237BD16600E05FE9 /* Point.swift in Sources */, 224 | 07B6604223700C9B000FE35A /* Topic.swift in Sources */, 225 | 07637C9F237BB1AB00E05FE9 /* Metadata.swift in Sources */, 226 | 07FE404B23754B300070DE70 /* Sheet.swift in Sources */, 227 | 07637CA7237BD27E00E05FE9 /* Marker.swift in Sources */, 228 | 07E117392398B0EC0042C083 /* Crypto.swift in Sources */, 229 | 0791AF4A2437BD1C00F5ECDC /* Builders.swift in Sources */, 230 | ); 231 | runOnlyForDeploymentPostprocessing = 0; 232 | }; 233 | /* End PBXSourcesBuildPhase section */ 234 | 235 | /* Begin XCBuildConfiguration section */ 236 | 07CABF37236FF2D900A50B58 /* Debug */ = { 237 | isa = XCBuildConfiguration; 238 | buildSettings = { 239 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 240 | CLANG_WARN_BOOL_CONVERSION = YES; 241 | CLANG_WARN_COMMA = YES; 242 | CLANG_WARN_CONSTANT_CONVERSION = YES; 243 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 244 | CLANG_WARN_EMPTY_BODY = YES; 245 | CLANG_WARN_ENUM_CONVERSION = YES; 246 | CLANG_WARN_INFINITE_RECURSION = YES; 247 | CLANG_WARN_INT_CONVERSION = YES; 248 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 249 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 250 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 251 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 252 | CLANG_WARN_STRICT_PROTOTYPES = YES; 253 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 254 | CLANG_WARN_UNREACHABLE_CODE = YES; 255 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 256 | ENABLE_STRICT_OBJC_MSGSEND = YES; 257 | ENABLE_TESTABILITY = YES; 258 | GCC_NO_COMMON_BLOCKS = YES; 259 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 260 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 261 | GCC_WARN_UNDECLARED_SELECTOR = YES; 262 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 263 | GCC_WARN_UNUSED_FUNCTION = YES; 264 | GCC_WARN_UNUSED_VARIABLE = YES; 265 | ONLY_ACTIVE_ARCH = YES; 266 | }; 267 | name = Debug; 268 | }; 269 | 07CABF38236FF2D900A50B58 /* Release */ = { 270 | isa = XCBuildConfiguration; 271 | buildSettings = { 272 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 273 | CLANG_WARN_BOOL_CONVERSION = YES; 274 | CLANG_WARN_COMMA = YES; 275 | CLANG_WARN_CONSTANT_CONVERSION = YES; 276 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 277 | CLANG_WARN_EMPTY_BODY = YES; 278 | CLANG_WARN_ENUM_CONVERSION = YES; 279 | CLANG_WARN_INFINITE_RECURSION = YES; 280 | CLANG_WARN_INT_CONVERSION = YES; 281 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 282 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 283 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 284 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 285 | CLANG_WARN_STRICT_PROTOTYPES = YES; 286 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 287 | CLANG_WARN_UNREACHABLE_CODE = YES; 288 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 289 | ENABLE_STRICT_OBJC_MSGSEND = YES; 290 | GCC_NO_COMMON_BLOCKS = YES; 291 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 292 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 293 | GCC_WARN_UNDECLARED_SELECTOR = YES; 294 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 295 | GCC_WARN_UNUSED_FUNCTION = YES; 296 | GCC_WARN_UNUSED_VARIABLE = YES; 297 | }; 298 | name = Release; 299 | }; 300 | 07CABF44236FF35C00A50B58 /* Debug */ = { 301 | isa = XCBuildConfiguration; 302 | buildSettings = { 303 | ALWAYS_SEARCH_USER_PATHS = NO; 304 | CLANG_ANALYZER_NONNULL = YES; 305 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 306 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 307 | CLANG_CXX_LIBRARY = "libc++"; 308 | CLANG_ENABLE_MODULES = YES; 309 | CLANG_ENABLE_OBJC_ARC = YES; 310 | CLANG_ENABLE_OBJC_WEAK = YES; 311 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 312 | CLANG_WARN_BOOL_CONVERSION = YES; 313 | CLANG_WARN_COMMA = YES; 314 | CLANG_WARN_CONSTANT_CONVERSION = YES; 315 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 316 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 317 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 318 | CLANG_WARN_EMPTY_BODY = YES; 319 | CLANG_WARN_ENUM_CONVERSION = YES; 320 | CLANG_WARN_INFINITE_RECURSION = YES; 321 | CLANG_WARN_INT_CONVERSION = YES; 322 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 323 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 324 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 325 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 326 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 327 | CLANG_WARN_STRICT_PROTOTYPES = YES; 328 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 329 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 330 | CLANG_WARN_UNREACHABLE_CODE = YES; 331 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 332 | CODE_SIGN_STYLE = Automatic; 333 | COMBINE_HIDPI_IMAGES = YES; 334 | COPY_PHASE_STRIP = NO; 335 | CURRENT_PROJECT_VERSION = 1; 336 | DEBUG_INFORMATION_FORMAT = dwarf; 337 | DEFINES_MODULE = YES; 338 | DEVELOPMENT_TEAM = 4WV38P2X5K; 339 | DYLIB_COMPATIBILITY_VERSION = 1; 340 | DYLIB_CURRENT_VERSION = 1; 341 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 342 | ENABLE_STRICT_OBJC_MSGSEND = YES; 343 | ENABLE_TESTABILITY = YES; 344 | FRAMEWORK_SEARCH_PATHS = ""; 345 | "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*]" = ( 346 | "$(inherited)", 347 | "$(PROJECT_DIR)/Carthage/Build/iOS", 348 | ); 349 | "FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator*]" = ( 350 | "$(inherited)", 351 | "$(PROJECT_DIR)/Carthage/Build/iOS", 352 | ); 353 | "FRAMEWORK_SEARCH_PATHS[sdk=macosx*]" = ( 354 | "$(inherited)", 355 | "$(PROJECT_DIR)/Carthage/Build/Mac", 356 | ); 357 | GCC_C_LANGUAGE_STANDARD = gnu11; 358 | GCC_DYNAMIC_NO_PIC = NO; 359 | GCC_NO_COMMON_BLOCKS = YES; 360 | GCC_OPTIMIZATION_LEVEL = 0; 361 | GCC_PREPROCESSOR_DEFINITIONS = ( 362 | "DEBUG=1", 363 | "$(inherited)", 364 | ); 365 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 366 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 367 | GCC_WARN_UNDECLARED_SELECTOR = YES; 368 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 369 | GCC_WARN_UNUSED_FUNCTION = YES; 370 | GCC_WARN_UNUSED_VARIABLE = YES; 371 | INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; 372 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 373 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 374 | LD_RUNPATH_SEARCH_PATHS = ( 375 | "$(inherited)", 376 | "@executable_path/../Frameworks", 377 | "@loader_path/Frameworks", 378 | ); 379 | MACOSX_DEPLOYMENT_TARGET = 10.11; 380 | MARKETING_VERSION = 1.1.0; 381 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 382 | MTL_FAST_MATH = YES; 383 | ONLY_ACTIVE_ARCH = YES; 384 | PRODUCT_BUNDLE_IDENTIFIER = net.xmind.XMindSDK; 385 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 386 | SDKROOT = ""; 387 | SKIP_INSTALL = YES; 388 | SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator"; 389 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 390 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 391 | SWIFT_VERSION = 5.0; 392 | VERSIONING_SYSTEM = "apple-generic"; 393 | VERSION_INFO_PREFIX = ""; 394 | }; 395 | name = Debug; 396 | }; 397 | 07CABF45236FF35C00A50B58 /* Release */ = { 398 | isa = XCBuildConfiguration; 399 | buildSettings = { 400 | ALWAYS_SEARCH_USER_PATHS = NO; 401 | CLANG_ANALYZER_NONNULL = YES; 402 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 403 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 404 | CLANG_CXX_LIBRARY = "libc++"; 405 | CLANG_ENABLE_MODULES = YES; 406 | CLANG_ENABLE_OBJC_ARC = YES; 407 | CLANG_ENABLE_OBJC_WEAK = YES; 408 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 409 | CLANG_WARN_BOOL_CONVERSION = YES; 410 | CLANG_WARN_COMMA = YES; 411 | CLANG_WARN_CONSTANT_CONVERSION = YES; 412 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 413 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 414 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 415 | CLANG_WARN_EMPTY_BODY = YES; 416 | CLANG_WARN_ENUM_CONVERSION = YES; 417 | CLANG_WARN_INFINITE_RECURSION = YES; 418 | CLANG_WARN_INT_CONVERSION = YES; 419 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 420 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 421 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 422 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 423 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 424 | CLANG_WARN_STRICT_PROTOTYPES = YES; 425 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 426 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 427 | CLANG_WARN_UNREACHABLE_CODE = YES; 428 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 429 | CODE_SIGN_STYLE = Automatic; 430 | COMBINE_HIDPI_IMAGES = YES; 431 | COPY_PHASE_STRIP = NO; 432 | CURRENT_PROJECT_VERSION = 1; 433 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 434 | DEFINES_MODULE = YES; 435 | DEVELOPMENT_TEAM = 4WV38P2X5K; 436 | DYLIB_COMPATIBILITY_VERSION = 1; 437 | DYLIB_CURRENT_VERSION = 1; 438 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 439 | ENABLE_NS_ASSERTIONS = NO; 440 | ENABLE_STRICT_OBJC_MSGSEND = YES; 441 | FRAMEWORK_SEARCH_PATHS = ""; 442 | "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*]" = ( 443 | "$(inherited)", 444 | "$(PROJECT_DIR)/Carthage/Build/iOS", 445 | ); 446 | "FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator*]" = ( 447 | "$(inherited)", 448 | "$(PROJECT_DIR)/Carthage/Build/iOS", 449 | ); 450 | "FRAMEWORK_SEARCH_PATHS[sdk=macosx*]" = ( 451 | "$(inherited)", 452 | "$(PROJECT_DIR)/Carthage/Build/Mac", 453 | ); 454 | GCC_C_LANGUAGE_STANDARD = gnu11; 455 | GCC_NO_COMMON_BLOCKS = YES; 456 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 457 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 458 | GCC_WARN_UNDECLARED_SELECTOR = YES; 459 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 460 | GCC_WARN_UNUSED_FUNCTION = YES; 461 | GCC_WARN_UNUSED_VARIABLE = YES; 462 | INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; 463 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 464 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 465 | LD_RUNPATH_SEARCH_PATHS = ( 466 | "$(inherited)", 467 | "@executable_path/../Frameworks", 468 | "@loader_path/Frameworks", 469 | ); 470 | MACOSX_DEPLOYMENT_TARGET = 10.11; 471 | MARKETING_VERSION = 1.1.0; 472 | MTL_ENABLE_DEBUG_INFO = NO; 473 | MTL_FAST_MATH = YES; 474 | PRODUCT_BUNDLE_IDENTIFIER = net.xmind.XMindSDK; 475 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 476 | SDKROOT = ""; 477 | SKIP_INSTALL = YES; 478 | SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator"; 479 | SWIFT_COMPILATION_MODE = wholemodule; 480 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 481 | SWIFT_VERSION = 5.0; 482 | VALIDATE_PRODUCT = YES; 483 | VERSIONING_SYSTEM = "apple-generic"; 484 | VERSION_INFO_PREFIX = ""; 485 | }; 486 | name = Release; 487 | }; 488 | /* End XCBuildConfiguration section */ 489 | 490 | /* Begin XCConfigurationList section */ 491 | 07CABF36236FF2D900A50B58 /* Build configuration list for PBXProject "XMindSDK" */ = { 492 | isa = XCConfigurationList; 493 | buildConfigurations = ( 494 | 07CABF37236FF2D900A50B58 /* Debug */, 495 | 07CABF38236FF2D900A50B58 /* Release */, 496 | ); 497 | defaultConfigurationIsVisible = 0; 498 | defaultConfigurationName = Release; 499 | }; 500 | 07CABF46236FF35C00A50B58 /* Build configuration list for PBXNativeTarget "XMindSDK" */ = { 501 | isa = XCConfigurationList; 502 | buildConfigurations = ( 503 | 07CABF44236FF35C00A50B58 /* Debug */, 504 | 07CABF45236FF35C00A50B58 /* Release */, 505 | ); 506 | defaultConfigurationIsVisible = 0; 507 | defaultConfigurationName = Release; 508 | }; 509 | /* End XCConfigurationList section */ 510 | }; 511 | rootObject = 07CABF33236FF2D900A50B58 /* Project object */; 512 | } 513 | -------------------------------------------------------------------------------- /XMindSDK.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /XMindSDK.xcworkspace/xcshareddata/IDETemplateMacros.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | FILEHEADER 6 | 7 | // ___FILENAME___ 8 | // ___PROJECTNAME___ 9 | // 10 | // Created by ___USERNAME___ on ___DATE___. 11 | // 12 | // Copyright © ___YEAR___ XMind. 13 | // 14 | // Permission is hereby granted, free of charge, to any person obtaining a copy 15 | // of this software and associated documentation files (the "Software"), to deal 16 | // in the Software without restriction, including without limitation the rights 17 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 18 | // copies of the Software, and to permit persons to whom the Software is 19 | // furnished to do so, subject to the following conditions: 20 | // 21 | // The above copyright notice and this permission notice shall be included in 22 | // all copies or substantial portions of the Software. 23 | // 24 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 29 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 30 | // THE SOFTWARE. 31 | 32 | 33 | -------------------------------------------------------------------------------- /XMindSDK.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /doc/main.md: -------------------------------------------------------------------------------- 1 | # Documents 2 | 3 | The xmind file is a tree-like structure. The root component is named `Workbook`. You can use this class to create, modify a xmind file. 4 | 5 | Then a `Workbook` contains serval sheets which represent mind map panels. 6 | 7 | And a `Sheet` contains a root topic mainly, and some infomation of this mind map panel. 8 | 9 | 10 | 11 | #### Workbook 12 | 13 | ```swift 14 | 15 | /// A workbook is as a xmind file. 16 | /// You can open or new a workbook(xmind file). 17 | /// To opera a xmind file, workbook use a temporary storge at temporary path on the disk. 18 | /// The temporary content will be deleted while the workbook object deinited. 19 | /// If open an existing file, first you need call 'loadManifest()' , second call 'loadContent(password: String?)'. 20 | /// 21 | public final class Workbook { 22 | } 23 | 24 | extension Workbook { 25 | 26 | public var passwordHint: String? { get set } 27 | 28 | /// Load the existing manifest. 29 | /// Just only can read passwordHint after called "loadManifest" 30 | public func loadManifest() throws 31 | 32 | /// Load the existing content. 33 | /// - Parameter password: Password of the file. 34 | public func loadContent(password: String? = nil) throws 35 | 36 | /// The all sheets. 37 | public var allSheets: [Sheet] { get } 38 | 39 | /// Add a sheet to the workbook. 40 | public func add(sheet: Sheet) 41 | 42 | /// Remove a sheet from the workbook. 43 | public func remove(sheet: Sheet) 44 | 45 | /// Save as a xmind file at the given path. 46 | /// If a file already exists with this path, This method will throw an error that indicates this csae. 47 | /// - Parameter path: Path will save to. 48 | public func save(to path: String, password: String? = nil) throws 49 | } 50 | 51 | extension Workbook { 52 | 53 | /// Open a xmind file at the given file path. 54 | /// It will make a random temporary path by default. 55 | /// - Parameter filePath: The location of a xmind file which will be opened. 56 | public static func open(filePath: String) throws -> Workbook 57 | 58 | /// Open a xmind file at the given file path. 59 | /// - Parameters: 60 | /// - filePath: The location of a xmind file which will be opened. 61 | /// - temporaryPath: The temporary space that use to cache and opera temporary files. 62 | public static func open(filePath: String, temporaryPath: String) throws -> Workbook 63 | 64 | /// Create a new xmind file that is empty. 65 | /// - Parameter temporaryPath: The temporary space that use to cache and opera temporary files. 66 | public static func new(temporaryPath: String) throws -> Workbook 67 | 68 | /// Create a new xmind file that is empty. 69 | /// It will make a random temporary path by default. 70 | public static func new() throws -> Workbook 71 | } 72 | 73 | 74 | 75 | ``` 76 | 77 | #### Sheet 78 | 79 | ```swift 80 | /// Sheet represents a mind map panel 81 | /// which contains a root topic. 82 | public class Sheet : Codable { 83 | 84 | /// The unique ID of this sheet. 85 | public let id: String 86 | 87 | /// The class of this sheet. 88 | public let `class`: String 89 | 90 | /// Title of this sheet which represents the name of this panel. 91 | public var title: String 92 | 93 | /// The root topic of this panel. 94 | /// A sheet only can contains a root topic, 95 | public let rootTopic: Topic 96 | 97 | /// The topic positioning function. 98 | public let topicPositioning: String 99 | 100 | /// The relationships of this panel. 101 | public let relationships: [Relationship]? 102 | 103 | /// Theme of this panel. 104 | public let theme: Theme 105 | 106 | public init(title: String, rootTopic: Topic) 107 | } 108 | ``` 109 | 110 | #### Topic 111 | 112 | ```swift 113 | public class Topic : Codable { 114 | 115 | /// The unique ID of this topic. 116 | public let id: String 117 | 118 | /// The title of this topic. 119 | public var title: String? 120 | 121 | public init(title: String? = nil) 122 | } 123 | 124 | 125 | extension Topic { 126 | 127 | /// Add a topic to self. 128 | /// You cant add an ancestor topic, It do nothing. 129 | /// If the topic that to be added was alredy contained by self. it will not add twice. 130 | /// If the topic had a super topic, it will remove from origin super topic,then add to self. 131 | /// - Parameter topic: The topic to be added. 132 | public func addSubTopic(_ topic: Topic) 133 | 134 | /// A convenience function for add a topic. 135 | /// The behave is same as "addSubTopic(_ topic: Topic)". 136 | /// The returned topic is the new created topic. 137 | /// - Parameter title: Title of the new topic. 138 | public func addSubTopic(_ title: String) -> Topic 139 | 140 | /// Remove a sub topic. 141 | /// - Parameter topic: The sub topic. 142 | public func removeSubTopic(_ topic: Topic) 143 | 144 | /// If the topic has a super topic, it will remove from the super topic. 145 | public func removeFromSuperTopic() 146 | 147 | /// Add a marker to the topic, The same class marker can only add once. 148 | /// - Parameter marker: Marker to be added. 149 | public func addMarker(_ marker: Marker) 150 | 151 | /// Remove a marker. 152 | /// - Parameter marker: Marker to be removed. 153 | public func removeMarker(_ marker: Marker) 154 | } 155 | 156 | ``` 157 | 158 | --------------------------------------------------------------------------------