Merge pull request #8 from Hext123/main

封装网络请求层, 对接接口API
This commit is contained in:
Easy 2022-01-05 11:16:47 +08:00 committed by GitHub
commit 835a27e0d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 1232 additions and 114 deletions

View File

@ -78,7 +78,7 @@ playground.xcworkspace
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
# Pods/
Pods/
#
# Add this line if you want to avoid checking in source code from the Xcode workspace
# *.xcworkspace

22
ios/PushDeer-iOS/Podfile Normal file
View File

@ -0,0 +1,22 @@
# Uncomment the next line to define a global platform for your project
platform :ios, '14.0'
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
def commonPods
# Pods for common
pod 'Moya', '~> 15.0'
end
target 'PushDeer' do
commonPods
# Pods for PushDeer
end
target 'PushDeerClip' do
commonPods
# Pods for PushDeerClip
end

View File

@ -0,0 +1,22 @@
PODS:
- Alamofire (5.5.0)
- Moya (15.0.0):
- Moya/Core (= 15.0.0)
- Moya/Core (15.0.0):
- Alamofire (~> 5.0)
DEPENDENCIES:
- Moya (~> 15.0)
SPEC REPOS:
trunk:
- Alamofire
- Moya
SPEC CHECKSUMS:
Alamofire: 1c4fb5369c3fe93d2857c780d8bbe09f06f97e7c
Moya: 138f0573e53411fb3dc17016add0b748dfbd78ee
PODFILE CHECKSUM: 71abdebce610eefe1a0299d0a0bd00a463b0a79c
COCOAPODS: 1.11.2

View File

