├── .DS_Store
├── logo.png
├── EasyShare
├── .DS_Store
├── Assets.xcassets
│ ├── Contents.json
│ ├── .DS_Store
│ ├── Logo.imageset
│ │ ├── new es logo.png
│ │ ├── new es logo@0,25x.png
│ │ ├── new es logo@0,5x.png
│ │ └── Contents.json
│ └── AppIcon.appiconset
│ │ ├── new es logo.png
│ │ ├── new es logo@0,5x-2.png
│ │ ├── new es logo@0,5x-3.png
│ │ ├── new es logo@0,25x-1.png
│ │ ├── new es logo@0,25x-2.png
│ │ ├── new es logo@0,25x@0,25x.png
│ │ ├── new es logo@0,25x@0,5x.png
│ │ ├── new es logo@0,25x@0,25x@0,5x.png
│ │ ├── new es logo@0,25x@0,25x@0,25x.png
│ │ ├── new es logo@0,25x@0,25x@0,5x-1.png
│ │ └── Contents.json
├── Preview Content
│ └── Preview Assets.xcassets
│ │ └── Contents.json
├── EasyShare.entitlements
├── Window.swift
├── AppDelegate.swift
├── Info.plist
├── DragView.swift
├── Base.lproj
│ └── Main.storyboard
└── Window.xib
├── ShareExtension
├── .DS_Store
├── icon.icns
├── Resource
│ ├── .DS_Store
│ └── wwwroot
│ │ ├── ESlogo.png
│ │ └── index.html
├── model
│ ├── ConfigMap.swift
│ └── db
│ │ ├── dto
│ │ ├── ConfigDTO.swift
│ │ └── ShareDTO.swift
│ │ └── DbHelper.swift
├── utils
│ └── DataUtils.swift
├── ShareExtension.entitlements
├── Info.plist
├── ShareViewController.swift
├── ShareServer.swift
└── Base.lproj
│ └── ShareViewController.xib
├── WX20200505-140330@2x.png
├── WX20200615-235553@2x.png
├── WX20200615-235713@2x.png
├── EasyShare.xcodeproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcuserdata
│ │ └── michaellee.xcuserdatad
│ │ │ ├── UserInterfaceState.xcuserstate
│ │ │ ├── IDEFindNavigatorScopes.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── xcshareddata
│ │ ├── WorkspaceSettings.xcsettings
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── swiftpm
│ │ └── Package.resolved
├── xcuserdata
│ └── michaellee.xcuserdatad
│ │ ├── xcschemes
│ │ └── xcschememanagement.plist
│ │ └── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
├── xcshareddata
│ └── xcschemes
│ │ ├── EasyShare.xcscheme
│ │ └── ShareExtension.xcscheme
└── project.pbxproj
├── Extension
├── Extension.entitlements
├── ShareViewController.swift
├── Info.plist
└── Base.lproj
│ └── ShareViewController.xib
├── EasyShareTests
├── Info.plist
└── EasyShareTests.swift
├── EasyShareUITests
├── Info.plist
└── EasyShareUITests.swift
├── README_zh.md
└── README.md
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaellee123/EasyShare/HEAD/.DS_Store
--------------------------------------------------------------------------------
/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaellee123/EasyShare/HEAD/logo.png
--------------------------------------------------------------------------------
/EasyShare/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaellee123/EasyShare/HEAD/EasyShare/.DS_Store
--------------------------------------------------------------------------------
/ShareExtension/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaellee123/EasyShare/HEAD/ShareExtension/.DS_Store
--------------------------------------------------------------------------------
/ShareExtension/icon.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaellee123/EasyShare/HEAD/ShareExtension/icon.icns
--------------------------------------------------------------------------------
/WX20200505-140330@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaellee123/EasyShare/HEAD/WX20200505-140330@2x.png
--------------------------------------------------------------------------------
/WX20200615-235553@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaellee123/EasyShare/HEAD/WX20200615-235553@2x.png
--------------------------------------------------------------------------------
/WX20200615-235713@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaellee123/EasyShare/HEAD/WX20200615-235713@2x.png
--------------------------------------------------------------------------------
/EasyShare/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/ShareExtension/Resource/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaellee123/EasyShare/HEAD/ShareExtension/Resource/.DS_Store
--------------------------------------------------------------------------------
/EasyShare/Assets.xcassets/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaellee123/EasyShare/HEAD/EasyShare/Assets.xcassets/.DS_Store
--------------------------------------------------------------------------------
/ShareExtension/Resource/wwwroot/ESlogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaellee123/EasyShare/HEAD/ShareExtension/Resource/wwwroot/ESlogo.png
--------------------------------------------------------------------------------
/EasyShare/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/EasyShare/Assets.xcassets/Logo.imageset/new es logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaellee123/EasyShare/HEAD/EasyShare/Assets.xcassets/Logo.imageset/new es logo.png
--------------------------------------------------------------------------------
/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaellee123/EasyShare/HEAD/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo.png
--------------------------------------------------------------------------------
/EasyShare/Assets.xcassets/Logo.imageset/new es logo@0,25x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaellee123/EasyShare/HEAD/EasyShare/Assets.xcassets/Logo.imageset/new es logo@0,25x.png
--------------------------------------------------------------------------------
/EasyShare/Assets.xcassets/Logo.imageset/new es logo@0,5x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaellee123/EasyShare/HEAD/EasyShare/Assets.xcassets/Logo.imageset/new es logo@0,5x.png
--------------------------------------------------------------------------------
/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,5x-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaellee123/EasyShare/HEAD/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,5x-2.png
--------------------------------------------------------------------------------
/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,5x-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaellee123/EasyShare/HEAD/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,5x-3.png
--------------------------------------------------------------------------------
/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,25x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaellee123/EasyShare/HEAD/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,25x-1.png
--------------------------------------------------------------------------------
/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,25x-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaellee123/EasyShare/HEAD/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,25x-2.png
--------------------------------------------------------------------------------
/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,25x@0,25x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaellee123/EasyShare/HEAD/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,25x@0,25x.png
--------------------------------------------------------------------------------
/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,25x@0,5x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaellee123/EasyShare/HEAD/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,25x@0,5x.png
--------------------------------------------------------------------------------
/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,25x@0,25x@0,5x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaellee123/EasyShare/HEAD/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,25x@0,25x@0,5x.png
--------------------------------------------------------------------------------
/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,25x@0,25x@0,25x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaellee123/EasyShare/HEAD/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,25x@0,25x@0,25x.png
--------------------------------------------------------------------------------
/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,25x@0,25x@0,5x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaellee123/EasyShare/HEAD/EasyShare/Assets.xcassets/AppIcon.appiconset/new es logo@0,25x@0,25x@0,5x-1.png
--------------------------------------------------------------------------------
/EasyShare.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/EasyShare/EasyShare.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/EasyShare.xcodeproj/project.xcworkspace/xcuserdata/michaellee.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaellee123/EasyShare/HEAD/EasyShare.xcodeproj/project.xcworkspace/xcuserdata/michaellee.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/EasyShare.xcodeproj/project.xcworkspace/xcuserdata/michaellee.xcuserdatad/IDEFindNavigatorScopes.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/ShareExtension/model/ConfigMap.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ConfigMap.swift
3 | // EasyShare
4 | //
5 | // Created by Michael Lee on 2020/5/4.
6 | // Copyright © 2020 Michael Lee. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class ConfigMap{
12 | /// 端口号
13 | static let port = "port"
14 | }
15 |
--------------------------------------------------------------------------------
/EasyShare.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/EasyShare.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Extension/Extension.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.files.user-selected.read-only
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ShareExtension/Resource/wwwroot/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Hello Motherfucker 666
4 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/EasyShare/Window.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Window.swift
3 | // EasyShare
4 | //
5 | // Created by Michael Lee on 2020/5/6.
6 | // Copyright © 2020 Michael Lee. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cocoa
11 | import SwiftUI
12 |
13 | class Window :NSWindowController{
14 | override func windowDidLoad() {
15 | super.windowDidLoad()
16 | // self.window?.titleVisibility = NSWindow.TitleVisibility.hidden
17 | // self.window?.titlebarAppearsTransparent = true
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/EasyShare/Assets.xcassets/Logo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "new es logo@0,25x.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "new es logo@0,5x.png",
10 | "idiom" : "universal",
11 | "scale" : "2x"
12 | },
13 | {
14 | "filename" : "new es logo.png",
15 | "idiom" : "universal",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "author" : "xcode",
21 | "version" : 1
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ShareExtension/utils/DataUtils.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DataUtils.swift
3 | // EasyShare
4 | //
5 | // Created by Michael Lee on 2020/5/4.
6 | // Copyright © 2020 Michael Lee. All rights reserved.
7 | //
8 | import PerfectCrypto
9 |
10 | import Foundation
11 |
12 | class DataUtils{
13 |
14 | static func generateKey(name :String) -> String{
15 | let md5 = "\(NSDate().timeIntervalSince1970)\(name)".digest(.md5)?.encode(.base64url)
16 | return String(validatingUTF8: md5!) ?? "\(NSDate().timeIntervalSince1970)\(name)"
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/EasyShare/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // EasyShare
4 | //
5 | // Created by Michael Lee on 2020/5/2.
6 | // Copyright © 2020 Michael Lee. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 | import SwiftUI
11 | import ShareExtension
12 |
13 | @NSApplicationMain
14 | class AppDelegate: NSObject, NSApplicationDelegate {
15 |
16 | func applicationDidFinishLaunching(_ aNotification: Notification) {
17 |
18 | Window(windowNibName: "Window").showWindow(nil)
19 | }
20 |
21 | func applicationWillTerminate(_ aNotification: Notification) {
22 | // Insert code here to tear down your application
23 | }
24 |
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/EasyShare.xcodeproj/project.xcworkspace/xcuserdata/michaellee.xcuserdatad/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildLocationStyle
6 | UseAppPreferences
7 | CustomBuildLocationType
8 | RelativeToDerivedData
9 | DerivedDataLocationStyle
10 | Default
11 | IssueFilterStyle
12 | ShowActiveSchemeOnly
13 | LiveSourceIssuesEnabled
14 |
15 | ShowSharedSchemesAutomaticallyEnabled
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/EasyShareTests/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 |
22 |
23 |
--------------------------------------------------------------------------------
/EasyShareUITests/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 |
22 |
23 |
--------------------------------------------------------------------------------
/README_zh.md:
--------------------------------------------------------------------------------
1 | # EasyShare
2 | 非常简单的从你的Mac分享文件到任何设备
3 |
4 | 
5 |
6 | ## 安装
7 |
8 | 下载release里面的文件,并且解压,把EaseShare.app拖进应用目录。这个app打开之后只有一些提示。
9 |
10 | 打开 系统偏好设置 -> 拓展 -> 共享菜单,并且勾选EasyShare。
11 |
12 | ## 使用
13 |
14 | 打开访达,选中你想要分享的文件,右键并选择共享->EasyShare,你就能得到一个像这样的二维码。
15 |
16 | 
17 |
18 | 保证你的设备都处于同一个网络下。
19 |
20 | 现在你可以在另一个设备的浏览器打开这个url进行下载了。当然,更方便的办法是,直接拿出手机扫码进浏览器。不要用微信。
21 |
22 | 在下载完成之前不要点`完成`按钮,否则会断开链接。
23 |
24 | 完事儿,就这么简单。
25 |
26 | ## 一些新东西
27 |
28 | 我发现可以在Safari和其他的浏览器里面使用macOS的`ShareExtension`,所以,现在可以使用`EasyShare`来生成二维码,使用手机扫码就可以访问这个网页了。只需要点击Safari右上角的按钮,在选择`EasyShare`就可以了。像这样。
29 |
30 | 
31 |
32 | 
33 |
34 | 但是我实在不知道怎么获取网页的标题, 并且苹果也没有提供文档。所以就这样吧。 😂
35 |
--------------------------------------------------------------------------------
/ShareExtension/ShareExtension.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.assets.movies.read-only
8 |
9 | com.apple.security.assets.music.read-only
10 |
11 | com.apple.security.assets.pictures.read-only
12 |
13 | com.apple.security.automation.apple-events
14 |
15 | com.apple.security.cs.allow-jit
16 |
17 | com.apple.security.files.downloads.read-only
18 |
19 | com.apple.security.files.user-selected.read-only
20 |
21 | com.apple.security.network.client
22 |
23 | com.apple.security.network.server
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ShareExtension/model/db/dto/ConfigDTO.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ConfigDTO.swift
3 | // EasyShare
4 | //
5 | // Created by Michael Lee on 2020/5/3.
6 | // Copyright © 2020 Michael Lee. All rights reserved.
7 | //
8 |
9 | import SQLiteStORM
10 | import StORM
11 |
12 |
13 | /// 配置表,key是主键,根据实际需求存储
14 | class ConfigDTO :SQLiteStORM{
15 | var key:String = ""
16 | var value:String = ""
17 | ///备注
18 | var remark:String = ""
19 | override open func table() -> String {
20 | return "tb_config"
21 | }
22 |
23 | override open func to(_ this: StORMRow) {
24 | key = this.data["key"] as! String
25 | value = this.data["value"] as! String
26 | remark = this.data["remark"] as! String
27 | }
28 |
29 | func rows() -> [ConfigDTO] {
30 | var rows = [ConfigDTO]()
31 | for i in 0.. String {
27 | return "tb_share"
28 | }
29 |
30 | override func to(_ this: StORMRow) {
31 | id = this.data["id"] as! Int
32 | name = this.data["name"] as! String
33 | key = this.data["key"] as! String
34 | path = this.data["path"] as! String
35 | createTime = Int64(this.data["createTime"] as! String)!
36 | }
37 |
38 | func rows() -> [ShareDTO] {
39 | var rows = [ShareDTO]()
40 | for i in 0..
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 | $(MARKETING_VERSION)
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | LSMinimumSystemVersion
24 | $(MACOSX_DEPLOYMENT_TARGET)
25 | NSHumanReadableCopyright
26 | Copyright © 2020 Michael Lee. All rights reserved.
27 | NSMainStoryboardFile
28 | Main
29 | NSPrincipalClass
30 | NSApplication
31 | NSSupportsAutomaticTermination
32 |
33 | NSSupportsSuddenTermination
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/Extension/ShareViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ShareViewController.swift
3 | // Extension
4 | //
5 | // Created by Michael Lee on 2020/5/4.
6 | // Copyright © 2020 Michael Lee. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | class ShareViewController: NSViewController {
12 |
13 | override var nibName: NSNib.Name? {
14 | return NSNib.Name("ShareViewController")
15 | }
16 |
17 | override func loadView() {
18 | super.loadView()
19 |
20 | // Insert code here to customize the view
21 | let item = self.extensionContext!.inputItems[0] as! NSExtensionItem
22 | if let attachments = item.attachments {
23 | NSLog("Attachments = %@", attachments as NSArray)
24 | } else {
25 | NSLog("No Attachments")
26 | }
27 | }
28 |
29 | @IBAction func send(_ sender: AnyObject?) {
30 | let outputItem = NSExtensionItem()
31 | // Complete implementation by setting the appropriate value on the output item
32 |
33 | let outputItems = [outputItem]
34 | self.extensionContext!.completeRequest(returningItems: outputItems, completionHandler: nil)
35 | }
36 |
37 | @IBAction func cancel(_ sender: AnyObject?) {
38 | let cancelError = NSError(domain: NSCocoaErrorDomain, code: NSUserCancelledError, userInfo: nil)
39 | self.extensionContext!.cancelRequest(withError: cancelError)
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/ShareExtension/model/db/DbHelper.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DbHelper.swift
3 | // EasyShare
4 | //
5 | // Created by Michael Lee on 2020/5/3.
6 | // Copyright © 2020 Michael Lee. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import SQLiteStORM
11 |
12 | class DbHelper{
13 | static func create() {
14 | SQLiteConnector.db = "./EasyShare.sqlite"
15 | do {
16 | try ConfigDTO().setup()
17 | //设置端口号
18 | let portConfig = ConfigDTO()
19 | portConfig.key = ConfigMap.port
20 | portConfig.value = "12580"
21 | portConfig.remark = "端口号"
22 | try createConfig(config: portConfig)
23 | }catch{
24 | fatalError("\(error)")
25 | }
26 | do{
27 | try ShareDTO().setup()
28 | }catch{
29 | fatalError("\(error)")
30 | }
31 | }
32 |
33 | /// 读取配置
34 | static func getConfig(key:String) throws ->ConfigDTO{
35 | let config = ConfigDTO()
36 | try config.get(key)
37 | return config
38 | }
39 |
40 | /// 创建配置,如果已经有了就不会再写入了
41 | static func createConfig(config:ConfigDTO) throws {
42 | let createConfig = ConfigDTO()
43 | createConfig.key = config.key
44 | try createConfig.get()
45 | if (createConfig.value.count == 0) {
46 | try config.create()
47 | }
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/Extension/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleDisplayName
8 | Extension
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIconFile
12 | icon
13 | CFBundleIdentifier
14 | $(PRODUCT_BUNDLE_IDENTIFIER)
15 | CFBundleInfoDictionaryVersion
16 | 6.0
17 | CFBundleName
18 | $(PRODUCT_NAME)
19 | CFBundlePackageType
20 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
21 | CFBundleShortVersionString
22 | 1.0
23 | CFBundleVersion
24 | 1
25 | LSMinimumSystemVersion
26 | $(MACOSX_DEPLOYMENT_TARGET)
27 | NSExtension
28 |
29 | NSExtensionAttributes
30 |
31 | NSExtensionActivationRule
32 | TRUEPREDICATE
33 |
34 | NSExtensionPointIdentifier
35 | com.apple.share-services
36 | NSExtensionPrincipalClass
37 | $(PRODUCT_MODULE_NAME).ShareViewController
38 |
39 | NSHumanReadableCopyright
40 | Copyright © 2020 Michael Lee. All rights reserved.
41 |
42 |
43 |
--------------------------------------------------------------------------------
/EasyShare/DragView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DragView.swift
3 | // EasyShare
4 | //
5 | // Created by Michael Lee on 2020/5/4.
6 | // Copyright © 2020 Michael Lee. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Cocoa
11 |
12 | protocol FileDragDelegate: class {
13 | func didFinishDrag(_ filePath:String)
14 | }
15 |
16 | class DragView: NSView {
17 | weak var delegate: FileDragDelegate?
18 |
19 | override func awakeFromNib() {
20 | super.awakeFromNib()
21 | self.registerForDraggedTypes([
22 | NSPasteboard.PasteboardType.fileURL,
23 | NSPasteboard.PasteboardType.fileContents
24 | ])
25 | }
26 |
27 | override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {
28 | let sourceDragMask = sender.draggingSourceOperationMask
29 | let pboard = sender.draggingPasteboard
30 | let dragTypes = pboard.types! as NSArray
31 | if dragTypes.contains(NSPasteboard.PasteboardType.fileContents) {
32 | if sourceDragMask.contains([.link]){
33 | return .link
34 | }
35 | if sourceDragMask.contains([.copy]){
36 | return .copy
37 | }
38 | }
39 | return .generic
40 | }
41 |
42 | override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
43 | let files = sender.draggingPasteboard.propertyList(forType: NSPasteboard.PasteboardType.fileContents)! as! Array
44 | print(files[0])
45 | return true
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/EasyShareUITests/EasyShareUITests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // EasyShareUITests.swift
3 | // EasyShareUITests
4 | //
5 | // Created by Michael Lee on 2020/5/2.
6 | // Copyright © 2020 Michael Lee. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | class EasyShareUITests: XCTestCase {
12 |
13 | override func setUpWithError() throws {
14 | // Put setup code here. This method is called before the invocation of each test method in the class.
15 |
16 | // In UI tests it is usually best to stop immediately when a failure occurs.
17 | continueAfterFailure = false
18 |
19 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
20 | }
21 |
22 | override func tearDownWithError() throws {
23 | // Put teardown code here. This method is called after the invocation of each test method in the class.
24 | }
25 |
26 | func testExample() throws {
27 | // UI tests must launch the application that they test.
28 | let app = XCUIApplication()
29 | app.launch()
30 |
31 | // Use recording to get started writing UI tests.
32 | // Use XCTAssert and related functions to verify your tests produce the correct results.
33 | }
34 |
35 | func testLaunchPerformance() throws {
36 | if #available(macOS 10.15, iOS 13.0, tvOS 13.0, *) {
37 | // This measures how long it takes to launch your application.
38 | measure(metrics: [XCTOSSignpostMetric.applicationLaunch]) {
39 | XCUIApplication().launch()
40 | }
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/EasyShare/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "new es logo@0,25x@0,25x@0,25x.png",
5 | "idiom" : "mac",
6 | "scale" : "1x",
7 | "size" : "16x16"
8 | },
9 | {
10 | "filename" : "new es logo@0,25x@0,25x@0,5x-1.png",
11 | "idiom" : "mac",
12 | "scale" : "2x",
13 | "size" : "16x16"
14 | },
15 | {
16 | "filename" : "new es logo@0,25x@0,25x@0,5x.png",
17 | "idiom" : "mac",
18 | "scale" : "1x",
19 | "size" : "32x32"
20 | },
21 | {
22 | "filename" : "new es logo@0,25x@0,25x.png",
23 | "idiom" : "mac",
24 | "scale" : "2x",
25 | "size" : "32x32"
26 | },
27 | {
28 | "filename" : "new es logo@0,25x@0,5x.png",
29 | "idiom" : "mac",
30 | "scale" : "1x",
31 | "size" : "128x128"
32 | },
33 | {
34 | "filename" : "new es logo@0,25x-1.png",
35 | "idiom" : "mac",
36 | "scale" : "2x",
37 | "size" : "128x128"
38 | },
39 | {
40 | "filename" : "new es logo@0,25x-2.png",
41 | "idiom" : "mac",
42 | "scale" : "1x",
43 | "size" : "256x256"
44 | },
45 | {
46 | "filename" : "new es logo@0,5x-2.png",
47 | "idiom" : "mac",
48 | "scale" : "2x",
49 | "size" : "256x256"
50 | },
51 | {
52 | "filename" : "new es logo@0,5x-3.png",
53 | "idiom" : "mac",
54 | "scale" : "1x",
55 | "size" : "512x512"
56 | },
57 | {
58 | "filename" : "new es logo.png",
59 | "idiom" : "mac",
60 | "scale" : "2x",
61 | "size" : "512x512"
62 | }
63 | ],
64 | "info" : {
65 | "author" : "xcode",
66 | "version" : 1
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/EasyShare.xcodeproj/xcuserdata/michaellee.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | EasyShare.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 | MyPlayground (Playground) 1.xcscheme
13 |
14 | isShown
15 |
16 | orderHint
17 | 3
18 |
19 | MyPlayground (Playground) 2.xcscheme
20 |
21 | isShown
22 |
23 | orderHint
24 | 4
25 |
26 | MyPlayground (Playground).xcscheme
27 |
28 | isShown
29 |
30 | orderHint
31 | 2
32 |
33 | Server.xcscheme_^#shared#^_
34 |
35 | orderHint
36 | 2
37 |
38 | ShareExtension.xcscheme_^#shared#^_
39 |
40 | orderHint
41 | 1
42 |
43 |
44 | SuppressBuildableAutocreation
45 |
46 | 9071415B245DCC61008D5294
47 |
48 | primary
49 |
50 |
51 | 90714170245DCC62008D5294
52 |
53 | primary
54 |
55 |
56 | 9071417B245DCC62008D5294
57 |
58 | primary
59 |
60 |
61 | 90C7A79224605D7300F7369C
62 |
63 | primary
64 |
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # EasyShare [简体中文](README_zh.md)
2 | Easy Share File From Mac To Every Device
3 |
4 | 
5 |
6 | ## Install
7 |
8 | Download the release package and unzip it, copy the EasyShare.app into Applications dir. This app is just some tips.
9 |
10 | Open System Preferences -> Extensions -> Share Menu, and select EasyShare.
11 |
12 | ## Use
13 |
14 | Open the finder, select the file you want to share, right-click, then select share -> EasyShare, you will see a QR code on your screen, like this.
15 |
16 | 
17 |
18 | Your devices should be connected to the same Wi-Fi.
19 |
20 | Then, you can copy the URL and open it in your browser to download. But, the most convenient way is to use your smartphone to scan this QR code.
21 |
22 | Do not click the `完成` button before the download is completed, otherwise, the link will be disconnected.
23 |
24 | That's all, everything is so easy!
25 |
26 | ## For Pro Man
27 |
28 | The default HTTP port is 12580, if you want to change it, you can search `EasyShare.sqlite` and change something.
29 |
30 | ## Something New
31 |
32 | I found macOS's `ShareExtension` can used in Safari and other browsers. So you can share web pages by `EasyShare` now. Just click the right-top button in Safari, and select `EasyShare`, you will get a QR code, then you can scan it to visit this web page on your smartphone, like this.
33 |
34 | 
35 |
36 | 
37 |
38 | But I don't know how to get the web page's title, and Apple provides no document. So, let it be. haha :)
39 |
40 | ## One More Thing
41 |
42 | There is a way to send a file from Android to Mac, [Check here for download `AndDrop`](https://play.google.com/store/apps/details?id=com.neure.anddrop).
43 |
44 |
45 | [
](https://ko-fi.com/michaellee123)
46 |
--------------------------------------------------------------------------------
/ShareExtension/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleDisplayName
8 | EasyShare
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
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 | $(MARKETING_VERSION)
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | LSMinimumSystemVersion
24 | $(MACOSX_DEPLOYMENT_TARGET)
25 | NSExtension
26 |
27 | NSExtensionAttributes
28 |
29 | NSExtensionActivationRule
30 |
31 | NSExtensionActivationSupportsAttachmentsWithMaxCount
32 | 1
33 | NSExtensionActivationSupportsAttachmentsWithMinCount
34 | 0
35 | NSExtensionActivationSupportsFileWithMaxCount
36 | 1
37 | NSExtensionActivationSupportsImageWithMaxCount
38 | 1
39 | NSExtensionActivationSupportsMovieWithMaxCount
40 | 1
41 | NSExtensionActivationSupportsWebPageWithMaxCount
42 | 1
43 | NSExtensionActivationSupportsWebURLWithMaxCount
44 | 1
45 |
46 |
47 | NSExtensionMainNibFile
48 | ShareViewController
49 | NSExtensionPointIdentifier
50 | com.apple.share-services
51 | NSExtensionPrincipalClass
52 | $(PRODUCT_MODULE_NAME).ShareViewController
53 |
54 | NSHumanReadableCopyright
55 | Copyright © 2020 Michael Lee. All rights reserved.
56 |
57 |
58 |
--------------------------------------------------------------------------------
/EasyShare/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/EasyShare.xcodeproj/xcuserdata/michaellee.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
9 |
21 |
22 |
23 |
25 |
37 |
38 |
39 |
41 |
53 |
54 |
55 |
57 |
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/EasyShare.xcodeproj/xcshareddata/xcschemes/EasyShare.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
43 |
49 |
50 |
51 |
52 |
53 |
63 |
65 |
71 |
72 |
73 |
74 |
80 |
82 |
88 |
89 |
90 |
91 |
93 |
94 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/EasyShare.xcodeproj/xcshareddata/xcschemes/ShareExtension.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
6 |
9 |
10 |
16 |
22 |
23 |
24 |
30 |
36 |
37 |
38 |
39 |
40 |
45 |
46 |
47 |
48 |
60 |
64 |
65 |
66 |
72 |
73 |
74 |
75 |
82 |
84 |
90 |
91 |
92 |
93 |
95 |
96 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/EasyShare/Window.xib:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/EasyShare.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved:
--------------------------------------------------------------------------------
1 | {
2 | "object": {
3 | "pins": [
4 | {
5 | "package": "COpenSSL",
6 | "repositoryURL": "https://github.com/PerfectlySoft/Perfect-COpenSSL.git",
7 | "state": {
8 | "branch": null,
9 | "revision": "ce3113e159b8c6d8565e5d8db2672b572c81aea9",
10 | "version": "4.0.2"
11 | }
12 | },
13 | {
14 | "package": "PerfectCRUD",
15 | "repositoryURL": "https://github.com/PerfectlySoft/Perfect-CRUD.git",
16 | "state": {
17 | "branch": null,
18 | "revision": "5a947634b7ce0b991e8f455a61ce02449f2e6f36",
19 | "version": "1.2.3"
20 | }
21 | },
22 | {
23 | "package": "PerfectCrypto",
24 | "repositoryURL": "https://github.com/PerfectlySoft/Perfect-Crypto.git",
25 | "state": {
26 | "branch": null,
27 | "revision": "98373fa3a6c3d551e498c1babe4f25f650fa1310",
28 | "version": "3.3.0"
29 | }
30 | },
31 | {
32 | "package": "PerfectCURL",
33 | "repositoryURL": "https://github.com/PerfectlySoft/Perfect-CURL.git",
34 | "state": {
35 | "branch": null,
36 | "revision": "a9f8950554585bd12b9ec24ad4bfbe0b1519e03f",
37 | "version": "3.1.0"
38 | }
39 | },
40 | {
41 | "package": "PerfectCZlib",
42 | "repositoryURL": "https://github.com/PerfectlySoft/Perfect-CZlib-src.git",
43 | "state": {
44 | "branch": null,
45 | "revision": "b63e46909aad937c6434766f8f8c6720d8f3bd05",
46 | "version": "0.0.4"
47 | }
48 | },
49 | {
50 | "package": "PerfectHTTP",
51 | "repositoryURL": "https://github.com/PerfectlySoft/Perfect-HTTP.git",
52 | "state": {
53 | "branch": null,
54 | "revision": "122affd0bb5090c61bdc1e50e7f32ab6457d228e",
55 | "version": "3.3.0"
56 | }
57 | },
58 | {
59 | "package": "PerfectHTTPServer",
60 | "repositoryURL": "https://github.com/PerfectlySoft/Perfect-HTTPServer.git",
61 | "state": {
62 | "branch": null,
63 | "revision": "4843cd54762d59b7e70841663ae561b279b80946",
64 | "version": "3.0.23"
65 | }
66 | },
67 | {
68 | "package": "cURL",
69 | "repositoryURL": "https://github.com/PerfectlySoft/Perfect-libcurl.git",
70 | "state": {
71 | "branch": null,
72 | "revision": "b3d7e65ef5c27c0a027cdc621f34835975301bf1",
73 | "version": "2.1.0"
74 | }
75 | },
76 | {
77 | "package": "PerfectLogger",
78 | "repositoryURL": "https://github.com/PerfectlySoft/Perfect-Logger.git",
79 | "state": {
80 | "branch": null,
81 | "revision": "78f47107c9f7563cf94e3b5d141ca8bf0cc2f995",
82 | "version": "3.3.0"
83 | }
84 | },
85 | {
86 | "package": "PerfectNet",
87 | "repositoryURL": "https://github.com/PerfectlySoft/Perfect-Net.git",
88 | "state": {
89 | "branch": null,
90 | "revision": "d00b2b9f4cccb4c398e1bcf18f767d6b8add6af7",
91 | "version": "3.3.0"
92 | }
93 | },
94 | {
95 | "package": "PerfectSQLite",
96 | "repositoryURL": "https://github.com/PerfectlySoft/Perfect-SQLite.git",
97 | "state": {
98 | "branch": null,
99 | "revision": "420002c79529f8307cf0dda832069a46e466ae82",
100 | "version": "3.1.4"
101 | }
102 | },
103 | {
104 | "package": "PerfectCSQLite3",
105 | "repositoryURL": "https://github.com/PerfectlySoft/Perfect-sqlite3-support.git",
106 | "state": {
107 | "branch": null,
108 | "revision": "64c2bd87e1fd3a41cdeeba073bab794db7e97e42",
109 | "version": "3.1.1"
110 | }
111 | },
112 | {
113 | "package": "PerfectThread",
114 | "repositoryURL": "https://github.com/PerfectlySoft/Perfect-Thread.git",
115 | "state": {
116 | "branch": null,
117 | "revision": "a50b9a33f08fce638f33ae3121613fe499cc23ec",
118 | "version": "3.0.7"
119 | }
120 | },
121 | {
122 | "package": "PerfectLib",
123 | "repositoryURL": "https://github.com/PerfectlySoft/PerfectLib.git",
124 | "state": {
125 | "branch": null,
126 | "revision": "5a08c2a596df23a3ae30b6ac9cb509a38384166c",
127 | "version": "3.1.4"
128 | }
129 | },
130 | {
131 | "package": "SQLiteStORM",
132 | "repositoryURL": "https://github.com/SwiftORM/SQLite-StORM.git",
133 | "state": {
134 | "branch": null,
135 | "revision": "dd4cf565ef9ebd7fb2589b64a77e49365f69c681",
136 | "version": "3.1.0"
137 | }
138 | },
139 | {
140 | "package": "StORM",
141 | "repositoryURL": "https://github.com/SwiftORM/StORM.git",
142 | "state": {
143 | "branch": null,
144 | "revision": "6b29b65bae2b15c7c32c151141f9b3345ec7c881",
145 | "version": "3.3.0"
146 | }
147 | },
148 | {
149 | "package": "SwiftMoment",
150 | "repositoryURL": "https://github.com/iamjono/SwiftMoment.git",
151 | "state": {
152 | "branch": null,
153 | "revision": "c2ed4248beb6b3b9c93520dd32be0a92f2fee241",
154 | "version": "1.3.0"
155 | }
156 | }
157 | ]
158 | },
159 | "version": 1
160 | }
161 |
--------------------------------------------------------------------------------
/Extension/Base.lproj/ShareViewController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
30 |
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 |
--------------------------------------------------------------------------------
/ShareExtension/ShareViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ShareViewController.swift
3 | // ShareExtension
4 | //
5 | // Created by Michael Lee on 2020/5/4.
6 | // Copyright © 2020 Michael Lee. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 | import PerfectLib
11 | import SwiftUI
12 |
13 | class ShareViewController: NSViewController {
14 |
15 | @IBOutlet weak var titleCell: NSTextFieldCell!
16 | @IBOutlet weak var imageCell: NSImageCell!
17 | @IBOutlet weak var urlCell: NSTextFieldCell!
18 |
19 | var id = 0
20 | var url = ""
21 |
22 | override var nibName: NSNib.Name? {
23 | return NSNib.Name("ShareViewController")
24 | }
25 |
26 | override func loadView() {
27 | super.loadView()
28 | }
29 |
30 | override func viewDidLoad() {
31 | super.viewDidLoad()
32 | let item = self.extensionContext!.inputItems[0] as! NSExtensionItem
33 | let provider = item.attachments?[0]
34 | provider?.loadItem(forTypeIdentifier: kUTTypeURL as String, options: nil, completionHandler: {data,error in
35 | let nsData = data as! NSData
36 | let url = NSURL(dataRepresentation: nsData as Data, relativeTo: nil)
37 | let path = url.absoluteString
38 | if(path!.starts(with: "file://")){
39 | self.shareFile(path: url.path!)
40 | }else if(path!.starts(with: "http://") || path!.starts(with: "https://")){
41 | self.shareWeb(path: path!)
42 | }else{
43 | self.extensionContext!.completeRequest(returningItems: [NSExtensionItem()], completionHandler: nil)
44 | }
45 | })
46 | }
47 |
48 | func shareFile(path:String) {
49 | DbHelper.create()
50 | ShareServer.instance.start()
51 | let file = File(path)
52 | if(file.exists){
53 | let splits = file.path.split(separator: "/")
54 | let name = splits[splits.count-1]
55 | let share = ShareDTO()
56 | share.name = "\(name)"
57 | share.path = file.path.replacingOccurrences(of: "/\(name)", with: "")
58 | share.key = DataUtils.generateKey(name: share.name)
59 | do{
60 | try share.save{ id in
61 | share.id = id as! Int
62 | self.id = share.id
63 | }
64 | }catch{
65 | fatalError("\(error)")
66 | }
67 | self.findAllShare()
68 | self.showWindowInfo(
69 | url: "http://\(self.getIFAddresses()[0]):\(ShareServer.instance.port)/api/download/\(share.key)",
70 | title: share.name
71 | )
72 | }else{
73 | self.extensionContext!.completeRequest(returningItems: [NSExtensionItem()], completionHandler: nil)
74 | }
75 | }
76 |
77 | func shareWeb(path:String){
78 | self.showWindowInfo(url: path, title: "我是真的不知道Title怎么获取😅👌")
79 | }
80 |
81 | func showWindowInfo(url:String,title:String) {
82 | self.url = url
83 | self.urlCell.stringValue = url
84 | self.titleCell.stringValue = title
85 | self.imageCell.image = self.generateQRCodeImage(self.url, size: NSSize(width: 600, height: 600))
86 | }
87 |
88 | @IBAction func copy(_ sender: NSButton) {
89 | let pasteboard = NSPasteboard.general
90 | pasteboard.declareTypes([NSPasteboard.PasteboardType.string], owner: nil)
91 | let b = pasteboard.setString(url, forType: NSPasteboard.PasteboardType.string)
92 | print(b)
93 | }
94 |
95 | @IBAction func send(_ sender: AnyObject?) {
96 |
97 | ShareServer.instance.stop()
98 | let share = ShareDTO()
99 | do{
100 | try share.delete(id)
101 | }catch{
102 | NSLog("\(error)")
103 | }
104 | self.extensionContext!.completeRequest(returningItems: [NSExtensionItem()], completionHandler: nil)
105 | }
106 |
107 | func generateQRCodeImage(_ content: String, size: NSSize) -> NSImage?{
108 | // 创建滤镜
109 | guard let filter = CIFilter(name: "CIQRCodeGenerator") else {return nil}
110 | // 还原滤镜的默认属性
111 | filter.setDefaults()
112 | //1.3 设置生成的二维码的容错率
113 | //value = @"L/M/Q/H"
114 | filter.setValue("L", forKey: "inputCorrectionLevel")
115 | // 设置需要生成的二维码数据
116 | let contentData = content.data(using: String.Encoding.utf8)
117 | filter.setValue(contentData, forKey: "inputMessage")
118 |
119 |
120 | // 从滤镜中取出生成的图片
121 | guard let ciImage = filter.outputImage else {return nil}
122 |
123 | let context = CIContext(options: nil)
124 | let bitmapImage = context.createCGImage(ciImage, from: ciImage.extent)
125 |
126 | let colorSpace = CGColorSpaceCreateDeviceGray()
127 | let bitmapContext = CGContext(data: nil, width: Int(size.width), height: Int(size.height), bitsPerComponent: 8, bytesPerRow: 0, space: colorSpace, bitmapInfo: CGImageAlphaInfo.none.rawValue)
128 |
129 | //draw image
130 | let scale = min(size.width / ciImage.extent.width, size.height / ciImage.extent.height)
131 | bitmapContext!.interpolationQuality = CGInterpolationQuality.none
132 | bitmapContext?.scaleBy(x: scale, y: scale)
133 | bitmapContext?.draw(bitmapImage!, in: ciImage.extent)
134 |
135 | //保存bitmap到图片
136 | guard let scaledImage = bitmapContext?.makeImage() else {return nil}
137 |
138 | return NSImage(cgImage: scaledImage, size: size)
139 | }
140 |
141 | func getIFAddresses() -> [String] {
142 | var addresses = [String]()
143 |
144 | // Get list of all interfaces on the local machine:
145 | var ifaddr : UnsafeMutablePointer? = nil
146 | if getifaddrs(&ifaddr) == 0 {
147 |
148 | var ptr = ifaddr
149 | while ptr != nil {
150 | let flags = Int32((ptr?.pointee.ifa_flags)!)
151 | var addr = ptr?.pointee.ifa_addr.pointee
152 |
153 | // Check for running IPv4, IPv6 interfaces. Skip the loopback interface.
154 | if (flags & (IFF_UP|IFF_RUNNING|IFF_LOOPBACK)) == (IFF_UP|IFF_RUNNING) {
155 | if addr?.sa_family == UInt8(AF_INET) && addr?.sa_family != UInt8(AF_INET6) {
156 |
157 | // Convert interface address to a human readable string:
158 | var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
159 | if (getnameinfo(&addr!, socklen_t((addr?.sa_len)!), &hostname, socklen_t(hostname.count),
160 | nil, socklen_t(0), NI_NUMERICHOST) == 0) {
161 | if let address = String(validatingUTF8: hostname) {
162 | addresses.append(address)
163 | }
164 | }
165 | }
166 | }
167 | ptr = ptr?.pointee.ifa_next
168 | }
169 |
170 | freeifaddrs(ifaddr)
171 | }
172 | print("Local IP \(addresses)")
173 | return addresses
174 | }
175 |
176 | func findAllShare(){
177 | let share = ShareDTO()
178 | do{
179 | try share.findAll()
180 | let rows = share.rows()
181 | for row in rows{
182 | print(row.asDataDict())
183 | }
184 | }catch{
185 | fatalError("\(error)")
186 | }
187 | }
188 |
189 | }
190 |
--------------------------------------------------------------------------------
/ShareExtension/ShareServer.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Server.swift
3 | // EasyShare
4 | //
5 | // Created by Michael Lee on 2020/5/3.
6 | // Copyright © 2020 Michael Lee. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import PerfectHTTP
11 | import PerfectLib
12 | import PerfectHTTPServer
13 | import Cocoa
14 |
15 | class ShareServer{
16 |
17 | static let instance = ShareServer()
18 |
19 | init() {
20 | addApi()
21 | addWeb()
22 | routes.add(api)
23 | routes.add(web)
24 | }
25 |
26 | var state = 0
27 |
28 | var port :UInt16 = 8899
29 |
30 | let queue = DispatchQueue.global()
31 |
32 | var httpServer = HTTPServer()
33 |
34 | var routes = Routes()
35 |
36 | var api = Routes(baseUri: "/api")
37 |
38 | var web = Routes(baseUri: "/web")
39 |
40 | func start(){
41 | if state == 1 {
42 | return
43 | }
44 | state = 1
45 | httpServer.serverName = "EasyShare"
46 | httpServer.addRoutes(routes)
47 | do{
48 | try httpServer.serverPort = UInt16(DbHelper.getConfig(key: ConfigMap.port).value) ?? port
49 | }catch{
50 | httpServer.serverPort = port
51 | }
52 | port = httpServer.serverPort
53 |
54 | queue.async {
55 | do{
56 | try self.httpServer.start()
57 | }catch{
58 | self.state = 0
59 | fatalError("\(error)")
60 | }
61 | }
62 | }
63 |
64 | func stop(){
65 | httpServer.stop()
66 | state = 0
67 | }
68 |
69 | func addApi() {
70 | /// 获取分享详情
71 | api.add(method: .get, uri: "/info/{key}", handler: {request,response in
72 | let key = request.urlVariables["key"]
73 | let share = ShareDTO()
74 | do {
75 | try share.find([("key",key!)])
76 | }catch{
77 | do{
78 | try response.setBody(json: self.createResponseBody(code: 500, message: "key error", data: nil))
79 | }catch{
80 | response.setBody(string: "\(error)")
81 | }
82 | response.completed()
83 | return
84 | }
85 | if(share.id == 0){
86 | do{
87 | try response.setBody(json: self.createResponseBody(code: 404, message: "key not found", data: nil))
88 | }catch{
89 | response.setBody(string: "\(error)")
90 | }
91 | response.completed()
92 | }else{
93 | do{
94 | try response.setBody(json:
95 | self.createResponseBody(
96 | code: 200,
97 | message: "success",
98 | data: share.asDataDict()))
99 | }catch{
100 | response.setBody(string: "\(error)")
101 | }
102 | response.completed()
103 | }
104 | })
105 |
106 | api.add(method: .get, uri: "/download/{key}", handler: {request,response in
107 | let share = ShareDTO()
108 | let key = request.urlVariables["key"]
109 | do {
110 | try share.find([("key",key!)])
111 | }catch{
112 | do{
113 | try response.setBody(json: self.createResponseBody(code: 500, message: "key error", data: nil))
114 | }catch{
115 | response.setBody(string: "\(error)")
116 | }
117 | response.completed()
118 | return
119 | }
120 |
121 | if(share.id == 0){
122 | do{
123 | try response.setBody(json: self.createResponseBody(code: 404, message: "key not found", data: nil))
124 | }catch{
125 | response.setBody(string: "\(error)")
126 | }
127 | response.completed()
128 | return
129 | }
130 | //重定向
131 |
132 | //获取文件
133 | let file = File(share.path + "/" + share.name)
134 | if(file.exists && !file.isDir){
135 | do{
136 | try file.open()
137 | let size = file.size
138 | let contentType = MimeType.forExtension(file.path.filePathExtension)
139 | response.status = .ok
140 | response.isStreaming = true
141 | response.setHeader(.contentType, value: contentType)
142 | response.setHeader(.contentLength, value: "\(size)")
143 | response.setHeader(.acceptRanges, value: "bytes")
144 | response.setHeader(.contentDisposition, value: "attachment;filename=\"\(share.name)\"")
145 | self.pushBody(response: response, file: file)
146 | // try response.appendBody(bytes: file.readSomeBytes(count: size))
147 | // let handler = StaticFileHandler(documentRoot: share.path)
148 | // request.path = share.name
149 | // handler.handleRequest(request: request, response: response)
150 | }catch{
151 | response.setBody(string: "\(error)")
152 | response.completed()
153 | }
154 | }else{
155 | //文件不存在
156 | do{
157 | try response.setBody(json: self.createResponseBody(code: 404, message: "file not exists", data: nil))
158 | } catch {
159 | response.setBody(string: "\(error)")
160 | }
161 | response.completed()
162 | }
163 | })
164 |
165 | api.add(method: .post, uri: "/upload/{key}"){request,response in
166 | if let uploads = request.postFileUploads, uploads.count > 0 {
167 | for upload in uploads{
168 | let file = File(upload.tmpFileName)
169 | do{
170 | try file.moveTo(path: "/Users/michaellee/Desktop/upload/"+upload.fileName,overWrite: true)
171 | } catch {
172 | print("\(error)")
173 | }
174 | }
175 | do {
176 | try response.setBody(json: self.createResponseBody(code: 200, message: "上传成功", data: nil))
177 | } catch {
178 | response.setBody(string: "\(error)")
179 | }
180 | }
181 | response.completed()
182 | }
183 |
184 | }
185 |
186 | func pushBody(response:HTTPResponse,file:File){
187 | let readSize = 5 * 1024 * 1024//每次读5m
188 | var bytes :[UInt8]
189 | do {
190 | bytes = try file.readSomeBytes(count: readSize)
191 | }catch{
192 | bytes = [UInt8]()
193 | }
194 | if(bytes.count==0){
195 | file.close()
196 | response.completed()
197 | return
198 | }
199 | response.appendBody(bytes: bytes)
200 | response.push(callback: { bool in
201 | if(bool){
202 | self.pushBody(response: response, file: file)
203 | }else{
204 | file.close()
205 | response.completed(status: HTTPResponseStatus.gatewayTimeout)
206 | }
207 | })
208 | }
209 |
210 | func addWeb() {
211 | web.add(method: .get, uri: "/**"){request,response in
212 | request.path = request.urlVariables[routeTrailingWildcardKey]!
213 | //allowResponseFilters=true 才能够访问
214 | let handler = StaticFileHandler(documentRoot: Bundle.main.resourcePath! , allowResponseFilters: true)
215 | handler.handleRequest(request: request, response: response)
216 | }
217 | }
218 |
219 | func createResponseBody(code:Int,message:String,data:Any?) -> [String:Any] {
220 | return ["code":code,"message":message,"data":data ?? [String:Any]()]
221 | }
222 |
223 | }
224 |
--------------------------------------------------------------------------------
/ShareExtension/Base.lproj/ShareViewController.xib:
--------------------------------------------------------------------------------
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 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
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 |
--------------------------------------------------------------------------------
/EasyShare.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 52;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 906B7534245DF6AE00662E03 /* PerfectHTTPServer in Frameworks */ = {isa = PBXBuildFile; productRef = 906B7533245DF6AE00662E03 /* PerfectHTTPServer */; };
11 | 90714160245DCC61008D5294 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9071415F245DCC61008D5294 /* AppDelegate.swift */; };
12 | 90714164245DCC62008D5294 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 90714163245DCC62008D5294 /* Assets.xcassets */; };
13 | 90714167245DCC62008D5294 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 90714166245DCC62008D5294 /* Preview Assets.xcassets */; };
14 | 9071416A245DCC62008D5294 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 90714168245DCC62008D5294 /* Main.storyboard */; };
15 | 90714176245DCC62008D5294 /* EasyShareTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90714175245DCC62008D5294 /* EasyShareTests.swift */; };
16 | 90714181245DCC62008D5294 /* EasyShareUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90714180245DCC62008D5294 /* EasyShareUITests.swift */; };
17 | 907B97EC24605F7A00F38E15 /* ShareServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90997479245DDF6900931C1F /* ShareServer.swift */; };
18 | 908DB5332574C6A8008AF55D /* ESlogo.png in Resources */ = {isa = PBXBuildFile; fileRef = 908DB5322574C6A8008AF55D /* ESlogo.png */; };
19 | 9096CC71245F14D700AC750B /* SQLiteStORM in Frameworks */ = {isa = PBXBuildFile; productRef = 9096CC70245F14D700AC750B /* SQLiteStORM */; };
20 | 9096CC78245F18A400AC750B /* ConfigDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9096CC77245F18A400AC750B /* ConfigDTO.swift */; };
21 | 9096CC7A245F18B700AC750B /* ShareDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9096CC79245F18B700AC750B /* ShareDTO.swift */; };
22 | 9096CC81245F21D700AC750B /* DbHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9096CC80245F21D700AC750B /* DbHelper.swift */; };
23 | 9096CC86245F39BE00AC750B /* DataUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9096CC85245F39BE00AC750B /* DataUtils.swift */; };
24 | 909CBEA42564C3C40046DA74 /* index.html in Resources */ = {isa = PBXBuildFile; fileRef = 909CBEA32564C3C40046DA74 /* index.html */; };
25 | 90C7A7492460014000F7369C /* ConfigMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9096CC82245F303800AC750B /* ConfigMap.swift */; };
26 | 90C7A76D2460125100F7369C /* DragView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90C7A76C2460125100F7369C /* DragView.swift */; };
27 | 90C7A79624605D7300F7369C /* icon.icns in Resources */ = {isa = PBXBuildFile; fileRef = 90C7A79524605D7300F7369C /* icon.icns */; };
28 | 90C7A79824605D7300F7369C /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90C7A79724605D7300F7369C /* ShareViewController.swift */; };
29 | 90C7A79B24605D7300F7369C /* ShareViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 90C7A79924605D7300F7369C /* ShareViewController.xib */; };
30 | 90C7A7A024605D7300F7369C /* ShareExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 90C7A79324605D7300F7369C /* ShareExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
31 | 90C7A7A424605D7F00F7369C /* ShareServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90997479245DDF6900931C1F /* ShareServer.swift */; };
32 | 90C7A7AA24605E2600F7369C /* PerfectHTTPServer in Frameworks */ = {isa = PBXBuildFile; productRef = 90C7A7A924605E2600F7369C /* PerfectHTTPServer */; };
33 | 90C7A7AC24605E2600F7369C /* SQLiteStORM in Frameworks */ = {isa = PBXBuildFile; productRef = 90C7A7AB24605E2600F7369C /* SQLiteStORM */; };
34 | 90C7A7AD24605E5500F7369C /* ConfigDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9096CC77245F18A400AC750B /* ConfigDTO.swift */; };
35 | 90C7A7AE24605E5500F7369C /* ShareDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9096CC79245F18B700AC750B /* ShareDTO.swift */; };
36 | 90C7A7AF24605E5500F7369C /* DbHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9096CC80245F21D700AC750B /* DbHelper.swift */; };
37 | 90C7A7B024605E5500F7369C /* ConfigMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9096CC82245F303800AC750B /* ConfigMap.swift */; };
38 | 90C7A7B124605E5500F7369C /* DataUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9096CC85245F39BE00AC750B /* DataUtils.swift */; };
39 | 90E808552463B6F70051447E /* Window.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90E808532463B6F70051447E /* Window.swift */; };
40 | 90E808562463B6F70051447E /* Window.xib in Resources */ = {isa = PBXBuildFile; fileRef = 90E808542463B6F70051447E /* Window.xib */; };
41 | /* End PBXBuildFile section */
42 |
43 | /* Begin PBXContainerItemProxy section */
44 | 90714172245DCC62008D5294 /* PBXContainerItemProxy */ = {
45 | isa = PBXContainerItemProxy;
46 | containerPortal = 90714154245DCC61008D5294 /* Project object */;
47 | proxyType = 1;
48 | remoteGlobalIDString = 9071415B245DCC61008D5294;
49 | remoteInfo = EasyShare;
50 | };
51 | 9071417D245DCC62008D5294 /* PBXContainerItemProxy */ = {
52 | isa = PBXContainerItemProxy;
53 | containerPortal = 90714154245DCC61008D5294 /* Project object */;
54 | proxyType = 1;
55 | remoteGlobalIDString = 9071415B245DCC61008D5294;
56 | remoteInfo = EasyShare;
57 | };
58 | 90C7A79E24605D7300F7369C /* PBXContainerItemProxy */ = {
59 | isa = PBXContainerItemProxy;
60 | containerPortal = 90714154245DCC61008D5294 /* Project object */;
61 | proxyType = 1;
62 | remoteGlobalIDString = 90C7A79224605D7300F7369C;
63 | remoteInfo = ShareExtension;
64 | };
65 | /* End PBXContainerItemProxy section */
66 |
67 | /* Begin PBXCopyFilesBuildPhase section */
68 | 90C7A704245FEE8300F7369C /* Embed App Extensions */ = {
69 | isa = PBXCopyFilesBuildPhase;
70 | buildActionMask = 2147483647;
71 | dstPath = "";
72 | dstSubfolderSpec = 13;
73 | files = (
74 | 90C7A7A024605D7300F7369C /* ShareExtension.appex in Embed App Extensions */,
75 | );
76 | name = "Embed App Extensions";
77 | runOnlyForDeploymentPostprocessing = 0;
78 | };
79 | 90C7A727245FF41300F7369C /* Embed Frameworks */ = {
80 | isa = PBXCopyFilesBuildPhase;
81 | buildActionMask = 2147483647;
82 | dstPath = "";
83 | dstSubfolderSpec = 10;
84 | files = (
85 | );
86 | name = "Embed Frameworks";
87 | runOnlyForDeploymentPostprocessing = 0;
88 | };
89 | /* End PBXCopyFilesBuildPhase section */
90 |
91 | /* Begin PBXFileReference section */
92 | 9071415C245DCC61008D5294 /* EasyShare.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EasyShare.app; sourceTree = BUILT_PRODUCTS_DIR; };
93 | 9071415F245DCC61008D5294 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
94 | 90714163245DCC62008D5294 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
95 | 90714166245DCC62008D5294 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
96 | 90714169245DCC62008D5294 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
97 | 9071416B245DCC62008D5294 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
98 | 9071416C245DCC62008D5294 /* EasyShare.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = EasyShare.entitlements; sourceTree = ""; };
99 | 90714171245DCC62008D5294 /* EasyShareTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = EasyShareTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
100 | 90714175245DCC62008D5294 /* EasyShareTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EasyShareTests.swift; sourceTree = ""; };
101 | 90714177245DCC62008D5294 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
102 | 9071417C245DCC62008D5294 /* EasyShareUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = EasyShareUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
103 | 90714180245DCC62008D5294 /* EasyShareUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EasyShareUITests.swift; sourceTree = ""; };
104 | 90714182245DCC62008D5294 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
105 | 908DB5322574C6A8008AF55D /* ESlogo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = ESlogo.png; sourceTree = ""; };
106 | 9096CC77245F18A400AC750B /* ConfigDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigDTO.swift; sourceTree = ""; };
107 | 9096CC79245F18B700AC750B /* ShareDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareDTO.swift; sourceTree = ""; };
108 | 9096CC80245F21D700AC750B /* DbHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DbHelper.swift; sourceTree = ""; };
109 | 9096CC82245F303800AC750B /* ConfigMap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigMap.swift; sourceTree = ""; };
110 | 9096CC85245F39BE00AC750B /* DataUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataUtils.swift; sourceTree = ""; };
111 | 90997479245DDF6900931C1F /* ShareServer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareServer.swift; sourceTree = ""; };
112 | 909CBEA32564C3C40046DA74 /* index.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = index.html; sourceTree = ""; };
113 | 90C7A76C2460125100F7369C /* DragView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DragView.swift; sourceTree = ""; };
114 | 90C7A79324605D7300F7369C /* ShareExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = ShareExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
115 | 90C7A79524605D7300F7369C /* icon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = icon.icns; sourceTree = ""; };
116 | 90C7A79724605D7300F7369C /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = ""; };
117 | 90C7A79A24605D7300F7369C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ShareViewController.xib; sourceTree = ""; };
118 | 90C7A79C24605D7300F7369C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
119 | 90C7A79D24605D7300F7369C /* ShareExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ShareExtension.entitlements; sourceTree = ""; };
120 | 90E808532463B6F70051447E /* Window.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Window.swift; sourceTree = ""; };
121 | 90E808542463B6F70051447E /* Window.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = Window.xib; sourceTree = ""; };
122 | /* End PBXFileReference section */
123 |
124 | /* Begin PBXFrameworksBuildPhase section */
125 | 90714159245DCC61008D5294 /* Frameworks */ = {
126 | isa = PBXFrameworksBuildPhase;
127 | buildActionMask = 2147483647;
128 | files = (
129 | 9096CC71245F14D700AC750B /* SQLiteStORM in Frameworks */,
130 | 906B7534245DF6AE00662E03 /* PerfectHTTPServer in Frameworks */,
131 | );
132 | runOnlyForDeploymentPostprocessing = 0;
133 | };
134 | 9071416E245DCC62008D5294 /* Frameworks */ = {
135 | isa = PBXFrameworksBuildPhase;
136 | buildActionMask = 2147483647;
137 | files = (
138 | );
139 | runOnlyForDeploymentPostprocessing = 0;
140 | };
141 | 90714179245DCC62008D5294 /* Frameworks */ = {
142 | isa = PBXFrameworksBuildPhase;
143 | buildActionMask = 2147483647;
144 | files = (
145 | );
146 | runOnlyForDeploymentPostprocessing = 0;
147 | };
148 | 90C7A79024605D7300F7369C /* Frameworks */ = {
149 | isa = PBXFrameworksBuildPhase;
150 | buildActionMask = 2147483647;
151 | files = (
152 | 90C7A7AC24605E2600F7369C /* SQLiteStORM in Frameworks */,
153 | 90C7A7AA24605E2600F7369C /* PerfectHTTPServer in Frameworks */,
154 | );
155 | runOnlyForDeploymentPostprocessing = 0;
156 | };
157 | /* End PBXFrameworksBuildPhase section */
158 |
159 | /* Begin PBXGroup section */
160 | 90714153245DCC61008D5294 = {
161 | isa = PBXGroup;
162 | children = (
163 | 9071415E245DCC61008D5294 /* EasyShare */,
164 | 90714174245DCC62008D5294 /* EasyShareTests */,
165 | 9071417F245DCC62008D5294 /* EasyShareUITests */,
166 | 90C7A79424605D7300F7369C /* ShareExtension */,
167 | 9071415D245DCC61008D5294 /* Products */,
168 | 90C7A78524601C1800F7369C /* Frameworks */,
169 | );
170 | sourceTree = "";
171 | };
172 | 9071415D245DCC61008D5294 /* Products */ = {
173 | isa = PBXGroup;
174 | children = (
175 | 9071415C245DCC61008D5294 /* EasyShare.app */,
176 | 90714171245DCC62008D5294 /* EasyShareTests.xctest */,
177 | 9071417C245DCC62008D5294 /* EasyShareUITests.xctest */,
178 | 90C7A79324605D7300F7369C /* ShareExtension.appex */,
179 | );
180 | name = Products;
181 | sourceTree = "";
182 | };
183 | 9071415E245DCC61008D5294 /* EasyShare */ = {
184 | isa = PBXGroup;
185 | children = (
186 | 9071415F245DCC61008D5294 /* AppDelegate.swift */,
187 | 90E808532463B6F70051447E /* Window.swift */,
188 | 90E808542463B6F70051447E /* Window.xib */,
189 | 90C7A76C2460125100F7369C /* DragView.swift */,
190 | 90714163245DCC62008D5294 /* Assets.xcassets */,
191 | 90714168245DCC62008D5294 /* Main.storyboard */,
192 | 9071416B245DCC62008D5294 /* Info.plist */,
193 | 9071416C245DCC62008D5294 /* EasyShare.entitlements */,
194 | 90714165245DCC62008D5294 /* Preview Content */,
195 | );
196 | path = EasyShare;
197 | sourceTree = "";
198 | };
199 | 90714165245DCC62008D5294 /* Preview Content */ = {
200 | isa = PBXGroup;
201 | children = (
202 | 90714166245DCC62008D5294 /* Preview Assets.xcassets */,
203 | );
204 | path = "Preview Content";
205 | sourceTree = "";
206 | };
207 | 90714174245DCC62008D5294 /* EasyShareTests */ = {
208 | isa = PBXGroup;
209 | children = (
210 | 90714175245DCC62008D5294 /* EasyShareTests.swift */,
211 | 90714177245DCC62008D5294 /* Info.plist */,
212 | );
213 | path = EasyShareTests;
214 | sourceTree = "";
215 | };
216 | 9071417F245DCC62008D5294 /* EasyShareUITests */ = {
217 | isa = PBXGroup;
218 | children = (
219 | 90714180245DCC62008D5294 /* EasyShareUITests.swift */,
220 | 90714182245DCC62008D5294 /* Info.plist */,
221 | );
222 | path = EasyShareUITests;
223 | sourceTree = "";
224 | };
225 | 908DB5372574C8E0008AF55D /* wwwroot */ = {
226 | isa = PBXGroup;
227 | children = (
228 | 908DB5322574C6A8008AF55D /* ESlogo.png */,
229 | 909CBEA32564C3C40046DA74 /* index.html */,
230 | );
231 | path = wwwroot;
232 | sourceTree = "";
233 | };
234 | 9096CC73245F17C100AC750B /* db */ = {
235 | isa = PBXGroup;
236 | children = (
237 | 9096CC76245F188C00AC750B /* dto */,
238 | 9096CC80245F21D700AC750B /* DbHelper.swift */,
239 | );
240 | path = db;
241 | sourceTree = "";
242 | };
243 | 9096CC76245F188C00AC750B /* dto */ = {
244 | isa = PBXGroup;
245 | children = (
246 | 9096CC77245F18A400AC750B /* ConfigDTO.swift */,
247 | 9096CC79245F18B700AC750B /* ShareDTO.swift */,
248 | );
249 | path = dto;
250 | sourceTree = "";
251 | };
252 | 909CBEA22564C35C0046DA74 /* Resource */ = {
253 | isa = PBXGroup;
254 | children = (
255 | 908DB5372574C8E0008AF55D /* wwwroot */,
256 | );
257 | path = Resource;
258 | sourceTree = "";
259 | };
260 | 90C7A7442460010000F7369C /* utils */ = {
261 | isa = PBXGroup;
262 | children = (
263 | 9096CC85245F39BE00AC750B /* DataUtils.swift */,
264 | );
265 | path = utils;
266 | sourceTree = "";
267 | };
268 | 90C7A7452460010000F7369C /* model */ = {
269 | isa = PBXGroup;
270 | children = (
271 | 9096CC73245F17C100AC750B /* db */,
272 | 9096CC82245F303800AC750B /* ConfigMap.swift */,
273 | );
274 | path = model;
275 | sourceTree = "";
276 | };
277 | 90C7A78524601C1800F7369C /* Frameworks */ = {
278 | isa = PBXGroup;
279 | children = (
280 | );
281 | name = Frameworks;
282 | sourceTree = "";
283 | };
284 | 90C7A79424605D7300F7369C /* ShareExtension */ = {
285 | isa = PBXGroup;
286 | children = (
287 | 909CBEA22564C35C0046DA74 /* Resource */,
288 | 90C7A7452460010000F7369C /* model */,
289 | 90C7A7442460010000F7369C /* utils */,
290 | 90997479245DDF6900931C1F /* ShareServer.swift */,
291 | 90C7A79524605D7300F7369C /* icon.icns */,
292 | 90C7A79724605D7300F7369C /* ShareViewController.swift */,
293 | 90C7A79924605D7300F7369C /* ShareViewController.xib */,
294 | 90C7A79C24605D7300F7369C /* Info.plist */,
295 | 90C7A79D24605D7300F7369C /* ShareExtension.entitlements */,
296 | );
297 | path = ShareExtension;
298 | sourceTree = "";
299 | };
300 | /* End PBXGroup section */
301 |
302 | /* Begin PBXNativeTarget section */
303 | 9071415B245DCC61008D5294 /* EasyShare */ = {
304 | isa = PBXNativeTarget;
305 | buildConfigurationList = 90714185245DCC62008D5294 /* Build configuration list for PBXNativeTarget "EasyShare" */;
306 | buildPhases = (
307 | 90714158245DCC61008D5294 /* Sources */,
308 | 90714159245DCC61008D5294 /* Frameworks */,
309 | 9071415A245DCC61008D5294 /* Resources */,
310 | 90C7A704245FEE8300F7369C /* Embed App Extensions */,
311 | 90C7A727245FF41300F7369C /* Embed Frameworks */,
312 | );
313 | buildRules = (
314 | );
315 | dependencies = (
316 | 90C7A79F24605D7300F7369C /* PBXTargetDependency */,
317 | );
318 | name = EasyShare;
319 | packageProductDependencies = (
320 | 906B7533245DF6AE00662E03 /* PerfectHTTPServer */,
321 | 9096CC70245F14D700AC750B /* SQLiteStORM */,
322 | );
323 | productName = EasyShare;
324 | productReference = 9071415C245DCC61008D5294 /* EasyShare.app */;
325 | productType = "com.apple.product-type.application";
326 | };
327 | 90714170245DCC62008D5294 /* EasyShareTests */ = {
328 | isa = PBXNativeTarget;
329 | buildConfigurationList = 90714188245DCC62008D5294 /* Build configuration list for PBXNativeTarget "EasyShareTests" */;
330 | buildPhases = (
331 | 9071416D245DCC62008D5294 /* Sources */,
332 | 9071416E245DCC62008D5294 /* Frameworks */,
333 | 9071416F245DCC62008D5294 /* Resources */,
334 | );
335 | buildRules = (
336 | );
337 | dependencies = (
338 | 90714173245DCC62008D5294 /* PBXTargetDependency */,
339 | );
340 | name = EasyShareTests;
341 | productName = EasyShareTests;
342 | productReference = 90714171245DCC62008D5294 /* EasyShareTests.xctest */;
343 | productType = "com.apple.product-type.bundle.unit-test";
344 | };
345 | 9071417B245DCC62008D5294 /* EasyShareUITests */ = {
346 | isa = PBXNativeTarget;
347 | buildConfigurationList = 9071418B245DCC62008D5294 /* Build configuration list for PBXNativeTarget "EasyShareUITests" */;
348 | buildPhases = (
349 | 90714178245DCC62008D5294 /* Sources */,
350 | 90714179245DCC62008D5294 /* Frameworks */,
351 | 9071417A245DCC62008D5294 /* Resources */,
352 | );
353 | buildRules = (
354 | );
355 | dependencies = (
356 | 9071417E245DCC62008D5294 /* PBXTargetDependency */,
357 | );
358 | name = EasyShareUITests;
359 | productName = EasyShareUITests;
360 | productReference = 9071417C245DCC62008D5294 /* EasyShareUITests.xctest */;
361 | productType = "com.apple.product-type.bundle.ui-testing";
362 | };
363 | 90C7A79224605D7300F7369C /* ShareExtension */ = {
364 | isa = PBXNativeTarget;
365 | buildConfigurationList = 90C7A7A124605D7300F7369C /* Build configuration list for PBXNativeTarget "ShareExtension" */;
366 | buildPhases = (
367 | 90C7A78F24605D7300F7369C /* Sources */,
368 | 90C7A79024605D7300F7369C /* Frameworks */,
369 | 90C7A79124605D7300F7369C /* Resources */,
370 | );
371 | buildRules = (
372 | );
373 | dependencies = (
374 | 90C7A7A624605E1C00F7369C /* PBXTargetDependency */,
375 | 90C7A7A824605E1C00F7369C /* PBXTargetDependency */,
376 | );
377 | name = ShareExtension;
378 | packageProductDependencies = (
379 | 90C7A7A924605E2600F7369C /* PerfectHTTPServer */,
380 | 90C7A7AB24605E2600F7369C /* SQLiteStORM */,
381 | );
382 | productName = ShareExtension;
383 | productReference = 90C7A79324605D7300F7369C /* ShareExtension.appex */;
384 | productType = "com.apple.product-type.app-extension";
385 | };
386 | /* End PBXNativeTarget section */
387 |
388 | /* Begin PBXProject section */
389 | 90714154245DCC61008D5294 /* Project object */ = {
390 | isa = PBXProject;
391 | attributes = {
392 | LastSwiftUpdateCheck = 1140;
393 | LastUpgradeCheck = 1140;
394 | ORGANIZATIONNAME = "Michael Lee";
395 | TargetAttributes = {
396 | 9071415B245DCC61008D5294 = {
397 | CreatedOnToolsVersion = 11.4;
398 | };
399 | 90714170245DCC62008D5294 = {
400 | CreatedOnToolsVersion = 11.4;
401 | TestTargetID = 9071415B245DCC61008D5294;
402 | };
403 | 9071417B245DCC62008D5294 = {
404 | CreatedOnToolsVersion = 11.4;
405 | TestTargetID = 9071415B245DCC61008D5294;
406 | };
407 | 90C7A79224605D7300F7369C = {
408 | CreatedOnToolsVersion = 11.4.1;
409 | };
410 | };
411 | };
412 | buildConfigurationList = 90714157245DCC61008D5294 /* Build configuration list for PBXProject "EasyShare" */;
413 | compatibilityVersion = "Xcode 9.3";
414 | developmentRegion = en;
415 | hasScannedForEncodings = 0;
416 | knownRegions = (
417 | en,
418 | Base,
419 | );
420 | mainGroup = 90714153245DCC61008D5294;
421 | packageReferences = (
422 | 906B7532245DF6AE00662E03 /* XCRemoteSwiftPackageReference "Perfect-HTTPServer" */,
423 | 9096CC6F245F14D700AC750B /* XCRemoteSwiftPackageReference "SQLite-StORM" */,
424 | );
425 | productRefGroup = 9071415D245DCC61008D5294 /* Products */;
426 | projectDirPath = "";
427 | projectRoot = "";
428 | targets = (
429 | 9071415B245DCC61008D5294 /* EasyShare */,
430 | 90714170245DCC62008D5294 /* EasyShareTests */,
431 | 9071417B245DCC62008D5294 /* EasyShareUITests */,
432 | 90C7A79224605D7300F7369C /* ShareExtension */,
433 | );
434 | };
435 | /* End PBXProject section */
436 |
437 | /* Begin PBXResourcesBuildPhase section */
438 | 9071415A245DCC61008D5294 /* Resources */ = {
439 | isa = PBXResourcesBuildPhase;
440 | buildActionMask = 2147483647;
441 | files = (
442 | 9071416A245DCC62008D5294 /* Main.storyboard in Resources */,
443 | 90714167245DCC62008D5294 /* Preview Assets.xcassets in Resources */,
444 | 90714164245DCC62008D5294 /* Assets.xcassets in Resources */,
445 | 90E808562463B6F70051447E /* Window.xib in Resources */,
446 | );
447 | runOnlyForDeploymentPostprocessing = 0;
448 | };
449 | 9071416F245DCC62008D5294 /* Resources */ = {
450 | isa = PBXResourcesBuildPhase;
451 | buildActionMask = 2147483647;
452 | files = (
453 | );
454 | runOnlyForDeploymentPostprocessing = 0;
455 | };
456 | 9071417A245DCC62008D5294 /* Resources */ = {
457 | isa = PBXResourcesBuildPhase;
458 | buildActionMask = 2147483647;
459 | files = (
460 | );
461 | runOnlyForDeploymentPostprocessing = 0;
462 | };
463 | 90C7A79124605D7300F7369C /* Resources */ = {
464 | isa = PBXResourcesBuildPhase;
465 | buildActionMask = 2147483647;
466 | files = (
467 | 909CBEA42564C3C40046DA74 /* index.html in Resources */,
468 | 90C7A79B24605D7300F7369C /* ShareViewController.xib in Resources */,
469 | 908DB5332574C6A8008AF55D /* ESlogo.png in Resources */,
470 | 90C7A79624605D7300F7369C /* icon.icns in Resources */,
471 | );
472 | runOnlyForDeploymentPostprocessing = 0;
473 | };
474 | /* End PBXResourcesBuildPhase section */
475 |
476 | /* Begin PBXSourcesBuildPhase section */
477 | 90714158245DCC61008D5294 /* Sources */ = {
478 | isa = PBXSourcesBuildPhase;
479 | buildActionMask = 2147483647;
480 | files = (
481 | 907B97EC24605F7A00F38E15 /* ShareServer.swift in Sources */,
482 | 90E808552463B6F70051447E /* Window.swift in Sources */,
483 | 9096CC7A245F18B700AC750B /* ShareDTO.swift in Sources */,
484 | 90714160245DCC61008D5294 /* AppDelegate.swift in Sources */,
485 | 9096CC86245F39BE00AC750B /* DataUtils.swift in Sources */,
486 | 9096CC78245F18A400AC750B /* ConfigDTO.swift in Sources */,
487 | 90C7A7492460014000F7369C /* ConfigMap.swift in Sources */,
488 | 9096CC81245F21D700AC750B /* DbHelper.swift in Sources */,
489 | 90C7A76D2460125100F7369C /* DragView.swift in Sources */,
490 | );
491 | runOnlyForDeploymentPostprocessing = 0;
492 | };
493 | 9071416D245DCC62008D5294 /* Sources */ = {
494 | isa = PBXSourcesBuildPhase;
495 | buildActionMask = 2147483647;
496 | files = (
497 | 90714176245DCC62008D5294 /* EasyShareTests.swift in Sources */,
498 | );
499 | runOnlyForDeploymentPostprocessing = 0;
500 | };
501 | 90714178245DCC62008D5294 /* Sources */ = {
502 | isa = PBXSourcesBuildPhase;
503 | buildActionMask = 2147483647;
504 | files = (
505 | 90714181245DCC62008D5294 /* EasyShareUITests.swift in Sources */,
506 | );
507 | runOnlyForDeploymentPostprocessing = 0;
508 | };
509 | 90C7A78F24605D7300F7369C /* Sources */ = {
510 | isa = PBXSourcesBuildPhase;
511 | buildActionMask = 2147483647;
512 | files = (
513 | 90C7A7AD24605E5500F7369C /* ConfigDTO.swift in Sources */,
514 | 90C7A7AE24605E5500F7369C /* ShareDTO.swift in Sources */,
515 | 90C7A7AF24605E5500F7369C /* DbHelper.swift in Sources */,
516 | 90C7A7B024605E5500F7369C /* ConfigMap.swift in Sources */,
517 | 90C7A7B124605E5500F7369C /* DataUtils.swift in Sources */,
518 | 90C7A7A424605D7F00F7369C /* ShareServer.swift in Sources */,
519 | 90C7A79824605D7300F7369C /* ShareViewController.swift in Sources */,
520 | );
521 | runOnlyForDeploymentPostprocessing = 0;
522 | };
523 | /* End PBXSourcesBuildPhase section */
524 |
525 | /* Begin PBXTargetDependency section */
526 | 90714173245DCC62008D5294 /* PBXTargetDependency */ = {
527 | isa = PBXTargetDependency;
528 | target = 9071415B245DCC61008D5294 /* EasyShare */;
529 | targetProxy = 90714172245DCC62008D5294 /* PBXContainerItemProxy */;
530 | };
531 | 9071417E245DCC62008D5294 /* PBXTargetDependency */ = {
532 | isa = PBXTargetDependency;
533 | target = 9071415B245DCC61008D5294 /* EasyShare */;
534 | targetProxy = 9071417D245DCC62008D5294 /* PBXContainerItemProxy */;
535 | };
536 | 90C7A79F24605D7300F7369C /* PBXTargetDependency */ = {
537 | isa = PBXTargetDependency;
538 | target = 90C7A79224605D7300F7369C /* ShareExtension */;
539 | targetProxy = 90C7A79E24605D7300F7369C /* PBXContainerItemProxy */;
540 | };
541 | 90C7A7A624605E1C00F7369C /* PBXTargetDependency */ = {
542 | isa = PBXTargetDependency;
543 | productRef = 90C7A7A524605E1C00F7369C /* PerfectHTTPServer */;
544 | };
545 | 90C7A7A824605E1C00F7369C /* PBXTargetDependency */ = {
546 | isa = PBXTargetDependency;
547 | productRef = 90C7A7A724605E1C00F7369C /* SQLiteStORM */;
548 | };
549 | /* End PBXTargetDependency section */
550 |
551 | /* Begin PBXVariantGroup section */
552 | 90714168245DCC62008D5294 /* Main.storyboard */ = {
553 | isa = PBXVariantGroup;
554 | children = (
555 | 90714169245DCC62008D5294 /* Base */,
556 | );
557 | name = Main.storyboard;
558 | sourceTree = "";
559 | };
560 | 90C7A79924605D7300F7369C /* ShareViewController.xib */ = {
561 | isa = PBXVariantGroup;
562 | children = (
563 | 90C7A79A24605D7300F7369C /* Base */,
564 | );
565 | name = ShareViewController.xib;
566 | sourceTree = "";
567 | };
568 | /* End PBXVariantGroup section */
569 |
570 | /* Begin XCBuildConfiguration section */
571 | 90714183245DCC62008D5294 /* Debug */ = {
572 | isa = XCBuildConfiguration;
573 | buildSettings = {
574 | ALWAYS_SEARCH_USER_PATHS = NO;
575 | CLANG_ANALYZER_NONNULL = YES;
576 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
577 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
578 | CLANG_CXX_LIBRARY = "libc++";
579 | CLANG_ENABLE_MODULES = YES;
580 | CLANG_ENABLE_OBJC_ARC = YES;
581 | CLANG_ENABLE_OBJC_WEAK = YES;
582 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
583 | CLANG_WARN_BOOL_CONVERSION = YES;
584 | CLANG_WARN_COMMA = YES;
585 | CLANG_WARN_CONSTANT_CONVERSION = YES;
586 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
587 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
588 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
589 | CLANG_WARN_EMPTY_BODY = YES;
590 | CLANG_WARN_ENUM_CONVERSION = YES;
591 | CLANG_WARN_INFINITE_RECURSION = YES;
592 | CLANG_WARN_INT_CONVERSION = YES;
593 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
594 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
595 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
596 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
597 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
598 | CLANG_WARN_STRICT_PROTOTYPES = YES;
599 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
600 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
601 | CLANG_WARN_UNREACHABLE_CODE = YES;
602 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
603 | COPY_PHASE_STRIP = NO;
604 | DEBUG_INFORMATION_FORMAT = dwarf;
605 | ENABLE_STRICT_OBJC_MSGSEND = YES;
606 | ENABLE_TESTABILITY = YES;
607 | GCC_C_LANGUAGE_STANDARD = gnu11;
608 | GCC_DYNAMIC_NO_PIC = NO;
609 | GCC_NO_COMMON_BLOCKS = YES;
610 | GCC_OPTIMIZATION_LEVEL = 0;
611 | GCC_PREPROCESSOR_DEFINITIONS = (
612 | "DEBUG=1",
613 | "$(inherited)",
614 | );
615 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
616 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
617 | GCC_WARN_UNDECLARED_SELECTOR = YES;
618 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
619 | GCC_WARN_UNUSED_FUNCTION = YES;
620 | GCC_WARN_UNUSED_VARIABLE = YES;
621 | MACOSX_DEPLOYMENT_TARGET = 10.13;
622 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
623 | MTL_FAST_MATH = YES;
624 | ONLY_ACTIVE_ARCH = YES;
625 | SDKROOT = macosx;
626 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
627 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
628 | };
629 | name = Debug;
630 | };
631 | 90714184245DCC62008D5294 /* Release */ = {
632 | isa = XCBuildConfiguration;
633 | buildSettings = {
634 | ALWAYS_SEARCH_USER_PATHS = NO;
635 | CLANG_ANALYZER_NONNULL = YES;
636 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
637 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
638 | CLANG_CXX_LIBRARY = "libc++";
639 | CLANG_ENABLE_MODULES = YES;
640 | CLANG_ENABLE_OBJC_ARC = YES;
641 | CLANG_ENABLE_OBJC_WEAK = YES;
642 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
643 | CLANG_WARN_BOOL_CONVERSION = YES;
644 | CLANG_WARN_COMMA = YES;
645 | CLANG_WARN_CONSTANT_CONVERSION = YES;
646 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
647 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
648 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
649 | CLANG_WARN_EMPTY_BODY = YES;
650 | CLANG_WARN_ENUM_CONVERSION = YES;
651 | CLANG_WARN_INFINITE_RECURSION = YES;
652 | CLANG_WARN_INT_CONVERSION = YES;
653 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
654 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
655 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
656 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
657 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
658 | CLANG_WARN_STRICT_PROTOTYPES = YES;
659 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
660 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
661 | CLANG_WARN_UNREACHABLE_CODE = YES;
662 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
663 | COPY_PHASE_STRIP = NO;
664 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
665 | ENABLE_NS_ASSERTIONS = NO;
666 | ENABLE_STRICT_OBJC_MSGSEND = YES;
667 | GCC_C_LANGUAGE_STANDARD = gnu11;
668 | GCC_NO_COMMON_BLOCKS = YES;
669 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
670 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
671 | GCC_WARN_UNDECLARED_SELECTOR = YES;
672 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
673 | GCC_WARN_UNUSED_FUNCTION = YES;
674 | GCC_WARN_UNUSED_VARIABLE = YES;
675 | MACOSX_DEPLOYMENT_TARGET = 10.13;
676 | MTL_ENABLE_DEBUG_INFO = NO;
677 | MTL_FAST_MATH = YES;
678 | SDKROOT = macosx;
679 | SWIFT_COMPILATION_MODE = wholemodule;
680 | SWIFT_OPTIMIZATION_LEVEL = "-O";
681 | };
682 | name = Release;
683 | };
684 | 90714186245DCC62008D5294 /* Debug */ = {
685 | isa = XCBuildConfiguration;
686 | buildSettings = {
687 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
688 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
689 | CODE_SIGN_ENTITLEMENTS = EasyShare/EasyShare.entitlements;
690 | CODE_SIGN_IDENTITY = "-";
691 | CODE_SIGN_STYLE = Automatic;
692 | COMBINE_HIDPI_IMAGES = YES;
693 | CURRENT_PROJECT_VERSION = 10;
694 | DEVELOPMENT_ASSET_PATHS = "\"EasyShare/Preview Content\"";
695 | DEVELOPMENT_TEAM = 5PYBGZXB6L;
696 | ENABLE_HARDENED_RUNTIME = YES;
697 | ENABLE_PREVIEWS = YES;
698 | INFOPLIST_FILE = EasyShare/Info.plist;
699 | LD_RUNPATH_SEARCH_PATHS = (
700 | "$(inherited)",
701 | "@executable_path/../Frameworks",
702 | );
703 | MACOSX_DEPLOYMENT_TARGET = 10.13;
704 | MARKETING_VERSION = 1.4;
705 | PRODUCT_BUNDLE_IDENTIFIER = dog.abcd.EasyShare;
706 | PRODUCT_NAME = "$(TARGET_NAME)";
707 | PROVISIONING_PROFILE_SPECIFIER = "";
708 | SWIFT_VERSION = 5.0;
709 | };
710 | name = Debug;
711 | };
712 | 90714187245DCC62008D5294 /* Release */ = {
713 | isa = XCBuildConfiguration;
714 | buildSettings = {
715 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
716 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
717 | CODE_SIGN_ENTITLEMENTS = EasyShare/EasyShare.entitlements;
718 | CODE_SIGN_IDENTITY = "-";
719 | CODE_SIGN_STYLE = Automatic;
720 | COMBINE_HIDPI_IMAGES = YES;
721 | CURRENT_PROJECT_VERSION = 10;
722 | DEVELOPMENT_ASSET_PATHS = "\"EasyShare/Preview Content\"";
723 | DEVELOPMENT_TEAM = 5PYBGZXB6L;
724 | ENABLE_HARDENED_RUNTIME = YES;
725 | ENABLE_PREVIEWS = YES;
726 | INFOPLIST_FILE = EasyShare/Info.plist;
727 | LD_RUNPATH_SEARCH_PATHS = (
728 | "$(inherited)",
729 | "@executable_path/../Frameworks",
730 | );
731 | MACOSX_DEPLOYMENT_TARGET = 10.13;
732 | MARKETING_VERSION = 1.4;
733 | PRODUCT_BUNDLE_IDENTIFIER = dog.abcd.EasyShare;
734 | PRODUCT_NAME = "$(TARGET_NAME)";
735 | PROVISIONING_PROFILE_SPECIFIER = "";
736 | SWIFT_VERSION = 5.0;
737 | };
738 | name = Release;
739 | };
740 | 90714189245DCC62008D5294 /* Debug */ = {
741 | isa = XCBuildConfiguration;
742 | buildSettings = {
743 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
744 | BUNDLE_LOADER = "$(TEST_HOST)";
745 | CODE_SIGN_STYLE = Automatic;
746 | COMBINE_HIDPI_IMAGES = YES;
747 | DEVELOPMENT_TEAM = 5PYBGZXB6L;
748 | INFOPLIST_FILE = EasyShareTests/Info.plist;
749 | LD_RUNPATH_SEARCH_PATHS = (
750 | "$(inherited)",
751 | "@executable_path/../Frameworks",
752 | "@loader_path/../Frameworks",
753 | );
754 | MACOSX_DEPLOYMENT_TARGET = 10.15;
755 | PRODUCT_BUNDLE_IDENTIFIER = dog.abcd.EasyShareTests;
756 | PRODUCT_NAME = "$(TARGET_NAME)";
757 | SWIFT_VERSION = 5.0;
758 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/EasyShare.app/Contents/MacOS/EasyShare";
759 | };
760 | name = Debug;
761 | };
762 | 9071418A245DCC62008D5294 /* Release */ = {
763 | isa = XCBuildConfiguration;
764 | buildSettings = {
765 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
766 | BUNDLE_LOADER = "$(TEST_HOST)";
767 | CODE_SIGN_STYLE = Automatic;
768 | COMBINE_HIDPI_IMAGES = YES;
769 | DEVELOPMENT_TEAM = 5PYBGZXB6L;
770 | INFOPLIST_FILE = EasyShareTests/Info.plist;
771 | LD_RUNPATH_SEARCH_PATHS = (
772 | "$(inherited)",
773 | "@executable_path/../Frameworks",
774 | "@loader_path/../Frameworks",
775 | );
776 | MACOSX_DEPLOYMENT_TARGET = 10.15;
777 | PRODUCT_BUNDLE_IDENTIFIER = dog.abcd.EasyShareTests;
778 | PRODUCT_NAME = "$(TARGET_NAME)";
779 | SWIFT_VERSION = 5.0;
780 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/EasyShare.app/Contents/MacOS/EasyShare";
781 | };
782 | name = Release;
783 | };
784 | 9071418C245DCC62008D5294 /* Debug */ = {
785 | isa = XCBuildConfiguration;
786 | buildSettings = {
787 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
788 | CODE_SIGN_STYLE = Automatic;
789 | COMBINE_HIDPI_IMAGES = YES;
790 | DEVELOPMENT_TEAM = 5PYBGZXB6L;
791 | INFOPLIST_FILE = EasyShareUITests/Info.plist;
792 | LD_RUNPATH_SEARCH_PATHS = (
793 | "$(inherited)",
794 | "@executable_path/../Frameworks",
795 | "@loader_path/../Frameworks",
796 | );
797 | PRODUCT_BUNDLE_IDENTIFIER = dog.abcd.EasyShareUITests;
798 | PRODUCT_NAME = "$(TARGET_NAME)";
799 | SWIFT_VERSION = 5.0;
800 | TEST_TARGET_NAME = EasyShare;
801 | };
802 | name = Debug;
803 | };
804 | 9071418D245DCC62008D5294 /* Release */ = {
805 | isa = XCBuildConfiguration;
806 | buildSettings = {
807 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
808 | CODE_SIGN_STYLE = Automatic;
809 | COMBINE_HIDPI_IMAGES = YES;
810 | DEVELOPMENT_TEAM = 5PYBGZXB6L;
811 | INFOPLIST_FILE = EasyShareUITests/Info.plist;
812 | LD_RUNPATH_SEARCH_PATHS = (
813 | "$(inherited)",
814 | "@executable_path/../Frameworks",
815 | "@loader_path/../Frameworks",
816 | );
817 | PRODUCT_BUNDLE_IDENTIFIER = dog.abcd.EasyShareUITests;
818 | PRODUCT_NAME = "$(TARGET_NAME)";
819 | SWIFT_VERSION = 5.0;
820 | TEST_TARGET_NAME = EasyShare;
821 | };
822 | name = Release;
823 | };
824 | 90C7A7A224605D7300F7369C /* Debug */ = {
825 | isa = XCBuildConfiguration;
826 | buildSettings = {
827 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
828 | CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
829 | CODE_SIGN_IDENTITY = "-";
830 | CODE_SIGN_STYLE = Automatic;
831 | COMBINE_HIDPI_IMAGES = YES;
832 | CURRENT_PROJECT_VERSION = 10;
833 | DEVELOPMENT_TEAM = 5PYBGZXB6L;
834 | ENABLE_HARDENED_RUNTIME = YES;
835 | INFOPLIST_FILE = ShareExtension/Info.plist;
836 | LD_RUNPATH_SEARCH_PATHS = (
837 | "$(inherited)",
838 | "@executable_path/../Frameworks",
839 | "@executable_path/../../../../Frameworks",
840 | );
841 | MACOSX_DEPLOYMENT_TARGET = 10.13;
842 | MARKETING_VERSION = 1.4;
843 | PRODUCT_BUNDLE_IDENTIFIER = dog.abcd.EasyShare.ShareExtension;
844 | PRODUCT_NAME = "$(TARGET_NAME)";
845 | SKIP_INSTALL = YES;
846 | SWIFT_VERSION = 5.0;
847 | };
848 | name = Debug;
849 | };
850 | 90C7A7A324605D7300F7369C /* Release */ = {
851 | isa = XCBuildConfiguration;
852 | buildSettings = {
853 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
854 | CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtensionRelease.entitlements;
855 | CODE_SIGN_IDENTITY = "-";
856 | CODE_SIGN_STYLE = Automatic;
857 | COMBINE_HIDPI_IMAGES = YES;
858 | CURRENT_PROJECT_VERSION = 10;
859 | DEVELOPMENT_TEAM = 5PYBGZXB6L;
860 | ENABLE_HARDENED_RUNTIME = YES;
861 | INFOPLIST_FILE = ShareExtension/Info.plist;
862 | LD_RUNPATH_SEARCH_PATHS = (
863 | "$(inherited)",
864 | "@executable_path/../Frameworks",
865 | "@executable_path/../../../../Frameworks",
866 | );
867 | MACOSX_DEPLOYMENT_TARGET = 10.13;
868 | MARKETING_VERSION = 1.4;
869 | PRODUCT_BUNDLE_IDENTIFIER = dog.abcd.EasyShare.ShareExtension;
870 | PRODUCT_NAME = "$(TARGET_NAME)";
871 | SKIP_INSTALL = YES;
872 | SWIFT_VERSION = 5.0;
873 | };
874 | name = Release;
875 | };
876 | /* End XCBuildConfiguration section */
877 |
878 | /* Begin XCConfigurationList section */
879 | 90714157245DCC61008D5294 /* Build configuration list for PBXProject "EasyShare" */ = {
880 | isa = XCConfigurationList;
881 | buildConfigurations = (
882 | 90714183245DCC62008D5294 /* Debug */,
883 | 90714184245DCC62008D5294 /* Release */,
884 | );
885 | defaultConfigurationIsVisible = 0;
886 | defaultConfigurationName = Release;
887 | };
888 | 90714185245DCC62008D5294 /* Build configuration list for PBXNativeTarget "EasyShare" */ = {
889 | isa = XCConfigurationList;
890 | buildConfigurations = (
891 | 90714186245DCC62008D5294 /* Debug */,
892 | 90714187245DCC62008D5294 /* Release */,
893 | );
894 | defaultConfigurationIsVisible = 0;
895 | defaultConfigurationName = Release;
896 | };
897 | 90714188245DCC62008D5294 /* Build configuration list for PBXNativeTarget "EasyShareTests" */ = {
898 | isa = XCConfigurationList;
899 | buildConfigurations = (
900 | 90714189245DCC62008D5294 /* Debug */,
901 | 9071418A245DCC62008D5294 /* Release */,
902 | );
903 | defaultConfigurationIsVisible = 0;
904 | defaultConfigurationName = Release;
905 | };
906 | 9071418B245DCC62008D5294 /* Build configuration list for PBXNativeTarget "EasyShareUITests" */ = {
907 | isa = XCConfigurationList;
908 | buildConfigurations = (
909 | 9071418C245DCC62008D5294 /* Debug */,
910 | 9071418D245DCC62008D5294 /* Release */,
911 | );
912 | defaultConfigurationIsVisible = 0;
913 | defaultConfigurationName = Release;
914 | };
915 | 90C7A7A124605D7300F7369C /* Build configuration list for PBXNativeTarget "ShareExtension" */ = {
916 | isa = XCConfigurationList;
917 | buildConfigurations = (
918 | 90C7A7A224605D7300F7369C /* Debug */,
919 | 90C7A7A324605D7300F7369C /* Release */,
920 | );
921 | defaultConfigurationIsVisible = 0;
922 | defaultConfigurationName = Release;
923 | };
924 | /* End XCConfigurationList section */
925 |
926 | /* Begin XCRemoteSwiftPackageReference section */
927 | 906B7532245DF6AE00662E03 /* XCRemoteSwiftPackageReference "Perfect-HTTPServer" */ = {
928 | isa = XCRemoteSwiftPackageReference;
929 | repositoryURL = "https://github.com/PerfectlySoft/Perfect-HTTPServer.git";
930 | requirement = {
931 | kind = upToNextMajorVersion;
932 | minimumVersion = 3.0.23;
933 | };
934 | };
935 | 9096CC6F245F14D700AC750B /* XCRemoteSwiftPackageReference "SQLite-StORM" */ = {
936 | isa = XCRemoteSwiftPackageReference;
937 | repositoryURL = "https://github.com/SwiftORM/SQLite-StORM.git";
938 | requirement = {
939 | kind = upToNextMajorVersion;
940 | minimumVersion = 3.1.0;
941 | };
942 | };
943 | /* End XCRemoteSwiftPackageReference section */
944 |
945 | /* Begin XCSwiftPackageProductDependency section */
946 | 906B7533245DF6AE00662E03 /* PerfectHTTPServer */ = {
947 | isa = XCSwiftPackageProductDependency;
948 | package = 906B7532245DF6AE00662E03 /* XCRemoteSwiftPackageReference "Perfect-HTTPServer" */;
949 | productName = PerfectHTTPServer;
950 | };
951 | 9096CC70245F14D700AC750B /* SQLiteStORM */ = {
952 | isa = XCSwiftPackageProductDependency;
953 | package = 9096CC6F245F14D700AC750B /* XCRemoteSwiftPackageReference "SQLite-StORM" */;
954 | productName = SQLiteStORM;
955 | };
956 | 90C7A7A524605E1C00F7369C /* PerfectHTTPServer */ = {
957 | isa = XCSwiftPackageProductDependency;
958 | package = 906B7532245DF6AE00662E03 /* XCRemoteSwiftPackageReference "Perfect-HTTPServer" */;
959 | productName = PerfectHTTPServer;
960 | };
961 | 90C7A7A724605E1C00F7369C /* SQLiteStORM */ = {
962 | isa = XCSwiftPackageProductDependency;
963 | package = 9096CC6F245F14D700AC750B /* XCRemoteSwiftPackageReference "SQLite-StORM" */;
964 | productName = SQLiteStORM;
965 | };
966 | 90C7A7A924605E2600F7369C /* PerfectHTTPServer */ = {
967 | isa = XCSwiftPackageProductDependency;
968 | package = 906B7532245DF6AE00662E03 /* XCRemoteSwiftPackageReference "Perfect-HTTPServer" */;
969 | productName = PerfectHTTPServer;
970 | };
971 | 90C7A7AB24605E2600F7369C /* SQLiteStORM */ = {
972 | isa = XCSwiftPackageProductDependency;
973 | package = 9096CC6F245F14D700AC750B /* XCRemoteSwiftPackageReference "SQLite-StORM" */;
974 | productName = SQLiteStORM;
975 | };
976 | /* End XCSwiftPackageProductDependency section */
977 | };
978 | rootObject = 90714154245DCC61008D5294 /* Project object */;
979 | }
980 |
--------------------------------------------------------------------------------