1.0.0
@ -7,22 +7,51 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
0603706720E1E31600F4CA05 /* Defines.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0603706620E1E31600F4CA05 /* Defines.swift */; };
|
||||
0603706920E1F89500F4CA05 /* PreviewCardCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0603706820E1F89500F4CA05 /* PreviewCardCell.swift */; };
|
||||
0603706B20E20A7C00F4CA05 /* String+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0603706A20E20A7C00F4CA05 /* String+Extension.swift */; };
|
||||
0603706D20E23EC000F4CA05 /* BarkSFSafariViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0603706C20E23EC000F4CA05 /* BarkSFSafariViewController.swift */; };
|
||||
0604F7DF20620D4900B32F09 /* ServerManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0604F7DE20620D4900B32F09 /* ServerManager.swift */; };
|
||||
0637FA7820E0926D00E80174 /* BarkTargetType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0637FA7720E0926D00E80174 /* BarkTargetType.swift */; };
|
||||
0637FA7A20E092B300E80174 /* Observable+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0637FA7920E092B300E80174 /* Observable+Extension.swift */; };
|
||||
0637FA7C20E0930E00E80174 /* BarkApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0637FA7B20E0930E00E80174 /* BarkApi.swift */; };
|
||||
0637FA7E20E0969800E80174 /* Client.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0637FA7D20E0969800E80174 /* Client.swift */; };
|
||||
0637FA8020E0981E00E80174 /* BarkSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0637FA7F20E0981E00E80174 /* BarkSettings.swift */; };
|
||||
0637FA8220E09C4B00E80174 /* BarkNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0637FA8120E09C4B00E80174 /* BarkNavigationController.swift */; };
|
||||
0637FA8620E0AB6600E80174 /* UIColor+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0637FA8520E0AB6600E80174 /* UIColor+Extension.swift */; };
|
||||
0637FA8A20E0D58800E80174 /* NewServerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0637FA8920E0D58800E80174 /* NewServerViewController.swift */; };
|
||||
0637FA8C20E0D7A700E80174 /* BaseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0637FA8B20E0D7A700E80174 /* BaseViewController.swift */; };
|
||||
0661A543204FDA4100965E4E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0661A542204FDA4100965E4E /* AppDelegate.swift */; };
|
||||
0661A545204FDA4100965E4E /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0661A544204FDA4100965E4E /* ViewController.swift */; };
|
||||
0661A548204FDA4100965E4E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0661A546204FDA4100965E4E /* Main.storyboard */; };
|
||||
0661A545204FDA4100965E4E /* HomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0661A544204FDA4100965E4E /* HomeViewController.swift */; };
|
||||
0661A54A204FDA4100965E4E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0661A549204FDA4100965E4E /* Assets.xcassets */; };
|
||||
0661A54D204FDA4100965E4E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0661A54B204FDA4100965E4E /* LaunchScreen.storyboard */; };
|
||||
4A97FDFB8C102B8A492ED65A /* Pods_Bark.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D155DFC7B804DC5518C01D75 /* Pods_Bark.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
0603706620E1E31600F4CA05 /* Defines.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Defines.swift; sourceTree = "<group>"; };
|
||||
0603706820E1F89500F4CA05 /* PreviewCardCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewCardCell.swift; sourceTree = "<group>"; };
|
||||
0603706A20E20A7C00F4CA05 /* String+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Extension.swift"; sourceTree = "<group>"; };
|
||||
0603706C20E23EC000F4CA05 /* BarkSFSafariViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BarkSFSafariViewController.swift; sourceTree = "<group>"; };
|
||||
0604F7DE20620D4900B32F09 /* ServerManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerManager.swift; sourceTree = "<group>"; };
|
||||
0637FA7720E0926D00E80174 /* BarkTargetType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BarkTargetType.swift; sourceTree = "<group>"; };
|
||||
0637FA7920E092B300E80174 /* Observable+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Observable+Extension.swift"; sourceTree = "<group>"; };
|
||||
0637FA7B20E0930E00E80174 /* BarkApi.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BarkApi.swift; sourceTree = "<group>"; };
|
||||
0637FA7D20E0969800E80174 /* Client.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Client.swift; sourceTree = "<group>"; };
|
||||
0637FA7F20E0981E00E80174 /* BarkSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BarkSettings.swift; sourceTree = "<group>"; };
|
||||
0637FA8120E09C4B00E80174 /* BarkNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BarkNavigationController.swift; sourceTree = "<group>"; };
|
||||
0637FA8520E0AB6600E80174 /* UIColor+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Extension.swift"; sourceTree = "<group>"; };
|
||||
0637FA8920E0D58800E80174 /* NewServerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewServerViewController.swift; sourceTree = "<group>"; };
|
||||
0637FA8B20E0D7A700E80174 /* BaseViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseViewController.swift; sourceTree = "<group>"; };
|
||||
0661A53F204FDA4100965E4E /* Bark.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Bark.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
0661A542204FDA4100965E4E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
0661A544204FDA4100965E4E /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
|
||||
0661A547204FDA4100965E4E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||
0661A544204FDA4100965E4E /* HomeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeViewController.swift; sourceTree = "<group>"; };
|
||||
0661A549204FDA4100965E4E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
0661A54C204FDA4100965E4E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
0661A54E204FDA4100965E4E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
0683486A2050F1310024B6DA /* Bark.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Bark.entitlements; sourceTree = "<group>"; };
|
||||
0683487020510FB20024B6DA /* UserNotifications.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UserNotifications.framework; path = System/Library/Frameworks/UserNotifications.framework; sourceTree = SDKROOT; };
|
||||
0683487220510FB20024B6DA /* UserNotificationsUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UserNotificationsUI.framework; path = System/Library/Frameworks/UserNotificationsUI.framework; sourceTree = SDKROOT; };
|
||||
1CC985CE300A858FF65E166A /* Pods-Bark.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Bark.release.xcconfig"; path = "Pods/Target Support Files/Pods-Bark/Pods-Bark.release.xcconfig"; sourceTree = "<group>"; };
|
||||
87D1222A4C6E7283974A44C6 /* Pods-Bark.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Bark.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Bark/Pods-Bark.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
D155DFC7B804DC5518C01D75 /* Pods_Bark.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Bark.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
@ -40,9 +69,48 @@
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
0604F7DB20620D2700B32F09 /* Controller */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0637FA8B20E0D7A700E80174 /* BaseViewController.swift */,
|
||||
0637FA8120E09C4B00E80174 /* BarkNavigationController.swift */,
|
||||
0661A544204FDA4100965E4E /* HomeViewController.swift */,
|
||||
0637FA8920E0D58800E80174 /* NewServerViewController.swift */,
|
||||
0603706C20E23EC000F4CA05 /* BarkSFSafariViewController.swift */,
|
||||
);
|
||||
path = Controller;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0604F7DC20620D3400B32F09 /* View */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0603706820E1F89500F4CA05 /* PreviewCardCell.swift */,
|
||||
);
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0604F7DD20620D3800B32F09 /* Model */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0603706620E1E31600F4CA05 /* Defines.swift */,
|
||||
0637FA8520E0AB6600E80174 /* UIColor+Extension.swift */,
|
||||
0603706A20E20A7C00F4CA05 /* String+Extension.swift */,
|
||||
0637FA7F20E0981E00E80174 /* BarkSettings.swift */,
|
||||
0604F7DE20620D4900B32F09 /* ServerManager.swift */,
|
||||
0637FA7720E0926D00E80174 /* BarkTargetType.swift */,
|
||||
0637FA7920E092B300E80174 /* Observable+Extension.swift */,
|
||||
0637FA7B20E0930E00E80174 /* BarkApi.swift */,
|
||||
0637FA7D20E0969800E80174 /* Client.swift */,
|
||||
);
|
||||
path = Model;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0661A536204FDA4100965E4E = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0604F7DD20620D3800B32F09 /* Model */,
|
||||
0604F7DC20620D3400B32F09 /* View */,
|
||||
0604F7DB20620D2700B32F09 /* Controller */,
|
||||
0661A541204FDA4100965E4E /* Bark */,
|
||||
0661A540204FDA4100965E4E /* Products */,
|
||||
9563D0DB71FE280909AB1C63 /* Pods */,
|
||||
@ -61,9 +129,8 @@
|
||||
0661A541204FDA4100965E4E /* Bark */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0683486A2050F1310024B6DA /* Bark.entitlements */,
|
||||
0661A542204FDA4100965E4E /* AppDelegate.swift */,
|
||||
0661A544204FDA4100965E4E /* ViewController.swift */,
|
||||
0661A546204FDA4100965E4E /* Main.storyboard */,
|
||||
0661A549204FDA4100965E4E /* Assets.xcassets */,
|
||||
0661A54B204FDA4100965E4E /* LaunchScreen.storyboard */,
|
||||
0661A54E204FDA4100965E4E /* Info.plist */,
|
||||
@ -84,6 +151,8 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D155DFC7B804DC5518C01D75 /* Pods_Bark.framework */,
|
||||
0683487020510FB20024B6DA /* UserNotifications.framework */,
|
||||
0683487220510FB20024B6DA /* UserNotificationsUI.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
@ -118,12 +187,17 @@
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0920;
|
||||
LastUpgradeCheck = 0920;
|
||||
LastUpgradeCheck = 0930;
|
||||
ORGANIZATIONNAME = Fin;
|
||||
TargetAttributes = {
|
||||
0661A53E204FDA4100965E4E = {
|
||||
CreatedOnToolsVersion = 9.2;
|
||||
ProvisioningStyle = Automatic;
|
||||
SystemCapabilities = {
|
||||
com.apple.Push = {
|
||||
enabled = 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
@ -152,7 +226,6 @@
|
||||
files = (
|
||||
0661A54D204FDA4100965E4E /* LaunchScreen.storyboard in Resources */,
|
||||
0661A54A204FDA4100965E4E /* Assets.xcassets in Resources */,
|
||||
0661A548204FDA4100965E4E /* Main.storyboard in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -200,26 +273,36 @@
|
||||
inputPaths = (
|
||||
"${SRCROOT}/Pods/Target Support Files/Pods-Bark/Pods-Bark-frameworks.sh",
|
||||
"${BUILT_PRODUCTS_DIR}/Alamofire/Alamofire.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/DefaultsKit/DefaultsKit.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/DeviceKit/DeviceKit.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/FDFullscreenPopGesture/FDFullscreenPopGesture.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/KVOController/KVOController.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/MJRefresh/MJRefresh.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/Material/Material.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/Motion/Motion.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/Moya/Moya.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/ObjectMapper/ObjectMapper.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/Result/Result.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/RxSwift/RxSwift.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/SVProgressHUD/SVProgressHUD.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/SwiftyJSON/SwiftyJSON.framework",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Alamofire.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DefaultsKit.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DeviceKit.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FDFullscreenPopGesture.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/KVOController.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MJRefresh.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Material.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Motion.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Moya.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ObjectMapper.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Result.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxSwift.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SVProgressHUD.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SnapKit.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyJSON.framework",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
@ -233,7 +316,21 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0661A545204FDA4100965E4E /* ViewController.swift in Sources */,
|
||||
0603706920E1F89500F4CA05 /* PreviewCardCell.swift in Sources */,
|
||||
0637FA8C20E0D7A700E80174 /* BaseViewController.swift in Sources */,
|
||||
0603706D20E23EC000F4CA05 /* BarkSFSafariViewController.swift in Sources */,
|
||||
0637FA7820E0926D00E80174 /* BarkTargetType.swift in Sources */,
|
||||
0637FA7E20E0969800E80174 /* Client.swift in Sources */,
|
||||
0661A545204FDA4100965E4E /* HomeViewController.swift in Sources */,
|
||||
0637FA8620E0AB6600E80174 /* UIColor+Extension.swift in Sources */,
|
||||
0637FA8A20E0D58800E80174 /* NewServerViewController.swift in Sources */,
|
||||
0637FA8220E09C4B00E80174 /* BarkNavigationController.swift in Sources */,
|
||||
0637FA7A20E092B300E80174 /* Observable+Extension.swift in Sources */,
|
||||
0604F7DF20620D4900B32F09 /* ServerManager.swift in Sources */,
|
||||
0603706720E1E31600F4CA05 /* Defines.swift in Sources */,
|
||||
0637FA7C20E0930E00E80174 /* BarkApi.swift in Sources */,
|
||||
0637FA8020E0981E00E80174 /* BarkSettings.swift in Sources */,
|
||||
0603706B20E20A7C00F4CA05 /* String+Extension.swift in Sources */,
|
||||
0661A543204FDA4100965E4E /* AppDelegate.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@ -241,14 +338,6 @@
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
0661A546204FDA4100965E4E /* Main.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
0661A547204FDA4100965E4E /* Base */,
|
||||
);
|
||||
name = Main.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0661A54B204FDA4100965E4E /* LaunchScreen.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
@ -274,6 +363,7 @@
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
@ -281,6 +371,7 @@
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
@ -331,6 +422,7 @@
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
@ -338,6 +430,7 @@
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
@ -372,11 +465,13 @@
|
||||
baseConfigurationReference = 87D1222A4C6E7283974A44C6 /* Pods-Bark.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = Bark/Bark.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = 5U8LBRXG3A;
|
||||
INFOPLIST_FILE = Bark/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = me.fin.Bark;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = me.fin.bark;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 4.0;
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
@ -388,11 +483,13 @@
|
||||
baseConfigurationReference = 1CC985CE300A858FF65E166A /* Pods-Bark.release.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = Bark/Bark.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = 5U8LBRXG3A;
|
||||
INFOPLIST_FILE = Bark/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = me.fin.Bark;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = me.fin.bark;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 4.0;
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
|
||||
@ -7,7 +7,8 @@
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
import Material
|
||||
import UserNotifications
|
||||
@UIApplicationMain
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
||||
@ -15,10 +16,37 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
||||
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
|
||||
// Override point for customization after application launch.
|
||||
|
||||
self.window = UIWindow(frame: UIScreen.main.bounds)
|
||||
self.window?.backgroundColor = Color.grey.lighten5
|
||||
self.window?.rootViewController = BarkSnackbarController(rootViewController: BarkNavigationController(rootViewController: HomeViewController()))
|
||||
self.window?.makeKeyAndVisible()
|
||||
|
||||
UNUserNotificationCenter.current().getNotificationSettings { (settings) in
|
||||
dispatch_sync_safely_main_queue {
|
||||
if settings.authorizationStatus == .authorized {
|
||||
Client.shared.registerForRemoteNotifications()
|
||||
}
|
||||
else{
|
||||
Client.shared.state = .unRegister
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
|
||||
print(error)
|
||||
}
|
||||
|
||||
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
|
||||
let deviceTokenString = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
|
||||
Settings[.deviceToken] = deviceTokenString
|
||||
|
||||
//注册设备
|
||||
Client.shared.bindDeviceToken()
|
||||
}
|
||||
|
||||
func applicationWillResignActive(_ application: UIApplication) {
|
||||
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
|
||||
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
|
||||
@ -30,7 +58,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
}
|
||||
|
||||
func applicationWillEnterForeground(_ application: UIApplication) {
|
||||
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
|
||||
if Client.shared.state == .serverError{
|
||||
Client.shared.bindDeviceToken()
|
||||
}
|
||||
}
|
||||
|
||||
func applicationDidBecomeActive(_ application: UIApplication) {
|
||||
|
||||
6
Bark/Assets.xcassets/Contents.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
26
Bark/Assets.xcassets/baseline_file_copy_white_24pt.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "baseline_file_copy_white_24pt_1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "baseline_file_copy_white_24pt_2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "baseline_file_copy_white_24pt_3x.png",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"properties" : {
|
||||
"template-rendering-intent" : "template"
|
||||
}
|
||||
}
|
||||
BIN
Bark/Assets.xcassets/baseline_file_copy_white_24pt.imageset/baseline_file_copy_white_24pt_1x.png
vendored
Normal file
|
After Width: | Height: | Size: 169 B |
BIN
Bark/Assets.xcassets/baseline_file_copy_white_24pt.imageset/baseline_file_copy_white_24pt_2x.png
vendored
Normal file
|
After Width: | Height: | Size: 240 B |
BIN
Bark/Assets.xcassets/baseline_file_copy_white_24pt.imageset/baseline_file_copy_white_24pt_3x.png
vendored
Normal file
|
After Width: | Height: | Size: 321 B |
26
Bark/Assets.xcassets/baseline_http_black_24pt.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "baseline_http_black_24pt_1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "baseline_http_black_24pt_2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "baseline_http_black_24pt_3x.png",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"properties" : {
|
||||
"template-rendering-intent" : "template"
|
||||
}
|
||||
}
|
||||
BIN
Bark/Assets.xcassets/baseline_http_black_24pt.imageset/baseline_http_black_24pt_1x.png
vendored
Normal file
|
After Width: | Height: | Size: 149 B |
BIN
Bark/Assets.xcassets/baseline_http_black_24pt.imageset/baseline_http_black_24pt_2x.png
vendored
Normal file
|
After Width: | Height: | Size: 154 B |
BIN
Bark/Assets.xcassets/baseline_http_black_24pt.imageset/baseline_http_black_24pt_3x.png
vendored
Normal file
|
After Width: | Height: | Size: 218 B |
26
Bark/Assets.xcassets/baseline_https_black_24pt.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "baseline_https_black_24pt_1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "baseline_https_black_24pt_2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "baseline_https_black_24pt_3x.png",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"properties" : {
|
||||
"template-rendering-intent" : "template"
|
||||
}
|
||||
}
|
||||
BIN
Bark/Assets.xcassets/baseline_https_black_24pt.imageset/baseline_https_black_24pt_1x.png
vendored
Normal file
|
After Width: | Height: | Size: 204 B |
BIN
Bark/Assets.xcassets/baseline_https_black_24pt.imageset/baseline_https_black_24pt_2x.png
vendored
Normal file
|
After Width: | Height: | Size: 355 B |
BIN
Bark/Assets.xcassets/baseline_https_black_24pt.imageset/baseline_https_black_24pt_3x.png
vendored
Normal file
|
After Width: | Height: | Size: 483 B |
8
Bark/Bark.entitlements
Normal 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>aps-environment</key>
|
||||
<string>development</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@ -1,24 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" systemVersion="17A277" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="tne-QT-ifu">
|
||||
<objects>
|
||||
<viewController id="BYZ-38-t0r" customClass="ViewController" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
@ -4,6 +4,8 @@
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Bark</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
@ -15,15 +17,18 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<string>1.0.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
@ -31,8 +36,6 @@
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
@ -41,5 +44,7 @@
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@ -1,25 +0,0 @@
|
||||
//
|
||||
// ViewController.swift
|
||||
// Bark
|
||||
//
|
||||
// Created by huangfeng on 2018/3/7.
|
||||
// Copyright © 2018年 Fin. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class ViewController: UIViewController {
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
// Do any additional setup after loading the view, typically from a nib.
|
||||
}
|
||||
|
||||
override func didReceiveMemoryWarning() {
|
||||
super.didReceiveMemoryWarning()
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
42
Controller/BarkNavigationController.swift
Normal file
@ -0,0 +1,42 @@
|
||||
//
|
||||
// BarkNavigationController.swift
|
||||
// Bark
|
||||
//
|
||||
// Created by huangfeng on 2018/6/25.
|
||||
// Copyright © 2018 Fin. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Material
|
||||
|
||||
class BarkNavigationController: NavigationController{
|
||||
override func prepare() {
|
||||
super.prepare()
|
||||
isMotionEnabled = true
|
||||
motionNavigationTransitionType = .autoReverse(presenting: .fade)
|
||||
|
||||
guard let v = navigationBar as? NavigationBar else {
|
||||
return
|
||||
}
|
||||
|
||||
v.depthPreset = .none
|
||||
v.dividerColor = Color.grey.lighten2
|
||||
|
||||
navigationBar.backgroundColor = Color.blue.darken2
|
||||
|
||||
statusBarStyle = .lightContent
|
||||
|
||||
}
|
||||
|
||||
override var childViewControllerForStatusBarStyle: UIViewController?{
|
||||
get {
|
||||
return self.topViewController
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BarkSnackbarController: SnackbarController {
|
||||
override var childViewControllerForStatusBarStyle: UIViewController?{
|
||||
return self.rootViewController
|
||||
}
|
||||
}
|
||||
30
Controller/BarkSFSafariViewController.swift
Normal file
@ -0,0 +1,30 @@
|
||||
//
|
||||
// BarkSFSafariViewController.swift
|
||||
// Bark
|
||||
//
|
||||
// Created by huangfeng on 2018/6/26.
|
||||
// Copyright © 2018 Fin. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import SafariServices
|
||||
class BarkSFSafariViewController: SFSafariViewController {
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
// Do any additional setup after loading the view.
|
||||
}
|
||||
|
||||
override func didReceiveMemoryWarning() {
|
||||
super.didReceiveMemoryWarning()
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
override var preferredStatusBarStyle: UIStatusBarStyle{
|
||||
get {
|
||||
return .default
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
26
Controller/BaseViewController.swift
Normal file
@ -0,0 +1,26 @@
|
||||
//
|
||||
// BaseViewController.swift
|
||||
// Bark
|
||||
//
|
||||
// Created by huangfeng on 2018/6/25.
|
||||
// Copyright © 2018 Fin. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Material
|
||||
class BaseViewController: UIViewController {
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
self.navigationItem.backButton.tintColor = UIColor.white
|
||||
self.view.backgroundColor = Color.grey.lighten5
|
||||
navigationItem.titleLabel.textColor = .white
|
||||
navigationItem.titleLabel.font = UIFont.systemFont(ofSize: 16)
|
||||
}
|
||||
|
||||
override var preferredStatusBarStyle: UIStatusBarStyle{
|
||||
get {
|
||||
return .lightContent
|
||||
}
|
||||
}
|
||||
}
|
||||
160
Controller/HomeViewController.swift
Normal file
@ -0,0 +1,160 @@
|
||||
//
|
||||
// ViewController.swift
|
||||
// Bark
|
||||
//
|
||||
// Created by huangfeng on 2018/3/7.
|
||||
// Copyright © 2018年 Fin. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import UserNotifications
|
||||
import Material
|
||||
class HomeViewController: BaseViewController {
|
||||
|
||||
let newButton: IconButton = {
|
||||
let btn = IconButton(image: Icon.add, tintColor: .white)
|
||||
btn.pulseColor = .white
|
||||
return btn
|
||||
}()
|
||||
|
||||
let startButton = FABButton(title: "注册设备")
|
||||
|
||||
let statusButton = IconButton(image: UIImage(named: "baseline_https_black_24pt"), tintColor: .white)
|
||||
|
||||
let tableView :UITableView = {
|
||||
let tableView = UITableView()
|
||||
tableView.separatorStyle = .none
|
||||
tableView.backgroundColor = Color.grey.lighten3
|
||||
tableView.register(PreviewCardCell.self, forCellReuseIdentifier: "\(PreviewCardCell.self)")
|
||||
return tableView
|
||||
}()
|
||||
|
||||
var dataSource:[PreviewModel] = {
|
||||
return [
|
||||
PreviewModel(
|
||||
body:"这里改成你自己的推送内容",
|
||||
notice: "点击右上角按钮可以复制测试URL、预览推送效果\nSafari有缓存,没收到推送时请刷新页面"),
|
||||
PreviewModel(
|
||||
title: "推送标题",
|
||||
body:"这里改成你自己的推送内容",
|
||||
notice: "推送标题的字号比推送内容粗一点")
|
||||
]
|
||||
}()
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
self.view.backgroundColor = Color.grey.lighten3
|
||||
|
||||
navigationItem.titleLabel.textColor = .white
|
||||
navigationItem.titleLabel.textAlignment = .left
|
||||
navigationItem.detailLabel.textAlignment = .left
|
||||
navigationItem.detailLabel.textColor = .white
|
||||
|
||||
newButton.addTarget(self, action: #selector(new), for: .touchUpInside)
|
||||
navigationItem.rightViews = [newButton]
|
||||
navigationItem.leftViews = [statusButton]
|
||||
|
||||
self.view.addSubview(self.tableView)
|
||||
self.tableView.snp.makeConstraints { (make ) in
|
||||
make.top.right.bottom.left.equalToSuperview()
|
||||
}
|
||||
self.tableView.delegate = self
|
||||
self.tableView.dataSource = self
|
||||
|
||||
UNUserNotificationCenter.current().getNotificationSettings { (settings) in
|
||||
if settings.authorizationStatus != .authorized {
|
||||
dispatch_sync_safely_main_queue {
|
||||
self.startButton.transition([ .scale(0.75) , .opacity(0)] )
|
||||
self.startButton.addTarget(self, action: #selector(self.start), for: .touchUpInside)
|
||||
self.view.addSubview(self.startButton)
|
||||
self.startButton.snp.makeConstraints { (make) in
|
||||
make.width.height.equalTo(150)
|
||||
make.centerX.equalToSuperview()
|
||||
make.top.equalTo(150)
|
||||
}
|
||||
self.tableView.isHidden = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(refreshState), name: Notification.Name(rawValue: "ClientStateChangeds"), object: nil)
|
||||
}
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
if let url = URL(string: ServerManager.shared.currentAddress) {
|
||||
navigationItem.titleLabel.text = url.host
|
||||
refreshState()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension HomeViewController : UITableViewDataSource, UITableViewDelegate {
|
||||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return dataSource.count
|
||||
}
|
||||
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
|
||||
return 200
|
||||
}
|
||||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let cell = self.tableView.dequeueReusableCell(withIdentifier: "\(PreviewCardCell.self)", for: indexPath) as! PreviewCardCell
|
||||
cell.bind(model: dataSource[indexPath.row])
|
||||
cell.copyHandler = {[weak self] in
|
||||
self?.showSnackbar(text: "复制成功")
|
||||
}
|
||||
return cell
|
||||
}
|
||||
}
|
||||
|
||||
extension HomeViewController {
|
||||
@objc func new(){
|
||||
self.navigationController?.pushViewController(NewServerViewController(), animated: true)
|
||||
}
|
||||
|
||||
@objc func start(){
|
||||
startButton.titleColor = Color.grey.base
|
||||
startButton.isEnabled = false
|
||||
|
||||
let center = UNUserNotificationCenter.current()
|
||||
center.requestAuthorization(options: [.alert , .sound , .badge], completionHandler: {(_ granted: Bool, _ error: Error?) -> Void in
|
||||
|
||||
// 兼容 iOS 12 BUG,不这样写会UI卡死
|
||||
DispatchQueue.global(qos: .default).async {
|
||||
DispatchQueue.main.sync {
|
||||
if granted {
|
||||
UIApplication.shared.registerForRemoteNotifications()
|
||||
if self.tableView.isHidden{
|
||||
self.tableView.isHidden = false
|
||||
}
|
||||
self.startButton.removeFromSuperview()
|
||||
}
|
||||
else{
|
||||
self.showSnackbar(text: "绑定设备需要推送。请打开推送后重试")
|
||||
self.startButton.titleColor = Color.blue.base
|
||||
self.startButton.isEnabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
@objc func refreshState() {
|
||||
switch Client.shared.state {
|
||||
case .ok:
|
||||
if let url = URL(string: ServerManager.shared.currentAddress) {
|
||||
if url.scheme?.lowercased() == "https" {
|
||||
navigationItem.detailLabel.text = "HTTPS安全连接"
|
||||
statusButton.image = UIImage(named: "baseline_https_black_24pt")
|
||||
}
|
||||
else {
|
||||
navigationItem.detailLabel.text = "连接不安全,请使用HTTPS安全连接"
|
||||
statusButton.image = UIImage(named: "baseline_http_black_24pt")
|
||||
}
|
||||
self.tableView.reloadData()
|
||||
}
|
||||
case .unRegister:
|
||||
navigationItem.detailLabel.text = "设备未注册,不能使用推送服务"
|
||||
case .serverError:
|
||||
navigationItem.detailLabel.text = "服务器错误,不能使用推送服务"
|
||||
}
|
||||
}
|
||||
}
|
||||
83
Controller/NewServerViewController.swift
Normal file
@ -0,0 +1,83 @@
|
||||
//
|
||||
// NewServerViewController.swift
|
||||
// Bark
|
||||
//
|
||||
// Created by huangfeng on 2018/6/25.
|
||||
// Copyright © 2018 Fin. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Material
|
||||
import SnapKit
|
||||
import SafariServices
|
||||
class NewServerViewController: BaseViewController {
|
||||
|
||||
let addressTextField : TextField = {
|
||||
let textField = TextField()
|
||||
textField.keyboardType = .URL
|
||||
textField.placeholder = "服务器地址"
|
||||
textField.detail = "输入服务器地址,例如: https://api.day.app"
|
||||
textField.transition([ .scale(0.85) , .opacity(0)] )
|
||||
textField.detailLabel.transition([ .scale(0.85) , .opacity(0)] )
|
||||
return textField
|
||||
}()
|
||||
|
||||
let noticeLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.text = "查看服务端部署教程"
|
||||
label.textColor = Color.blue.base
|
||||
label.font = UIFont.systemFont(ofSize: 12)
|
||||
label.transition([ .scale(0.85) , .opacity(0), .translate(x: 50)] )
|
||||
return label
|
||||
}()
|
||||
|
||||
let doneButton = IconButton(image: Icon.check, tintColor: .white)
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
navigationItem.titleLabel.text = "添加私有服务器"
|
||||
|
||||
doneButton.addTarget(self, action: #selector(done), for: .touchUpInside)
|
||||
navigationItem.rightViews = [doneButton]
|
||||
|
||||
self.view.layout(addressTextField).top(40).left(10).right(10)
|
||||
|
||||
self.view.addSubview(noticeLabel)
|
||||
noticeLabel.snp.makeConstraints { (make) in
|
||||
make.top.equalTo(self.addressTextField.snp.bottom).offset(40)
|
||||
make.left.equalTo(self.addressTextField)
|
||||
}
|
||||
noticeLabel.isUserInteractionEnabled = true
|
||||
noticeLabel.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(noticeClick)))
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
_ = self.addressTextField.becomeFirstResponder()
|
||||
addressTextField.text = "https://"
|
||||
}
|
||||
|
||||
@objc func done(){
|
||||
self.addressTextField.resignFirstResponder()
|
||||
if let text = addressTextField.text, let _ = URL(string: text) {
|
||||
_ = BarkApi.provider.request(.ping(baseURL: text))
|
||||
.filterResponseError()
|
||||
.subscribe(onNext: {[weak self] (_) in
|
||||
self?.navigationController?.popViewController(animated: true)
|
||||
ServerManager.shared.currentAddress = text
|
||||
self?.showSnackbar(text: "修改成功!")
|
||||
Client.shared.bindDeviceToken()
|
||||
|
||||
}, onError: {[weak self] (error) in
|
||||
self?.showSnackbar(text: "填写的服务器无效,请重试!\(error.localizedDescription)")
|
||||
})
|
||||
}
|
||||
else{
|
||||
self.showSnackbar(text: "输入的URL好像不对劲!")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@objc func noticeClick(){
|
||||
self.navigationController?.present(BarkSFSafariViewController(url: URL(string: "https://day.app/2018/06/bark-server-document/")!), animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
46
Model/BarkApi.swift
Normal file
@ -0,0 +1,46 @@
|
||||
//
|
||||
// BarkApi.swift
|
||||
// Bark
|
||||
//
|
||||
// Created by huangfeng on 2018/6/25.
|
||||
// Copyright © 2018 Fin. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
enum BarkApi {
|
||||
case ping(baseURL:String?)
|
||||
case register(key:String? , devicetoken:String) //注册设备
|
||||
}
|
||||
|
||||
extension BarkApi: BarkTargetType {
|
||||
var baseURL: URL {
|
||||
if case let .ping(urlStr) = self, let url = URL(string: urlStr ?? "") {
|
||||
return url
|
||||
}
|
||||
return URL(string: ServerManager.shared.currentAddress)!
|
||||
}
|
||||
var parameters: [String : Any]? {
|
||||
switch self {
|
||||
case let .register(key, devicetoken):
|
||||
var params = ["devicetoken":devicetoken]
|
||||
if let key = key {
|
||||
params["key"] = key
|
||||
}
|
||||
return params
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
var path: String {
|
||||
switch self {
|
||||
case .ping:
|
||||
return "/ping"
|
||||
case .register:
|
||||
return "/register"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
77
Model/BarkSettings.swift
Normal file
@ -0,0 +1,77 @@
|
||||
//
|
||||
// BarkSettings.swift
|
||||
// Bark
|
||||
//
|
||||
// Created by huangfeng on 2018/6/25.
|
||||
// Copyright © 2018 Fin. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import DefaultsKit
|
||||
|
||||
enum BarkSettingKey:String {
|
||||
/// 存放key
|
||||
case key = "me.fin.bark.key"
|
||||
case servers = "me.fin.bark.servers"
|
||||
case currentServer = "me.fin.bark.servers.current"
|
||||
|
||||
case deviceToken = "me.fin.bark.deviceToken"
|
||||
}
|
||||
|
||||
class BarkSettings{
|
||||
static let shared = BarkSettings()
|
||||
private init(){
|
||||
|
||||
}
|
||||
|
||||
subscript(key:String) -> String? {
|
||||
get {
|
||||
let storeKey = Key<String>(key)
|
||||
return Defaults.shared.get(for: storeKey)
|
||||
}
|
||||
set {
|
||||
let storeKey = Key<String>(key)
|
||||
if let value = newValue {
|
||||
Defaults.shared.set(value, for: storeKey)
|
||||
}
|
||||
else {
|
||||
Defaults.shared.clear(storeKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
subscript(key:BarkSettingKey) -> String? {
|
||||
get {
|
||||
return self[key.rawValue]
|
||||
}
|
||||
set {
|
||||
self[key.rawValue] = newValue
|
||||
}
|
||||
}
|
||||
|
||||
subscript<T : Codable>(key:String) -> T? {
|
||||
get {
|
||||
let storeKey = Key<T>(key)
|
||||
return Defaults.shared.get(for: storeKey)
|
||||
}
|
||||
set {
|
||||
let storeKey = Key<T>(key)
|
||||
if let value = newValue {
|
||||
Defaults.shared.set(value, for: storeKey)
|
||||
}
|
||||
else {
|
||||
Defaults.shared.clear(storeKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
subscript<T : Codable>(key:BarkSettingKey) -> T? {
|
||||
get {
|
||||
return self[key.rawValue]
|
||||
}
|
||||
set {
|
||||
self[key.rawValue] = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let Settings = BarkSettings.shared
|
||||
128
Model/BarkTargetType.swift
Normal file
@ -0,0 +1,128 @@
|
||||
//
|
||||
// BarkTargetType.swift
|
||||
// Bark
|
||||
//
|
||||
// Created by huangfeng on 2018/6/25.
|
||||
// Copyright © 2018 Fin. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Moya
|
||||
import RxSwift
|
||||
import Result
|
||||
|
||||
//保存全局Providers
|
||||
fileprivate var retainProviders:[String: Any] = [:]
|
||||
|
||||
protocol BarkTargetType: TargetType {
|
||||
var parameters: [String: Any]? { get }
|
||||
}
|
||||
|
||||
extension BarkTargetType {
|
||||
var headers: [String : String]? {
|
||||
return nil
|
||||
}
|
||||
var baseURL: URL {
|
||||
return URL(string: ServerManager.shared.currentAddress)!
|
||||
}
|
||||
|
||||
var method: Moya.Method {
|
||||
return .get
|
||||
}
|
||||
|
||||
var parameterEncoding: ParameterEncoding {
|
||||
return URLEncoding.default
|
||||
}
|
||||
|
||||
var sampleData: Data {
|
||||
return Data()
|
||||
}
|
||||
|
||||
var task: Task {
|
||||
return requestTaskWithParameters
|
||||
}
|
||||
|
||||
var requestTaskWithParameters: Task {
|
||||
get {
|
||||
//默认参数
|
||||
var defaultParameters:[String:Any] = [:]
|
||||
//协议参数
|
||||
if let parameters = self.parameters {
|
||||
for (key, value) in parameters {
|
||||
defaultParameters[key] = value
|
||||
}
|
||||
}
|
||||
return Task.requestParameters(parameters: defaultParameters, encoding: parameterEncoding)
|
||||
}
|
||||
}
|
||||
|
||||
static var networkActivityPlugin: PluginType {
|
||||
return NetworkActivityPlugin { (change, type) in
|
||||
switch change {
|
||||
case .began:
|
||||
UIApplication.shared.isNetworkActivityIndicatorVisible = true
|
||||
case .ended:
|
||||
UIApplication.shared.isNetworkActivityIndicatorVisible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 实现此协议的类,将自动获得用该类实例化的 provider 对象
|
||||
static var provider: RxSwift.Reactive< MoyaProvider<Self> > {
|
||||
let key = "\(Self.self)"
|
||||
if let provider = retainProviders[key] as? RxSwift.Reactive< MoyaProvider<Self> > {
|
||||
return provider
|
||||
}
|
||||
let provider = Self.weakProvider
|
||||
retainProviders[key] = provider
|
||||
return provider
|
||||
}
|
||||
|
||||
/// 不被全局持有的 Provider ,使用时,需要持有它,否则将立即释放,请求随即终止
|
||||
static var weakProvider: RxSwift.Reactive< MoyaProvider<Self> > {
|
||||
var plugins:[PluginType] = [networkActivityPlugin]
|
||||
#if DEBUG
|
||||
plugins.append(LogPlugin())
|
||||
#endif
|
||||
let provider = MoyaProvider<Self>(plugins:plugins)
|
||||
return provider.rx
|
||||
}
|
||||
}
|
||||
|
||||
extension RxSwift.Reactive where Base: MoyaProviderType {
|
||||
public func request(_ token: Base.Target, callbackQueue: DispatchQueue? = nil) -> Observable<Response> {
|
||||
return Single.create { [weak base] single in
|
||||
let cancellableToken = base?.request(token, callbackQueue: callbackQueue, progress: nil) { result in
|
||||
switch result {
|
||||
case let .success(response):
|
||||
single(.success(response))
|
||||
case let .failure(error):
|
||||
single(.error(error))
|
||||
}
|
||||
}
|
||||
|
||||
return Disposables.create {
|
||||
cancellableToken?.cancel()
|
||||
}
|
||||
}.asObservable()
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate class LogPlugin: PluginType{
|
||||
func willSend(_ request: RequestType, target: TargetType) {
|
||||
print("\n-------------------\n准备请求: \(target.path)")
|
||||
print("请求方式: \(target.method.rawValue)")
|
||||
if let params = (target as? BarkTargetType)?.parameters {
|
||||
print(params)
|
||||
}
|
||||
print("\n")
|
||||
|
||||
}
|
||||
func didReceive(_ result: Result<Response, MoyaError>, target: TargetType) {
|
||||
print("\n-------------------\n请求结束: \(target.path)")
|
||||
if let data = result.value?.data, let resutl = String(data: data, encoding: String.Encoding.utf8) {
|
||||
print("请求结果: \(resutl)")
|
||||
}
|
||||
print("\n")
|
||||
}
|
||||
}
|
||||
84
Model/Client.swift
Normal file
@ -0,0 +1,84 @@
|
||||
//
|
||||
// Client.swift
|
||||
// Bark
|
||||
//
|
||||
// Created by huangfeng on 2018/6/25.
|
||||
// Copyright © 2018 Fin. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import UserNotifications
|
||||
class Client: NSObject {
|
||||
static let shared = Client()
|
||||
private override init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
let appVersion:String = {
|
||||
var version = "0.0.0"
|
||||
if let infoDict = Bundle.main.infoDictionary {
|
||||
if let appVersion = infoDict["CFBundleVersion"] as? String {
|
||||
version = appVersion
|
||||
}
|
||||
}
|
||||
return version
|
||||
}()
|
||||
|
||||
private var _key:String?
|
||||
var key:String? {
|
||||
get {
|
||||
if _key == nil, let aKey = Settings[.key]{
|
||||
_key = aKey
|
||||
}
|
||||
return _key
|
||||
}
|
||||
set {
|
||||
_key = newValue
|
||||
Settings[.key] = newValue
|
||||
}
|
||||
}
|
||||
|
||||
enum ClienState {
|
||||
case ok
|
||||
case unRegister
|
||||
case serverError
|
||||
}
|
||||
|
||||
var state = ClienState.ok {
|
||||
didSet{
|
||||
NotificationCenter.default.post(name: Notification.Name(rawValue: "ClientStateChangeds"), object: nil)
|
||||
}
|
||||
}
|
||||
|
||||
func bindDeviceToken(){
|
||||
if let token = Settings[.deviceToken] , token.count > 0{
|
||||
_ = BarkApi.provider.request(.register(key: key, devicetoken: token)).filterResponseError().subscribe(onNext: { (json) in
|
||||
if let key = json["data","key"].rawString() {
|
||||
Client.shared.key = key
|
||||
self.state = .ok
|
||||
}
|
||||
else{
|
||||
self.state = .serverError
|
||||
}
|
||||
}, onError: { (error) in
|
||||
self.state = .serverError
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func registerForRemoteNotifications() {
|
||||
let center = UNUserNotificationCenter.current()
|
||||
center.requestAuthorization(options: [.alert , .sound , .badge], completionHandler: {(_ granted: Bool, _ error: Error?) -> Void in
|
||||
if granted {
|
||||
DispatchQueue.global(qos: .default).async {
|
||||
DispatchQueue.main.sync {
|
||||
UIApplication.shared.registerForRemoteNotifications()
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
print("没有打开推送")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
28
Model/Defines.swift
Normal file
@ -0,0 +1,28 @@
|
||||
//
|
||||
// Defines.swift
|
||||
// Bark
|
||||
//
|
||||
// Created by huangfeng on 2018/6/26.
|
||||
// Copyright © 2018 Fin. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
/// 将代码安全的运行在主线程
|
||||
func dispatch_sync_safely_main_queue(_ block: ()->()) {
|
||||
if Thread.isMainThread {
|
||||
block()
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
block()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension UIViewController {
|
||||
func showSnackbar(text:String) {
|
||||
self.snackbarController?.snackbar.text = text
|
||||
self.snackbarController?.animate(snackbar: .visible)
|
||||
self.snackbarController?.animate(snackbar: .hidden, delay: 3)
|
||||
}
|
||||
}
|
||||
125
Model/Observable+Extension.swift
Normal file
@ -0,0 +1,125 @@
|
||||
//
|
||||
// Observable+Extension.swift
|
||||
// Bark
|
||||
//
|
||||
// Created by huangfeng on 2018/6/25.
|
||||
// Copyright © 2018 Fin. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
import UIKit
|
||||
import RxSwift
|
||||
import ObjectMapper
|
||||
import SwiftyJSON
|
||||
import Moya
|
||||
|
||||
public enum ApiError : Swift.Error {
|
||||
case Error(info: String)
|
||||
case AccountBanned(info: String)
|
||||
}
|
||||
|
||||
extension Swift.Error {
|
||||
func rawString() -> String {
|
||||
guard let err = self as? ApiError else {
|
||||
return self.localizedDescription
|
||||
}
|
||||
switch err {
|
||||
case let .Error(info):
|
||||
return info
|
||||
case let .AccountBanned(info):
|
||||
return info
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Observable where Element: Moya.Response {
|
||||
/// 过滤 HTTP 错误,例如超时,请求失败等
|
||||
func filterHttpError() -> Observable<Element> {
|
||||
return filter{ response in
|
||||
if (200...209) ~= response.statusCode {
|
||||
return true
|
||||
}
|
||||
print("网络错误")
|
||||
throw ApiError.Error(info: "网络错误")
|
||||
}
|
||||
}
|
||||
|
||||
/// 过滤逻辑错误,例如协议里返回 错误CODE
|
||||
func filterResponseError() -> Observable<JSON> {
|
||||
return filterHttpError().map({ (response) -> JSON in
|
||||
|
||||
let json = try JSON(data: response.data)
|
||||
var code = 400
|
||||
var msg:String?
|
||||
if let codeStr = json["code"].rawString(), let c = Int(codeStr) {
|
||||
code = c
|
||||
}
|
||||
if json["message"].exists() {
|
||||
msg = json["message"].rawString()!
|
||||
}
|
||||
if (code == 200){
|
||||
return json
|
||||
}
|
||||
|
||||
switch code {
|
||||
default: throw ApiError.Error(info: msg ?? "未知错误")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// 将Response 转换成 JSON Model
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - typeName: 要转换的Model Class
|
||||
/// - dataPath: 从哪个节点开始转换,例如 ["data","links"]
|
||||
func mapResponseToObj<T: Mappable>(_ typeName: T.Type , dataPath:[String] = ["data"] ) -> Observable<T> {
|
||||
return filterResponseError().map{ json in
|
||||
var rootJson = json
|
||||
if dataPath.count > 0{
|
||||
rootJson = rootJson[dataPath]
|
||||
}
|
||||
if let model: T = self.resultFromJSON(json: rootJson) {
|
||||
return model
|
||||
}
|
||||
else{
|
||||
throw ApiError.Error(info: "json 转换失败")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 将Response 转换成 JSON Model Array
|
||||
func mapResponseToObjArray<T: Mappable>(_ type: T.Type, dataPath:[String] = ["data"] ) -> Observable<[T]> {
|
||||
return filterResponseError().map{ json in
|
||||
var rootJson = json;
|
||||
if dataPath.count > 0{
|
||||
rootJson = rootJson[dataPath]
|
||||
}
|
||||
var result = [T]()
|
||||
guard let jsonArray = rootJson.array else{
|
||||
return result
|
||||
}
|
||||
|
||||
for json in jsonArray{
|
||||
if let jsonModel: T = self.resultFromJSON(json: json) {
|
||||
result.append(jsonModel)
|
||||
}
|
||||
else{
|
||||
throw ApiError.Error(info: "json 转换失败")
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
private func resultFromJSON<T: Mappable>(jsonString:String) -> T? {
|
||||
return T(JSONString: jsonString)
|
||||
}
|
||||
private func resultFromJSON<T: Mappable>(json:JSON) -> T? {
|
||||
if let str = json.rawString(){
|
||||
return resultFromJSON(jsonString: str)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
51
Model/ServerManager.swift
Normal file
@ -0,0 +1,51 @@
|
||||
//
|
||||
// ServerManager.swift
|
||||
// Bark
|
||||
//
|
||||
// Created by huangfeng on 2018/3/21.
|
||||
// Copyright © 2018年 Fin. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
let defaultServer = "https://api.day.app"
|
||||
|
||||
class ServerManager: NSObject {
|
||||
static let shared = ServerManager()
|
||||
private override init() {
|
||||
if let servers:Set<String> = Settings[.servers] {
|
||||
self.servers = servers
|
||||
}
|
||||
|
||||
if let address = Settings[.currentServer] {
|
||||
self.currentAddress = address
|
||||
}
|
||||
else{
|
||||
self.currentAddress = self.servers.first ?? defaultServer
|
||||
}
|
||||
super.init()
|
||||
}
|
||||
|
||||
var servers:Set<String> = [defaultServer]
|
||||
var currentAddress:String {
|
||||
didSet{
|
||||
Settings[.currentServer] = currentAddress
|
||||
}
|
||||
}
|
||||
|
||||
func addServer(server:String){
|
||||
self.servers.insert(server)
|
||||
Settings[.servers] = self.servers
|
||||
}
|
||||
func removeServer(server:String){
|
||||
self.servers.remove(server)
|
||||
if self.servers.count <= 0 {
|
||||
self.servers.insert(defaultServer)
|
||||
}
|
||||
Settings[.servers] = self.servers
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
}
|
||||
23
Model/String+Extension.swift
Normal file
@ -0,0 +1,23 @@
|
||||
//
|
||||
// String+Extension.swift
|
||||
// Bark
|
||||
//
|
||||
// Created by huangfeng on 2018/6/26.
|
||||
// Copyright © 2018 Fin. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
extension String {
|
||||
//将原始的url编码为合法的url
|
||||
func urlEncoded() -> String {
|
||||
let encodeUrlString = self.addingPercentEncoding(withAllowedCharacters:
|
||||
.urlQueryAllowed)
|
||||
return encodeUrlString ?? ""
|
||||
}
|
||||
|
||||
//将编码后的url转换回原始的url
|
||||
func urlDecoded() -> String {
|
||||
return self.removingPercentEncoding ?? ""
|
||||
}
|
||||
}
|
||||
29
Model/UIColor+Extension.swift
Normal file
@ -0,0 +1,29 @@
|
||||
//
|
||||
// UIColor+Extension.swift
|
||||
// Bark
|
||||
//
|
||||
// Created by huangfeng on 2018/6/25.
|
||||
// Copyright © 2018 Fin. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
extension UIColor {
|
||||
convenience public init(r255:CGFloat, g255:CGFloat, b255:CGFloat, a255:CGFloat = 255) {
|
||||
self.init(red: r255/255, green: g255/255, blue: b255/255, alpha: a255/255)
|
||||
}
|
||||
class func image(color:UIColor, size:CGSize = CGSize(width: 1, height: 1)) -> UIImage{
|
||||
UIGraphicsBeginImageContext(size)
|
||||
let context = UIGraphicsGetCurrentContext()
|
||||
context?.setFillColor(color.cgColor)
|
||||
context?.fill(CGRect(origin: CGPoint.zero, size: size))
|
||||
|
||||
let image = UIGraphicsGetImageFromCurrentImageContext()
|
||||
UIGraphicsEndImageContext()
|
||||
return image! //context应该不会没get到吧~ 所以直接强解了
|
||||
}
|
||||
|
||||
var image: UIImage {
|
||||
return UIColor.image(color: self)
|
||||
}
|
||||
}
|
||||
6
Podfile
@ -3,12 +3,16 @@ inhibit_all_warnings!
|
||||
use_frameworks!
|
||||
|
||||
def pods
|
||||
pod 'SnapKit'
|
||||
pod 'Material'
|
||||
pod 'KVOController'
|
||||
pod 'SVProgressHUD'
|
||||
pod 'MJRefresh'
|
||||
pod 'FDFullscreenPopGesture'
|
||||
pod 'Moya/RxSwift'
|
||||
pod 'ObjectMapper'
|
||||
pod 'SwiftyJSON'
|
||||
pod 'DeviceKit'
|
||||
pod 'DefaultsKit', :git => 'https://github.com/nmdias/DefaultsKit'
|
||||
end
|
||||
|
||||
target 'Bark' do
|
||||
|
||||
54
Podfile.lock
@ -1,38 +1,66 @@
|
||||
PODS:
|
||||
- Alamofire (4.6.0)
|
||||
- DeviceKit (1.5.0)
|
||||
- Alamofire (4.7.2)
|
||||
- DefaultsKit (0.0.9)
|
||||
- DeviceKit (1.7.0)
|
||||
- FDFullscreenPopGesture (1.1)
|
||||
- KVOController (1.2.0)
|
||||
- MJRefresh (3.1.15.3)
|
||||
- Moya/Core (11.0.0):
|
||||
- Material (2.15.0):
|
||||
- Material/Core (= 2.15.0)
|
||||
- Material/Core (2.15.0):
|
||||
- Motion (~> 1.3.0)
|
||||
- Motion (1.3.5):
|
||||
- Motion/Core (= 1.3.5)
|
||||
- Motion/Core (1.3.5)
|
||||
- Moya/Core (11.0.2):
|
||||
- Alamofire (~> 4.1)
|
||||
- Result (~> 3.0)
|
||||
- Moya/RxSwift (11.0.0):
|
||||
- Moya/RxSwift (11.0.2):
|
||||
- Moya/Core
|
||||
- RxSwift (~> 4.0)
|
||||
- ObjectMapper (3.3.0)
|
||||
- Result (3.2.4)
|
||||
- RxSwift (4.1.2)
|
||||
- RxSwift (4.2.0)
|
||||
- SnapKit (4.0.0)
|
||||
- SVProgressHUD (2.2.5)
|
||||
- SwiftyJSON (4.1.0)
|
||||
|
||||
DEPENDENCIES:
|
||||
- DefaultsKit (from `https://github.com/nmdias/DefaultsKit`)
|
||||
- DeviceKit
|
||||
- FDFullscreenPopGesture
|
||||
- KVOController
|
||||
- MJRefresh
|
||||
- Material
|
||||
- Moya/RxSwift
|
||||
- ObjectMapper
|
||||
- SnapKit
|
||||
- SVProgressHUD
|
||||
- SwiftyJSON
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
DefaultsKit:
|
||||
:git: https://github.com/nmdias/DefaultsKit
|
||||
|
||||
CHECKOUT OPTIONS:
|
||||
DefaultsKit:
|
||||
:commit: d0ec9bf0e0aa1b44759122c2faf76eb46e1f847f
|
||||
:git: https://github.com/nmdias/DefaultsKit
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Alamofire: f41a599bd63041760b26d393ec1069d9d7b917f4
|
||||
DeviceKit: 883552d64028056216e913a88f892e7e29678e75
|
||||
Alamofire: e4fa87002c137ba2d8d634d2c51fabcda0d5c223
|
||||
DefaultsKit: e47d11c54a53c66f9e5c65a1992dead90bc7144f
|
||||
DeviceKit: 6a5bdeb103c03757bb94aef1ccb01e08bc8ef4ee
|
||||
FDFullscreenPopGesture: a8a620179e3d9c40e8e00256dcee1c1a27c6d0f0
|
||||
KVOController: d72ace34afea42468329623b3379ab3cd1d286b6
|
||||
MJRefresh: b48380ae2b927b46c4ef000de9adb8dc748e1df7
|
||||
Moya: be29766339783963a70d1279d69c891ab3a1393c
|
||||
Material: 00e32bb5e61b3f749044897b2d93acd8bf33faa4
|
||||
Motion: 9f74d115d7f72bb5380a8e3cde2f8a1fc898ac36
|
||||
Moya: a725035953bc1c0eb1be505ab903984501d82440
|
||||
ObjectMapper: b612bf8c8e99c4dc0bb6013a51f7c27966ed5da9
|
||||
Result: d2d07204ce72856f1fd9130bbe42c35a7b0fea10
|
||||
RxSwift: e49536837d9901277638493ea537394d4b55f570
|
||||
RxSwift: 99e10317ddfcc7fbe01356aafd118fde4a0be104
|
||||
SnapKit: a42d492c16e80209130a3379f73596c3454b7694
|
||||
SVProgressHUD: 1428aafac632c1f86f62aa4243ec12008d7a51d6
|
||||
SwiftyJSON: c29297daf073d2aa016295d5809cdd68045c39b3
|
||||
|
||||
PODFILE CHECKSUM: aff58c4e14741124f994b6d0084c6bf1a2384835
|
||||
PODFILE CHECKSUM: 9fe640283f4a4f35eff4a390df2c42a64be57c18
|
||||
|
||||
COCOAPODS: 1.4.0
|
||||
|
||||
161
View/PreviewCardCell.swift
Normal file
@ -0,0 +1,161 @@
|
||||
//
|
||||
// PreviewCardCell.swift
|
||||
// Bark
|
||||
//
|
||||
// Created by huangfeng on 2018/6/26.
|
||||
// Copyright © 2018 Fin. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Material
|
||||
|
||||
class PreviewModel: NSObject {
|
||||
var title:String?
|
||||
var body:String?
|
||||
var category:String?
|
||||
var notice:String?
|
||||
|
||||
init(title:String? = nil, body:String? = nil, category:String? = nil, notice:String? = nil) {
|
||||
self.title = title
|
||||
self.body = body
|
||||
self.category = category
|
||||
self.notice = notice
|
||||
}
|
||||
}
|
||||
|
||||
class PreviewCardCell: UITableViewCell {
|
||||
|
||||
let previewButton = IconButton(image: Icon.cm.skipForward, tintColor: Color.grey.base)
|
||||
let copyButton = IconButton(image: UIImage(named: "baseline_file_copy_white_24pt"), tintColor: Color.grey.base)
|
||||
let toolbar = Toolbar()
|
||||
|
||||
let noticeLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = RobotoFont.regular(with: 12)
|
||||
label.textColor = Color.grey.base
|
||||
label.numberOfLines = 0
|
||||
return label
|
||||
}()
|
||||
|
||||
let bottomBar = Bar()
|
||||
|
||||
let card = Card()
|
||||
|
||||
var copyHandler: (() -> Void)?
|
||||
|
||||
let contentLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.numberOfLines = 0
|
||||
label.font = RobotoFont.regular(with: 14)
|
||||
return label
|
||||
}()
|
||||
|
||||
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
self.selectionStyle = .none
|
||||
self.backgroundColor = Color.grey.lighten3
|
||||
|
||||
self.transition([ .scale(0.75) , .opacity(0)] )
|
||||
|
||||
self.toolbar.rightViews = [copyButton,previewButton]
|
||||
self.bottomBar.leftViews = [noticeLabel]
|
||||
|
||||
toolbar.titleLabel.font = RobotoFont.regular(with: 14)
|
||||
toolbar.titleLabel.textColor = Color.grey.darken4
|
||||
toolbar.titleLabel.textAlignment = .left
|
||||
|
||||
toolbar.detailLabel.textAlignment = .left
|
||||
toolbar.detailLabel.textColor = Color.grey.darken2
|
||||
|
||||
card.toolbar = toolbar
|
||||
card.toolbarEdgeInsetsPreset = .square3
|
||||
card.toolbarEdgeInsets.bottom = 0
|
||||
card.toolbarEdgeInsets.right = 8
|
||||
|
||||
card.contentView = contentLabel
|
||||
card.contentViewEdgeInsetsPreset = .wideRectangle3
|
||||
|
||||
card.bottomBar = bottomBar
|
||||
card.bottomBarEdgeInsetsPreset = .wideRectangle2
|
||||
|
||||
self.layout(card).horizontally(left: 10, right: 10).top(40)
|
||||
|
||||
previewButton.addTarget(self, action: #selector(preview), for: .touchUpInside)
|
||||
copyButton.addTarget(self, action: #selector(copyURL), for: .touchUpInside)
|
||||
|
||||
//小屏幕兼容
|
||||
if UIScreen.main.bounds.size.width <= 320 {
|
||||
card.contentViewEdgeInsetsPreset = .wideRectangle2
|
||||
card.bottomBarEdgeInsetsPreset = .wideRectangle1
|
||||
toolbar.titleLabel.font = RobotoFont.regular(with: 12)
|
||||
toolbar.detailLabel.font = RobotoFont.regular(with: 10)
|
||||
contentLabel.font = RobotoFont.regular(with: 10)
|
||||
noticeLabel.font = RobotoFont.regular(with: 10)
|
||||
}
|
||||
}
|
||||
|
||||
@objc func copyURL(){
|
||||
if let urlStr = self.contentLabel.text{
|
||||
UIPasteboard.general.string = urlStr
|
||||
copyHandler?()
|
||||
}
|
||||
}
|
||||
@objc func preview(){
|
||||
|
||||
if let urlStr = self.contentLabel.text?.urlEncoded(),
|
||||
let url = URL(string: urlStr){
|
||||
UIApplication.shared.open(url, options: [:], completionHandler: nil)
|
||||
}
|
||||
}
|
||||
|
||||
var previewModel:PreviewModel?
|
||||
func bind(model:PreviewModel) {
|
||||
self.previewModel = model
|
||||
|
||||
var fontSize:CGFloat = 14
|
||||
if UIScreen.main.bounds.size.width <= 320 {
|
||||
fontSize = 11
|
||||
}
|
||||
|
||||
let serverUrl = URL(string: ServerManager.shared.currentAddress)!
|
||||
|
||||
let attrStr = NSMutableAttributedString(string: "")
|
||||
attrStr.append(NSAttributedString(string: serverUrl.absoluteString, attributes: [
|
||||
NSAttributedStringKey.foregroundColor: Color.grey.darken4,
|
||||
NSAttributedStringKey.font : RobotoFont.regular(with: fontSize)
|
||||
]))
|
||||
|
||||
attrStr.append(NSAttributedString(string: "/\(Client.shared.key ?? "")", attributes: [
|
||||
NSAttributedStringKey.foregroundColor: Color.grey.darken3,
|
||||
NSAttributedStringKey.font : RobotoFont.regular(with: fontSize)
|
||||
]))
|
||||
|
||||
if let title = model.title {
|
||||
attrStr.append(NSAttributedString(string: "/\(title)", attributes: [
|
||||
NSAttributedStringKey.foregroundColor: Color.grey.darken1,
|
||||
NSAttributedStringKey.font : RobotoFont.regular(with: fontSize)
|
||||
]))
|
||||
self.toolbar.title = title
|
||||
}
|
||||
if let body = model.body {
|
||||
attrStr.append(NSAttributedString(string: "/\(body)", attributes: [
|
||||
NSAttributedStringKey.foregroundColor: Color.grey.base,
|
||||
NSAttributedStringKey.font : RobotoFont.regular(with: fontSize)
|
||||
]))
|
||||
if model.title == nil {
|
||||
self.toolbar.title = body
|
||||
}
|
||||
else{
|
||||
self.toolbar.detail = body
|
||||
}
|
||||
}
|
||||
self.contentLabel.attributedText = attrStr
|
||||
self.noticeLabel.text = model.notice
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
|
||||
}
|
||||