@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
4812F19BB0BFEFE089BC253E /* Pods_PushDeerClip.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E03C2088F4CD9F4C0848E1A5 /* Pods_PushDeerClip.framework */; };
52163EB327773F8400594190 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52163EB227773F8400594190 /* MainView.swift */; };
52163EB52777413B00594190 /* MessageListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52163EB42777413B00594190 /* MessageListView.swift */; };
52163EB72777415F00594190 /* DeviceListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52163EB62777415F00594190 /* DeviceListView.swift */; };
@ -14,18 +15,76 @@
52163EBB277741AC00594190 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52163EBA277741AC00594190 /* SettingsView.swift */; };
523150D9277875FB00941EDC /* DeletableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 523150D8277875FB00941EDC /* DeletableView.swift */; };
523150DC2778762B00941EDC /* DeviceItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 523150DB2778762B00941EDC /* DeviceItemView.swift */; };
52450F3827848243003652D8 /* PushDeerApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52450F3727848243003652D8 /* PushDeerApi.swift */; };
52450F3927848243003652D8 /* PushDeerApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52450F3727848243003652D8 /* PushDeerApi.swift */; };
52450F3B278491F8003652D8 /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52450F3A278491F8003652D8 /* AppState.swift */; };
52450F3C278491F8003652D8 /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52450F3A278491F8003652D8 /* AppState.swift */; };
52450F3F2784923D003652D8 /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52450F3E2784923D003652D8 /* Result.swift */; };
52450F402784923D003652D8 /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52450F3E2784923D003652D8 /* Result.swift */; };
52450F422784943F003652D8 /* HttpRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52450F412784943F003652D8 /* HttpRequest.swift */; };
52450F432784943F003652D8 /* HttpRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52450F412784943F003652D8 /* HttpRequest.swift */; };
52483FC2277ED6D5003A100E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52483FC1277ED6D5003A100E /* AppDelegate.swift */; };
52483FC3277ED6D5003A100E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52483FC1277ED6D5003A100E /* AppDelegate.swift */; };
5292F4F92776BC7900B9A7BB /* PushDeerApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5292F4F82776BC7900B9A7BB /* PushDeerApp.swift */; };
5292F4FB2776BC7900B9A7BB /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5292F4FA2776BC7900B9A7BB /* ContentView.swift */; };
5292F4FD2776BC7A00B9A7BB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5292F4FC2776BC7A00B9A7BB /* Assets.xcassets */; };
5292F5002776BC7A00B9A7BB /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5292F4FF2776BC7A00B9A7BB /* Preview Assets.xcassets */; };
52B8CF5F277DE660004CB680 /* AppleSignInButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B8CF5E277DE660004CB680 /* AppleSignInButton.swift */; };
52B8CF67277E0B44004CB680 /* PushDeerClipApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B8CF66277E0B44004CB680 /* PushDeerClipApp.swift */; };
52B8CF69277E0B44004CB680 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B8CF68277E0B44004CB680 /* ContentView.swift */; };
52B8CF6B277E0B46004CB680 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 52B8CF6A277E0B46004CB680 /* Assets.xcassets */; };
52B8CF6E277E0B46004CB680 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 52B8CF6D277E0B46004CB680 /* Preview Assets.xcassets */; };
52B8CF73277E0B46004CB680 /* PushDeerClip.app in Embed App Clips */ = {isa = PBXBuildFile; fileRef = 52B8CF64277E0B44004CB680 /* PushDeerClip.app */; platformFilter = ios; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
52B8CF78277E0BF1004CB680 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52163EB227773F8400594190 /* MainView.swift */; };
52B8CF79277E0BFB004CB680 /* DeviceListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52163EB62777415F00594190 /* DeviceListView.swift */; };
52B8CF7A277E0BFB004CB680 /* MessageListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52163EB42777413B00594190 /* MessageListView.swift */; };
52B8CF7B277E0BFB004CB680 /* DeviceItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 523150DB2778762B00941EDC /* DeviceItemView.swift */; };
52B8CF7C277E0BFB004CB680 /* KeyListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52163EB82777417900594190 /* KeyListView.swift */; };
52B8CF7D277E0BFB004CB680 /* KeyItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52EB90AF2778D67F0048E0ED /* KeyItemView.swift */; };
52B8CF7E277E0BFB004CB680 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52163EBA277741AC00594190 /* SettingsView.swift */; };
52B8CF7F277E0BFB004CB680 /* SettingsItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52F2C222277961D7006F08DC /* SettingsItemView.swift */; };
52B8CF80277E0BFB004CB680 /* MessageItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52F40D2E277CA05600766C24 /* MessageItemView.swift */; };
52B8CF81277E0BFB004CB680 /* LoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52F0243E277737470071D861 /* LoginView.swift */; };
52B8CF82277E0C06004CB680 /* AppleSignInButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B8CF5E277DE660004CB680 /* AppleSignInButton.swift */; };
52B8CF83277E0C12004CB680 /* DeletableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 523150D8277875FB00941EDC /* DeletableView.swift */; };
52B8CF84277E0C12004CB680 /* CardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52EB90AB2778ADF80048E0ED /* CardView.swift */; };
52B8CF85277E0C12004CB680 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52EB90B22778DA4E0048E0ED /* Line.swift */; };
52B8CF86277E0C12004CB680 /* BaseNavigationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52EB90AD2778AFD60048E0ED /* BaseNavigationView.swift */; };
52B8CF87277E0C5C004CB680 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5292F4FC2776BC7A00B9A7BB /* Assets.xcassets */; };
52EB90AC2778ADF80048E0ED /* CardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52EB90AB2778ADF80048E0ED /* CardView.swift */; };
52EB90AE2778AFD60048E0ED /* BaseNavigationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52EB90AD2778AFD60048E0ED /* BaseNavigationView.swift */; };
52EB90B02778D67F0048E0ED /* KeyItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52EB90AF2778D67F0048E0ED /* KeyItemView.swift */; };
52EB90B32778DA4E0048E0ED /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52EB90B22778DA4E0048E0ED /* Line.swift */; };
52F0243F277737470071D861 /* LoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52F0243E277737470071D861 /* LoginView.swift */; };
52F2C223277961D7006F08DC /* SettingsItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52F2C222277961D7006F08DC /* SettingsItemView.swift */; };
52F40D2F277CA05600766C24 /* MessageItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52F40D2E277CA05600766C24 /* MessageItemView.swift */; };
64B0C15E70CCC382B480F76E /* Pods_PushDeer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E380A18349DE4D26071E913E /* Pods_PushDeer.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
52B8CF71277E0B46004CB680 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 5292F4ED2776BC7900B9A7BB /* Project object */;
proxyType = 1;
remoteGlobalIDString = 52B8CF63277E0B44004CB680;
remoteInfo = PushDeerClip;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
52B8CF77277E0B46004CB680 /* Embed App Clips */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "$(CONTENTS_FOLDER_PATH)/AppClips";
dstSubfolderSpec = 16;
files = (
52B8CF73277E0B46004CB680 /* PushDeerClip.app in Embed App Clips */,
);
name = "Embed App Clips";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
52163EB227773F8400594190 /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = "<group>"; };
52163EB42777413B00594190 /* MessageListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageListView.swift; sourceTree = "<group>"; };
@ -34,11 +93,25 @@
52163EBA277741AC00594190 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
523150D8277875FB00941EDC /* DeletableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeletableView.swift; sourceTree = "<group>"; };
523150DB2778762B00941EDC /* DeviceItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceItemView.swift; sourceTree = "<group>"; };
52450F3727848243003652D8 /* PushDeerApi.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushDeerApi.swift; sourceTree = "<group>"; };
52450F3A278491F8003652D8 /* AppState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppState.swift; sourceTree = "<group>"; };
52450F3E2784923D003652D8 /* Result.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Result.swift; sourceTree = "<group>"; };
52450F412784943F003652D8 /* HttpRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HttpRequest.swift; sourceTree = "<group>"; };
52450F442784A95D003652D8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
52483FC1277ED6D5003A100E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
5292F4F52776BC7900B9A7BB /* PushDeer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PushDeer.app; sourceTree = BUILT_PRODUCTS_DIR; };
5292F4F82776BC7900B9A7BB /* PushDeerApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushDeerApp.swift; sourceTree = "<group>"; };
5292F4FA2776BC7900B9A7BB /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
5292F4FC2776BC7A00B9A7BB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
5292F4FF2776BC7A00B9A7BB /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
52B8CF5E277DE660004CB680 /* AppleSignInButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleSignInButton.swift; sourceTree = "<group>"; };
52B8CF64277E0B44004CB680 /* PushDeerClip.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PushDeerClip.app; sourceTree = BUILT_PRODUCTS_DIR; };
52B8CF66277E0B44004CB680 /* PushDeerClipApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushDeerClipApp.swift; sourceTree = "<group>"; };
52B8CF68277E0B44004CB680 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
52B8CF6A277E0B46004CB680 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
52B8CF6D277E0B46004CB680 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
52B8CF6F277E0B46004CB680 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
52B8CF70277E0B46004CB680 /* PushDeerClip.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = PushDeerClip.entitlements; sourceTree = "<group>"; };
52EB90AB2778ADF80048E0ED /* CardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardView.swift; sourceTree = "<group>"; };
52EB90AD2778AFD60048E0ED /* BaseNavigationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseNavigationView.swift; sourceTree = "<group>"; };
52EB90AF2778D67F0048E0ED /* KeyItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyItemView.swift; sourceTree = "<group>"; };
@ -46,6 +119,13 @@
52F0243C277733CE0071D861 /* PushDeer.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = PushDeer.entitlements; sourceTree = "<group>"; };
52F0243E277737470071D861 /* LoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginView.swift; sourceTree = "<group>"; };
52F2C222277961D7006F08DC /* SettingsItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsItemView.swift; sourceTree = "<group>"; };
52F40D2E277CA05600766C24 /* MessageItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageItemView.swift; sourceTree = "<group>"; };
69F56B2711ED98819D474BE3 /* Pods-PushDeerClip.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushDeerClip.debug.xcconfig"; path = "Target Support Files/Pods-PushDeerClip/Pods-PushDeerClip.debug.xcconfig"; sourceTree = "<group>"; };
9CC775BE0326BF31C6FACF06 /* Pods-PushDeerClip.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushDeerClip.release.xcconfig"; path = "Target Support Files/Pods-PushDeerClip/Pods-PushDeerClip.release.xcconfig"; sourceTree = "<group>"; };
CCCE1F6E56B157872E2C755F /* Pods-PushDeer.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushDeer.release.xcconfig"; path = "Target Support Files/Pods-PushDeer/Pods-PushDeer.release.xcconfig"; sourceTree = "<group>"; };
CE3005BD875FC9819A92466C /* Pods-PushDeer.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushDeer.debug.xcconfig"; path = "Target Support Files/Pods-PushDeer/Pods-PushDeer.debug.xcconfig"; sourceTree = "<group>"; };
E03C2088F4CD9F4C0848E1A5 /* Pods_PushDeerClip.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PushDeerClip.framework; sourceTree = BUILT_PRODUCTS_DIR; };
E380A18349DE4D26071E913E /* Pods_PushDeer.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PushDeer.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -53,17 +133,58 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
64B0C15E70CCC382B480F76E /* Pods_PushDeer.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
52B8CF61277E0B44004CB680 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
4812F19BB0BFEFE089BC253E /* Pods_PushDeerClip.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
17D35B157765D96FC4DA6C39 /* Pods */ = {
isa = PBXGroup;
children = (
CE3005BD875FC9819A92466C /* Pods-PushDeer.debug.xcconfig */,
CCCE1F6E56B157872E2C755F /* Pods-PushDeer.release.xcconfig */,
69F56B2711ED98819D474BE3 /* Pods-PushDeerClip.debug.xcconfig */,
9CC775BE0326BF31C6FACF06 /* Pods-PushDeerClip.release.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
};
52450F362784822C003652D8 /* Service */ = {
isa = PBXGroup;
children = (
52450F3727848243003652D8 /* PushDeerApi.swift */,
52450F3A278491F8003652D8 /* AppState.swift */,
52450F412784943F003652D8 /* HttpRequest.swift */,
);
path = Service;
sourceTree = "<group>";
};
52450F3D27849228003652D8 /* Model */ = {
isa = PBXGroup;
children = (
52450F3E2784923D003652D8 /* Result.swift */,
);
path = Model;
sourceTree = "<group>";
};
5292F4EC2776BC7900B9A7BB = {
isa = PBXGroup;
children = (
5292F4F72776BC7900B9A7BB /* PushDeer */,
52B8CF65277E0B44004CB680 /* PushDeerClip */,
5292F4F62776BC7900B9A7BB /* Products */,
17D35B157765D96FC4DA6C39 /* Pods */,
78FEAD2568FB92808C44E85A /* Frameworks */,
);
indentWidth = 2;
sourceTree = "<group>";
@ -72,6 +193,7 @@
isa = PBXGroup;
children = (
5292F4F52776BC7900B9A7BB /* PushDeer.app */,
52B8CF64277E0B44004CB680 /* PushDeerClip.app */,
);
name = Products;
sourceTree = "<group>";
@ -79,8 +201,13 @@
5292F4F72776BC7900B9A7BB /* PushDeer */ = {
isa = PBXGroup;
children = (
52450F442784A95D003652D8 /* Info.plist */,
52450F362784822C003652D8 /* Service */,
52B8CF5D277DE5FF004CB680 /* Common */,
52450F3D27849228003652D8 /* Model */,
52F0243D2777370F0071D861 /* View */,
52F0243C277733CE0071D861 /* PushDeer.entitlements */,
52483FC1277ED6D5003A100E /* AppDelegate.swift */,
5292F4F82776BC7900B9A7BB /* PushDeerApp.swift */,
5292F4FA2776BC7900B9A7BB /* ContentView.swift */,
5292F4FC2776BC7A00B9A7BB /* Assets.xcassets */,
@ -97,6 +224,35 @@
path = "Preview Content";
sourceTree = "<group>";
};
52B8CF5D277DE5FF004CB680 /* Common */ = {
isa = PBXGroup;
children = (
52B8CF5E277DE660004CB680 /* AppleSignInButton.swift */,
);
path = Common;
sourceTree = "<group>";
};
52B8CF65277E0B44004CB680 /* PushDeerClip */ = {
isa = PBXGroup;
children = (
52B8CF66277E0B44004CB680 /* PushDeerClipApp.swift */,
52B8CF68277E0B44004CB680 /* ContentView.swift */,
52B8CF6A277E0B46004CB680 /* Assets.xcassets */,
52B8CF6F277E0B46004CB680 /* Info.plist */,
52B8CF70277E0B46004CB680 /* PushDeerClip.entitlements */,
52B8CF6C277E0B46004CB680 /* Preview Content */,
);
path = PushDeerClip;
sourceTree = "<group>";
};
52B8CF6C277E0B46004CB680 /* Preview Content */ = {
isa = PBXGroup;
children = (
52B8CF6D277E0B46004CB680 /* Preview Assets.xcassets */,
);
path = "Preview Content";
sourceTree = "<group>";
};
52EB90B12778D9F90048E0ED /* Common */ = {
isa = PBXGroup;
children = (
@ -120,11 +276,21 @@
52163EBA277741AC00594190 /* SettingsView.swift */,
523150DB2778762B00941EDC /* DeviceItemView.swift */,
52EB90AF2778D67F0048E0ED /* KeyItemView.swift */,
52F40D2E277CA05600766C24 /* MessageItemView.swift */,
52F2C222277961D7006F08DC /* SettingsItemView.swift */,
);
path = View;
sourceTree = "<group>";
};
78FEAD2568FB92808C44E85A /* Frameworks */ = {
isa = PBXGroup;
children = (
E380A18349DE4D26071E913E /* Pods_PushDeer.framework */,
E03C2088F4CD9F4C0848E1A5 /* Pods_PushDeerClip.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@ -132,19 +298,42 @@
isa = PBXNativeTarget;
buildConfigurationList = 5292F5032776BC7A00B9A7BB /* Build configuration list for PBXNativeTarget "PushDeer" */;
buildPhases = (
D7C2D4C0049487EE64D69530 /* [CP] Check Pods Manifest.lock */,
5292F4F12776BC7900B9A7BB /* Sources */,
5292F4F22776BC7900B9A7BB /* Frameworks */,
5292F4F32776BC7900B9A7BB /* Resources */,
52B8CF77277E0B46004CB680 /* Embed App Clips */,
D5C7FAC44EC37CBCD945E0F2 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
dependencies = (
52B8CF72277E0B46004CB680 /* PBXTargetDependency */,
);
name = PushDeer;
productName = PushDeer;
productReference = 5292F4F52776BC7900B9A7BB /* PushDeer.app */;
productType = "com.apple.product-type.application";
};
52B8CF63277E0B44004CB680 /* PushDeerClip */ = {
isa = PBXNativeTarget;
buildConfigurationList = 52B8CF74277E0B46004CB680 /* Build configuration list for PBXNativeTarget "PushDeerClip" */;
buildPhases = (
2478CBF24D0E46561F75C65B /* [CP] Check Pods Manifest.lock */,
52B8CF60277E0B44004CB680 /* Sources */,
52B8CF61277E0B44004CB680 /* Frameworks */,
52B8CF62277E0B44004CB680 /* Resources */,
2E496999EBC4004366E8DE5E /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = PushDeerClip;
productName = PushDeerClip;
productReference = 52B8CF64277E0B44004CB680 /* PushDeerClip.app */;
productType = "com.apple.product-type.application.on-demand-install-capable";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
@ -158,6 +347,9 @@
5292F4F42776BC7900B9A7BB = {
CreatedOnToolsVersion = 13.2.1;
};
52B8CF63277E0B44004CB680 = {
CreatedOnToolsVersion = 13.2.1;
};
};
};
buildConfigurationList = 5292F4F02776BC7900B9A7BB /* Build configuration list for PBXProject "PushDeer" */;
@ -174,6 +366,7 @@
projectRoot = "";
targets = (
5292F4F42776BC7900B9A7BB /* PushDeer */,
52B8CF63277E0B44004CB680 /* PushDeerClip */,
);
};
/* End PBXProject section */
@ -188,8 +381,99 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
52B8CF62277E0B44004CB680 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
52B8CF6E277E0B46004CB680 /* Preview Assets.xcassets in Resources */,
52B8CF87277E0C5C004CB680 /* Assets.xcassets in Resources */,
52B8CF6B277E0B46004CB680 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
2478CBF24D0E46561F75C65B /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-PushDeerClip-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
2E496999EBC4004366E8DE5E /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-PushDeerClip/Pods-PushDeerClip-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-PushDeerClip/Pods-PushDeerClip-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-PushDeerClip/Pods-PushDeerClip-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
D5C7FAC44EC37CBCD945E0F2 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-PushDeer/Pods-PushDeer-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-PushDeer/Pods-PushDeer-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-PushDeer/Pods-PushDeer-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
D7C2D4C0049487EE64D69530 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-PushDeer-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
5292F4F12776BC7900B9A7BB /* Sources */ = {
isa = PBXSourcesBuildPhase;
@ -203,18 +487,63 @@
52EB90B32778DA4E0048E0ED /* Line.swift in Sources */,
52F2C223277961D7006F08DC /* SettingsItemView.swift in Sources */,
52163EB72777415F00594190 /* DeviceListView.swift in Sources */,
52B8CF5F277DE660004CB680 /* AppleSignInButton.swift in Sources */,
52163EB92777417900594190 /* KeyListView.swift in Sources */,
5292F4FB2776BC7900B9A7BB /* ContentView.swift in Sources */,
52450F3B278491F8003652D8 /* AppState.swift in Sources */,
5292F4F92776BC7900B9A7BB /* PushDeerApp.swift in Sources */,
52483FC2277ED6D5003A100E /* AppDelegate.swift in Sources */,
52450F3827848243003652D8 /* PushDeerApi.swift in Sources */,
52EB90AE2778AFD60048E0ED /* BaseNavigationView.swift in Sources */,
52EB90AC2778ADF80048E0ED /* CardView.swift in Sources */,
52EB90B02778D67F0048E0ED /* KeyItemView.swift in Sources */,
52450F3F2784923D003652D8 /* Result.swift in Sources */,
52450F422784943F003652D8 /* HttpRequest.swift in Sources */,
52163EB52777413B00594190 /* MessageListView.swift in Sources */,
52F40D2F277CA05600766C24 /* MessageItemView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
52B8CF60277E0B44004CB680 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
52B8CF82277E0C06004CB680 /* AppleSignInButton.swift in Sources */,
52B8CF69277E0B44004CB680 /* ContentView.swift in Sources */,
52B8CF78277E0BF1004CB680 /* MainView.swift in Sources */,
52B8CF79277E0BFB004CB680 /* DeviceListView.swift in Sources */,
52B8CF84277E0C12004CB680 /* CardView.swift in Sources */,
52B8CF7E277E0BFB004CB680 /* SettingsView.swift in Sources */,
52B8CF7C277E0BFB004CB680 /* KeyListView.swift in Sources */,
52B8CF7A277E0BFB004CB680 /* MessageListView.swift in Sources */,
52B8CF83277E0C12004CB680 /* DeletableView.swift in Sources */,
52B8CF81277E0BFB004CB680 /* LoginView.swift in Sources */,
52B8CF7F277E0BFB004CB680 /* SettingsItemView.swift in Sources */,
52450F3C278491F8003652D8 /* AppState.swift in Sources */,
52B8CF80277E0BFB004CB680 /* MessageItemView.swift in Sources */,
52483FC3277ED6D5003A100E /* AppDelegate.swift in Sources */,
52450F3927848243003652D8 /* PushDeerApi.swift in Sources */,
52B8CF86277E0C12004CB680 /* BaseNavigationView.swift in Sources */,
52B8CF67277E0B44004CB680 /* PushDeerClipApp.swift in Sources */,
52B8CF85277E0C12004CB680 /* Line.swift in Sources */,
52450F402784923D003652D8 /* Result.swift in Sources */,
52450F432784943F003652D8 /* HttpRequest.swift in Sources */,
52B8CF7B277E0BFB004CB680 /* DeviceItemView.swift in Sources */,
52B8CF7D277E0BFB004CB680 /* KeyItemView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
52B8CF72277E0B46004CB680 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
platformFilter = ios;
target = 52B8CF63277E0B44004CB680 /* PushDeerClip */;
targetProxy = 52B8CF71277E0B46004CB680 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
5292F5012776BC7A00B9A7BB /* Debug */ = {
isa = XCBuildConfiguration;
@ -334,6 +663,7 @@
};
5292F5042776BC7A00B9A7BB /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = CE3005BD875FC9819A92466C /* Pods-PushDeer.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
@ -344,6 +674,7 @@
DEVELOPMENT_TEAM = Y47WTLML2S;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = PushDeer/Info.plist;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
@ -365,6 +696,7 @@
};
5292F5052776BC7A00B9A7BB /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = CCCE1F6E56B157872E2C755F /* Pods-PushDeer.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
@ -375,6 +707,7 @@
DEVELOPMENT_TEAM = Y47WTLML2S;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = PushDeer/Info.plist;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
@ -394,6 +727,74 @@
};
name = Release;
};
52B8CF75277E0B46004CB680 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 69F56B2711ED98819D474BE3 /* Pods-PushDeerClip.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = PushDeerClip/PushDeerClip.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"PushDeerClip/Preview Content\"";
DEVELOPMENT_TEAM = Y47WTLML2S;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = PushDeerClip/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = PushDeer;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.wskfz.pushdeer.ios.Clip;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
52B8CF76277E0B46004CB680 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9CC775BE0326BF31C6FACF06 /* Pods-PushDeerClip.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = PushDeerClip/PushDeerClip.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"PushDeerClip/Preview Content\"";
DEVELOPMENT_TEAM = Y47WTLML2S;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = PushDeerClip/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = PushDeer;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.wskfz.pushdeer.ios.Clip;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@ -415,6 +816,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
52B8CF74277E0B46004CB680 /* Build configuration list for PBXNativeTarget "PushDeerClip" */ = {
isa = XCConfigurationList;
buildConfigurations = (
52B8CF75277E0B46004CB680 /* Debug */,
52B8CF76277E0B46004CB680 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 5292F4ED2776BC7900B9A7BB /* Project object */;

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:PushDeer.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@ -0,0 +1,49 @@
//
// AppDelegate.swift
// PushDeer
//
// Created by HeXiaoTian on 2021/12/31.
//
import UIKit
import UserNotifications
class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDelegate {
static var deviceToken: String = ""
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
let center = UNUserNotificationCenter.current()
center.delegate = self
center.requestAuthorization(options: [.badge, .sound, .alert]) { granted, error in
print("注册通知结果: \(granted) - \(String(describing: error))")
}
application.registerForRemoteNotifications()
Task {
// APP, , . ()
let result = try await HttpRequest.fake()
AppState.shared.token = result.token
HttpRequest.getDevices()
}
return true
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
print("deviceToken: ", deviceTokenString)
AppDelegate.deviceToken = deviceTokenString;
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification) async -> UNNotificationPresentationOptions {
print("willPresent:", notification.request.content.userInfo)
return [.sound, .list, .banner]
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse) async {
print("didReceive:", response.notification.request.content.userInfo)
}
}

View File

@ -1,98 +1,122 @@
{
"images" : [
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "20x20"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "20x20"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "40x40"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "40x40"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x60"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "20x20"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "20x20"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "29x29"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "29x29"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "40x40"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "40x40"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "76x76"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "76x76"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "83.5x83.5"
},
{
"idiom" : "ios-marketing",
"scale" : "1x",
"size" : "1024x1024"
"images": [
{
"size": "20x20",
"idiom": "iphone",
"filename": "icon-20@2x.png",
"scale": "2x"
},
{
"size": "20x20",
"idiom": "iphone",
"filename": "icon-20@3x.png",
"scale": "3x"
},
{
"size": "29x29",
"idiom": "iphone",
"filename": "icon-29.png",
"scale": "1x"
},
{
"size": "29x29",
"idiom": "iphone",
"filename": "icon-29@2x.png",
"scale": "2x"
},
{
"size": "29x29",
"idiom": "iphone",
"filename": "icon-29@3x.png",
"scale": "3x"
},
{
"size": "40x40",
"idiom": "iphone",
"filename": "icon-40@2x.png",
"scale": "2x"
},
{
"size": "40x40",
"idiom": "iphone",
"filename": "icon-40@3x.png",
"scale": "3x"
},
{
"size": "60x60",
"idiom": "iphone",
"filename": "icon-60@2x.png",
"scale": "2x"
},
{
"size": "60x60",
"idiom": "iphone",
"filename": "icon-60@3x.png",
"scale": "3x"
},
{
"size": "20x20",
"idiom": "ipad",
"filename": "icon-20-ipad.png",
"scale": "1x"
},
{
"size": "20x20",
"idiom": "ipad",
"filename": "icon-20@2x-ipad.png",
"scale": "2x"
},
{
"size": "29x29",
"idiom": "ipad",
"filename": "icon-29-ipad.png",
"scale": "1x"
},
{
"size": "29x29",
"idiom": "ipad",
"filename": "icon-29@2x-ipad.png",
"scale": "2x"
},
{
"size": "40x40",
"idiom": "ipad",
"filename": "icon-40.png",
"scale": "1x"
},
{
"size": "40x40",
"idiom": "ipad",
"filename": "icon-40@2x.png",
"scale": "2x"
},
{
"size": "76x76",
"idiom": "ipad",
"filename": "icon-76.png",
"scale": "1x"
},
{
"size": "76x76",
"idiom": "ipad",
"filename": "icon-76@2x.png",
"scale": "2x"
},
{
"size": "83.5x83.5",
"idiom": "ipad",
"filename": "icon-83.5@2x.png",
"scale": "2x"
},
{
"size": "1024x1024",
"idiom": "ios-marketing",
"filename": "icon-1024.png",
"scale": "1x"
}
],
"info": {
"version": 1,
"author": "icon.wuruihong.com"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 641 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 947 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 947 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

@ -0,0 +1,71 @@
//
// AppleSignInButton.swift
// PushDeer
//
// Created by HEXT on 2021/12/30.
//
import Foundation
import UIKit
import SwiftUI
import AuthenticationServices
/// Apple , 仿 SwiftUI SignInWithAppleButton
///
/// 使? , SignInWithAppleButton macOS , iOS .
struct AppleSignInButton: UIViewRepresentable {
var type = ASAuthorizationAppleIDButton.ButtonType.signIn
var style = ASAuthorizationAppleIDButton.Style.black
let onRequest: (ASAuthorizationAppleIDRequest) -> Void
let onCompletion: (Result<ASAuthorization, Error>) -> Void
func makeUIView(context: Context) -> ASAuthorizationAppleIDButton {
let signInButton = ASAuthorizationAppleIDButton(type: type, style: style)
let coordinator = AppleSignInCoordinator(onRequest: onRequest, onCompletion: onCompletion)
signInButton.addAction(
UIAction { action in
coordinator.performRequests()
},
for: UIControl.Event.touchUpInside
)
return signInButton
}
func updateUIView(_ uiView: ASAuthorizationAppleIDButton, context: Context) {
}
}
class AppleSignInCoordinator: NSObject, ASAuthorizationControllerDelegate {
let onRequest: (ASAuthorizationAppleIDRequest) -> Void
let onCompletion: (Result<ASAuthorization, Error>) -> Void
init(
onRequest: @escaping (ASAuthorizationAppleIDRequest) -> Void,
onCompletion: @escaping (Result<ASAuthorization, Error>) -> Void
) {
self.onRequest = onRequest
self.onCompletion = onCompletion
}
@objc func performRequests() {
let appleIDProvider = ASAuthorizationAppleIDProvider()
let request = appleIDProvider.createRequest()
onRequest(request)
let authorizationController = ASAuthorizationController(authorizationRequests: [request])
authorizationController.delegate = self
authorizationController.performRequests()
}
func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
print(authorization.debugDescription)
onCompletion(.success(authorization))
}
func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
print(error.localizedDescription)
onCompletion(.failure(error))
}
}

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>UIBackgroundModes</key>
<array>
<string>remote-notification</string>
</array>
</dict>
</plist>

View File

@ -0,0 +1,59 @@
//
// Result.swift
// PushDeer
//
// Created by HEXT on 2022/1/4.
//
import Foundation
/// API
struct ApiResult<T : Codable> : Codable{
let code: Int
/// , code != 0
let error: String?
/// , code == 0
let content: T?
}
struct TokenContent: Codable{
let token: String
}
struct DeviceItem: Codable, Identifiable{
let id: Int
let uid: String
let name: String
let type: String
let device_id: String
let is_clip: Int
}
struct DeviceContent: Codable{
let devices: [DeviceItem]
}
struct KeyContent: Codable{
let keys: [KeyItem]
}
struct KeyItem: Codable, Identifiable{
let id: Int
let key: String
}
struct MessageContent: Codable{
let messages: [MessageItem]
}
struct MessageItem: Codable, Identifiable{
let id: Int
let uid: String
let text: String
let desp: String
let type: String
}
struct ActionContent: Codable{
let message: String
}

View File

@ -2,6 +2,12 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>aps-environment</key>
<string>development</string>
<key>com.apple.developer.applesignin</key>
<array>
<string>Default</string>
</array>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.network.client</key>

View File

@ -9,9 +9,11 @@ import SwiftUI
@main
struct PushDeerApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
ContentView().environmentObject(AppState.shared)
}
}
}

View File

@ -0,0 +1,19 @@
//
// AppState.swift
// PushDeer
//
// Created by HEXT on 2022/1/4.
//
import Foundation
class AppState: ObservableObject {
@Published var token : String? = nil
@Published var devices: [DeviceItem] = []
@Published var keys: [KeyItem] = []
@Published var messages: [MessageItem] = []
@Published var tab_selected: Int = 1
@Published var device_token: String = ""
static let shared = AppState()
private init() {}
}

View File

@ -0,0 +1,55 @@
//
// HttpRequest.swift
// PushDeer
//
// Created by HEXT on 2022/1/4.
//
import Foundation
import Moya
struct HttpRequest {
static let provider = MoyaProvider<PushDeerApi>(callbackQueue: DispatchQueue.main)
/// , Swift Concurrency (async / await)
static func request<T: Codable>(_ targetType: PushDeerApi, resultType: T.Type) async throws -> T {
return try await withCheckedThrowingContinuation { continuation in
provider.request(targetType) { result in
switch result {
case let .success(response):
do {
let result = try JSONDecoder().decode(ApiResult<T>.self, from: response.data)
print(result)
if let content = result.content, result.code == 0 {
continuation.resume(returning: content)
} else {
continuation.resume(throwing: NSError(domain: result.error ?? "接口报错", code: result.code, userInfo: nil))
}
} catch {
print(error)
continuation.resume(throwing: error)
}
case let .failure(error):
print(error)
continuation.resume(throwing: error)
}
}
}
}
static func fake() async throws -> TokenContent {
return try await request(.fake, resultType: TokenContent.self)
}
static func login(idToken: String) async throws -> TokenContent {
return try await request(.login(idToken: idToken), resultType: TokenContent.self)
}
@MainActor static func getDevices() {
_Concurrency.Task {
let result = try await request(.getDevices(token: AppState.shared.token ?? ""), resultType: DeviceContent.self)
AppState.shared.devices = result.devices
}
}
}

View File

@ -0,0 +1,114 @@
//
// PushDeerApi.swift
// PushDeer
//
// Created by HEXT on 2022/1/4.
//
import Foundation
import Moya
enum PushDeerApi {
case fake
case login(idToken: String)
case regDevice(token: String, name: String, device_id: String, is_clip: Int)
case getDevices(token: String)
case rmDevice(token: String, id: Int)
case genKey(token: String)
case regenKey(token: String, id: Int)
case renameKey(token: String, id: Int, name: String)
case getKeys(token: String)
case rmKey(token: String, id: Int)
/// type: =textmarkdown=imagemarkdown
case push(pushkey: String, text: String, desp: String, type: String)
case getMessages(token: String, limit: Int)
case rmMessage(token: String, id: Int)
}
extension PushDeerApi: TargetType {
var baseURL: URL { URL( string: "http://pushdeer.wskfz.com:8800" )! }
var path: String {
switch self {
case .fake:
return "/login/fake"
case .login:
return "/login/idtoken"
case .regDevice:
return "/device/reg"
case .getDevices:
return "/device/list"
case .rmDevice:
return "/device/remove"
case .genKey:
return "/key/gen"
case .regenKey:
return "/key/regen"
case .renameKey:
return "/key/rename"
case .getKeys:
return "/key/list"
case .rmKey:
return "/key/remove"
case .push:
return "/message/push"
case .getMessages:
return "/message/list"
case .rmMessage:
return "/message/remove"
}
}
var method: Moya.Method {
switch self {
default:
return .post
}
}
var task: Task {
switch self {
case .fake:
return .requestParameters(parameters: [:], encoding: URLEncoding.queryString)
case let .login(idToken):
return .requestParameters(parameters: ["idToken": idToken], encoding: URLEncoding.queryString)
case let .regDevice(token, name, device_id, is_clip):
return .requestParameters(parameters: ["token": token,"name": name, "device_id": device_id,"is_clip": is_clip], encoding: URLEncoding.queryString)
case let .getDevices(token):
return .requestParameters(parameters: ["token": token], encoding: URLEncoding.queryString)
case let .rmDevice(token, id):
return .requestParameters(parameters: ["token": token,"id": id], encoding: URLEncoding.queryString)
case let .genKey(token):
return .requestParameters(parameters: ["token": token], encoding: URLEncoding.queryString)
case let .regenKey(token, id):
return .requestParameters(parameters: ["token": token,"id": id], encoding: URLEncoding.queryString)
case let .renameKey(token, id, name):
return .requestParameters(parameters: ["token": token,"id": id,"name": name], encoding: URLEncoding.queryString)
case let .getKeys(token):
return .requestParameters(parameters: ["token": token],encoding: URLEncoding.queryString)
case let .rmKey(token, id):
return .requestParameters(parameters: ["token": token, "id": id],encoding: URLEncoding.queryString)
case let .push(pushkey, text, desp, type):
return .requestParameters(parameters: ["pushkey": pushkey, "text": text, "desp": desp, "type": type],encoding: URLEncoding.queryString)
case let .getMessages(token, limit):
return .requestParameters(parameters: ["token": token, "limit": limit],encoding: URLEncoding.queryString)
case let .rmMessage(token, id):
return .requestParameters(parameters: ["token": token, "id": id],encoding: URLEncoding.queryString)
}
}
var headers: [String: String]? {
return ["Content-type": "application/json"]
}
}

View File

@ -9,32 +9,36 @@ import SwiftUI
///
struct DeviceListView: View {
@State var devices = Array(0..<10)
@EnvironmentObject private var store: AppState
var body: some View {
BaseNavigationView(title: "设备") {
ScrollView {
LazyVStack(alignment: .center) {
ForEach(devices, id: \.self) { name in
ForEach(store.devices, id: \.id) { deviceItem in
DeletableView(contentView: {
DeviceItemView(name: "设备 \(name)")
DeviceItemView(name: deviceItem.name)
}, deleteAction: {
devices.removeAll { _name in
_name == name
store.devices.removeAll { _deviceItem in
_deviceItem.id == deviceItem.id
}
})
.padding(EdgeInsets(top: 18, leading: 26, bottom: 0, trailing: 24))
}
Spacer(minLength: 30)
}
}
.navigationBarItems(trailing: Button(action: {
withAnimation(.easeOut) {
devices.insert(Int(arc4random_uniform(1000)), at: 0)
// store.devices.insert(DeviceItem(), at: 0)
}
}, label: {
Image(systemName: "plus")
.foregroundColor(Color(UIColor.lightGray))
}))
}
.onAppear {
HttpRequest.getDevices()
}
}
}

View File

@ -7,11 +7,6 @@
import SwiftUI
struct KeyItem: Codable, Identifiable{
let id: Int
let key: String
}
/// Key
struct KeyListView: View {
@State private var keyItems = [
@ -37,6 +32,7 @@ struct KeyListView: View {
})
.padding(EdgeInsets(top: 18, leading: 26, bottom: 0, trailing: 24))
}
Spacer(minLength: 30)
}
}
.navigationBarItems(trailing: Button(action: {

View File

@ -17,15 +17,39 @@ struct LoginView: View {
.resizable()
.scaledToFit()
Spacer()
SignInWithAppleButton(
AppleSignInButton(
onRequest: { request in
request.requestedScopes = [.fullName, .email]
},
onCompletion: { result in
switch result {
case let .success(authorization):
if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential {
// IDAPP
print(appleIDCredential.user) // 000791.7a323f1326dd4674bc16d32fd6339875.1424
// emailfullName->Apple ID->->使AppleIDApp APP
print(appleIDCredential.email as Any) // easychen@qq.com
print(appleIDCredential.fullName as Any) // givenName: lijie familyName: chen
// JWTtoken.3, base64
let idToken = String(data:appleIDCredential.identityToken!, encoding: .utf8)
print(idToken as Any)
Task {
do {
let result = try await HttpRequest.login(idToken: idToken!)
print(result)
} catch {
print(error)
}
}
}
case let .failure(error):
print(error)
}
}
)
.frame(height: 64)
.frame(maxWidth: 375, minHeight: 64, maxHeight: 64)
.padding()
Spacer()
}

View File

@ -0,0 +1,64 @@
//
// MessageItemView.swift
// PushDeer
//
// Created by HEXT on 2021/12/29.
//
import SwiftUI
struct MessageItemView: View {
///
let deleteAction : () -> ()
var body: some View {
VStack {
HStack {
HLine().stroke(Color(UIColor.lightGray))
.frame(width: 20, height: 1)
Image("avatar2")
.resizable()
.scaledToFit()
.frame(width: 38, height: 38)
Text("key名字")
.font(.system(size: 14))
.foregroundColor(Color(UIColor.darkGray))
Text("· 5分钟前")
.font(.system(size: 12))
.foregroundColor(Color(UIColor.darkGray))
HLine().stroke(Color(UIColor.lightGray))
.frame(height: 1)
}
DeletableView(contentView: {
CardView {
HStack{
Text("纯文本的效果")
.font(.system(size: 14))
.foregroundColor(Color(UIColor.darkGray))
.padding()
Spacer(minLength: 0)
}
.contextMenu {
Button("复制") {
UIPasteboard.general.string = "someText"
}
}
}
}, deleteAction: deleteAction)
.padding(EdgeInsets(top: 10, leading: 26, bottom: 0, trailing: 24))
}
.padding(.top, 25)
}
}
struct MessageItemView_Previews: PreviewProvider {
static var previews: some View {
VStack {
MessageItemView(){}
MessageItemView(){}
Spacer()
}
}
}

View File

@ -9,8 +9,56 @@ import SwiftUI
///
struct MessageListView: View {
@State private var messages = Array(0..<10)
@State private var isShowTest = true
var body: some View {
Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
BaseNavigationView(title: "消息") {
ScrollView {
LazyVStack(alignment: .leading) {
if isShowTest {
TestPushView()
}
ForEach(messages, id: \.self) { msg in
MessageItemView {
messages.removeAll { _msg in
_msg == msg
}
}
}
Spacer(minLength: 30)
}
}
.navigationBarItems(trailing: Button(action: {
withAnimation(.easeOut) {
isShowTest = !isShowTest
}
}, label: {
Image(systemName: isShowTest ? "chevron.up" : "chevron.down")
.foregroundColor(Color(UIColor.lightGray))
}))
}
}
}
struct TestPushView: View {
@State private var testText = ""
var body: some View {
TextEditor(text: $testText)
.overlay(RoundedRectangle(cornerRadius: 4).stroke(Color.accentColor))
.frame(height: 128)
.padding(EdgeInsets(top: 18, leading: 26, bottom: 0, trailing: 24))
Button("推送测试") {
print("点击推送测试")
}
.font(.system(size: 20))
.frame(width: 104, height: 42)
.foregroundColor(Color.white)
.background(Color.accentColor)
.cornerRadius(8)
.padding(EdgeInsets(top: 12, leading: 26, bottom: 0, trailing: 24))
}
}

View File

@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,20 @@
//
// ContentView.swift
// PushDeerClip
//
// Created by HEXT on 2021/12/30.
//
import SwiftUI
struct ContentView: View {
var body: some View {
MainView()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSAppClip</key>
<dict>
<key>NSAppClipRequestEphemeralUserNotification</key>
<false/>
<key>NSAppClipRequestLocationConfirmation</key>
<false/>
</dict>
</dict>
</plist>

View File

@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>aps-environment</key>
<string>development</string>
<key>com.apple.developer.applesignin</key>
<array>
<string>Default</string>
</array>
<key>com.apple.developer.parent-application-identifiers</key>
<array>
<string>$(AppIdentifierPrefix)com.wskfz.pushdeer.ios</string>
</array>
</dict>
</plist>

View File

@ -0,0 +1,19 @@
//
// PushDeerClipApp.swift
// PushDeerClip
//
// Created by HEXT on 2021/12/30.
//
import SwiftUI
@main
struct PushDeerClipApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView().environmentObject(AppState.shared)
}
}
}