chengyanfang

init

Showing 97 changed files with 3893 additions and 0 deletions
No preview for this file type
  1 +# Xcode
  2 +#
  3 +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
  4 +
  5 +## Build generated
  6 +build/
  7 +DerivedData/
  8 +Pods/
  9 +Podfile.lock
  10 +fastlane/
  11 +firim/
  12 +Gemfile
  13 +Gemfile.lock
  14 +
  15 +
  16 +## Various settings
  17 +*.pbxuser
  18 +!default.pbxuser
  19 +*.mode1v3
  20 +!default.mode1v3
  21 +*.mode2v3
  22 +!default.mode2v3
  23 +*.perspectivev3
  24 +!default.perspectivev3
  25 +xcuserdata/
  26 +
  27 +## Other
  28 +*.moved-aside
  29 +*.xccheckout
  30 +*.xcscmblueprint
  31 +
  32 +## Obj-C/Swift specific
  33 +*.hmap
  34 +*.ipa
  35 +*.dSYM.zip
  36 +*.dSYM
  37 +
  38 +## Playgrounds
  39 +timeline.xctimeline
  40 +playground.xcworkspace
  41 +
  42 +# Swift Package Manager
  43 +#
  44 +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
  45 +# Packages/
  46 +# Package.pins
  47 +# Package.resolved
  48 +.build/
  49 +
  50 +# CocoaPods
  51 +#
  52 +# We recommend against adding the Pods directory to your .gitignore. However
  53 +# you should judge for yourself, the pros and cons are mentioned at:
  54 +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
  55 +#
  56 +# Pods/
  57 +
  58 +# Carthage
  59 +#
  60 +# Add this line if you want to avoid checking in source code from Carthage dependencies.
  61 +# Carthage/Checkouts
  62 +
  63 +Carthage/Build
  64 +
  65 +# fastlane
  66 +#
  67 +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
  68 +# screenshots whenever they are needed.
  69 +# For more information about the recommended setup visit:
  70 +# https://docs.fastlane.tools/best-practices/source-control/#source-control
  71 +
  72 +fastlane/report.xml
  73 +fastlane/Preview.html
  74 +fastlane/screenshots/**/*.png
  75 +fastlane/test_output
  1 +// !$*UTF8*$!
  2 +{
  3 + archiveVersion = 1;
  4 + classes = {
  5 + };
  6 + objectVersion = 51;
  7 + objects = {
  8 +
  9 +/* Begin PBXBuildFile section */
  10 + 6AF58710F6F4704A0DDB54DA /* BuildFile in Frameworks */ = {isa = PBXBuildFile; };
  11 + 7ECF5CBC25627CCE001B60C2 /* PreviewTransitionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ECF5CA725627CCE001B60C2 /* PreviewTransitionViewController.swift */; };
  12 + 7ECF5CBD25627CCE001B60C2 /* WebviewPreviewViewContoller.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ECF5CA825627CCE001B60C2 /* WebviewPreviewViewContoller.swift */; };
  13 + 7ECF5CBE25627CCE001B60C2 /* FileListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ECF5CA925627CCE001B60C2 /* FileListViewController.swift */; };
  14 + 7ECF5CBF25627CCE001B60C2 /* FileParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ECF5CAA25627CCE001B60C2 /* FileParser.swift */; };
  15 + 7ECF5CC025627CCE001B60C2 /* PreviewManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ECF5CAB25627CCE001B60C2 /* PreviewManager.swift */; };
  16 + 7ECF5CC125627CCE001B60C2 /* FileListSearch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ECF5CAC25627CCE001B60C2 /* FileListSearch.swift */; };
  17 + 7ECF5CC225627CCE001B60C2 /* FBFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ECF5CAD25627CCE001B60C2 /* FBFile.swift */; };
  18 + 7ECF5CC325627CCE001B60C2 /* FileListTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ECF5CAF25627CCE001B60C2 /* FileListTableView.swift */; };
  19 + 7ECF5CC425627CCE001B60C2 /* FileBrowser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ECF5CB025627CCE001B60C2 /* FileBrowser.swift */; };
  20 + 7ECF5CC525627CCF001B60C2 /* FileListPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ECF5CB125627CCE001B60C2 /* FileListPreview.swift */; };
  21 + 7ECF5CC625627CCF001B60C2 /* folder@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7ECF5CB325627CCE001B60C2 /* folder@2x.png */; };
  22 + 7ECF5CC725627CCF001B60C2 /* zip@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7ECF5CB425627CCE001B60C2 /* zip@2x.png */; };
  23 + 7ECF5CC825627CCF001B60C2 /* WebviewPreviewViewContoller.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7ECF5CB525627CCE001B60C2 /* WebviewPreviewViewContoller.xib */; };
  24 + 7ECF5CC925627CCF001B60C2 /* image@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7ECF5CB625627CCE001B60C2 /* image@2x.png */; };
  25 + 7ECF5CCA25627CCF001B60C2 /* documents@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7ECF5CB725627CCE001B60C2 /* documents@2x.png */; };
  26 + 7ECF5CCB25627CCF001B60C2 /* file@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7ECF5CB825627CCE001B60C2 /* file@2x.png */; };
  27 + 7ECF5CCC25627CCF001B60C2 /* FileBrowser.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7ECF5CB925627CCE001B60C2 /* FileBrowser.xib */; };
  28 + 7ECF5CCD25627CCF001B60C2 /* pdf@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7ECF5CBA25627CCE001B60C2 /* pdf@2x.png */; };
  29 + 7ECF5CCE25627CCF001B60C2 /* PreviewTransitionViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7ECF5CBB25627CCE001B60C2 /* PreviewTransitionViewController.xib */; };
  30 + 7ECF5CD125627CDE001B60C2 /* SettingVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ECF5CD025627CDE001B60C2 /* SettingVC.swift */; };
  31 + 8CDC226071D1655432DC3BCC /* Pods_HHMSDKDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B8EF2823F6F38130867DF23A /* Pods_HHMSDKDemo.framework */; };
  32 + 952594822293906E00053058 /* HHWebBrowser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 952594812293906E00053058 /* HHWebBrowser.swift */; };
  33 + 95844E312153A4E800D836F1 /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95844E302153A4E800D836F1 /* CoreMotion.framework */; };
  34 + 95CC5FD020D8A64100310344 /* UIView+xib.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95CC5FCF20D8A64100310344 /* UIView+xib.swift */; };
  35 + 95F31C4120D0F8C9000BDAC4 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95F31C4020D0F8C9000BDAC4 /* AppDelegate.swift */; };
  36 + 95F31C4620D0F8C9000BDAC4 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 95F31C4420D0F8C9000BDAC4 /* Main.storyboard */; };
  37 + 95F31C4820D0F8CA000BDAC4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 95F31C4720D0F8CA000BDAC4 /* Assets.xcassets */; };
  38 + 95F31C4B20D0F8CA000BDAC4 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 95F31C4920D0F8CA000BDAC4 /* LaunchScreen.storyboard */; };
  39 + 95F31C5520D24789000BDAC4 /* LoginVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95F31C5420D24789000BDAC4 /* LoginVC.swift */; };
  40 +/* End PBXBuildFile section */
  41 +
  42 +/* Begin PBXFileReference section */
  43 + 17CA3CCBE1A55DDD5C3CA3C4 /* Pods-HHMSDKDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HHMSDKDemo.debug.xcconfig"; path = "Pods/Target Support Files/Pods-HHMSDKDemo/Pods-HHMSDKDemo.debug.xcconfig"; sourceTree = "<group>"; };
  44 + 4D6DB950D99E74522E220E53 /* Pods-HHMSDKDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HHMSDKDemo.release.xcconfig"; path = "Pods/Target Support Files/Pods-HHMSDKDemo/Pods-HHMSDKDemo.release.xcconfig"; sourceTree = "<group>"; };
  45 + 7ECF5CA725627CCE001B60C2 /* PreviewTransitionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreviewTransitionViewController.swift; sourceTree = "<group>"; };
  46 + 7ECF5CA825627CCE001B60C2 /* WebviewPreviewViewContoller.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WebviewPreviewViewContoller.swift; sourceTree = "<group>"; };
  47 + 7ECF5CA925627CCE001B60C2 /* FileListViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileListViewController.swift; sourceTree = "<group>"; };
  48 + 7ECF5CAA25627CCE001B60C2 /* FileParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileParser.swift; sourceTree = "<group>"; };
  49 + 7ECF5CAB25627CCE001B60C2 /* PreviewManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreviewManager.swift; sourceTree = "<group>"; };
  50 + 7ECF5CAC25627CCE001B60C2 /* FileListSearch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileListSearch.swift; sourceTree = "<group>"; };
  51 + 7ECF5CAD25627CCE001B60C2 /* FBFile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FBFile.swift; sourceTree = "<group>"; };
  52 + 7ECF5CAE25627CCE001B60C2 /* FileBrowser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileBrowser.h; sourceTree = "<group>"; };
  53 + 7ECF5CAF25627CCE001B60C2 /* FileListTableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileListTableView.swift; sourceTree = "<group>"; };
  54 + 7ECF5CB025627CCE001B60C2 /* FileBrowser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileBrowser.swift; sourceTree = "<group>"; };
  55 + 7ECF5CB125627CCE001B60C2 /* FileListPreview.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileListPreview.swift; sourceTree = "<group>"; };
  56 + 7ECF5CB325627CCE001B60C2 /* folder@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "folder@2x.png"; sourceTree = "<group>"; };
  57 + 7ECF5CB425627CCE001B60C2 /* zip@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "zip@2x.png"; sourceTree = "<group>"; };
  58 + 7ECF5CB525627CCE001B60C2 /* WebviewPreviewViewContoller.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = WebviewPreviewViewContoller.xib; sourceTree = "<group>"; };
  59 + 7ECF5CB625627CCE001B60C2 /* image@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "image@2x.png"; sourceTree = "<group>"; };
  60 + 7ECF5CB725627CCE001B60C2 /* documents@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "documents@2x.png"; sourceTree = "<group>"; };
  61 + 7ECF5CB825627CCE001B60C2 /* file@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "file@2x.png"; sourceTree = "<group>"; };
  62 + 7ECF5CB925627CCE001B60C2 /* FileBrowser.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = FileBrowser.xib; sourceTree = "<group>"; };
  63 + 7ECF5CBA25627CCE001B60C2 /* pdf@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "pdf@2x.png"; sourceTree = "<group>"; };
  64 + 7ECF5CBB25627CCE001B60C2 /* PreviewTransitionViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PreviewTransitionViewController.xib; sourceTree = "<group>"; };
  65 + 7ECF5CD025627CDE001B60C2 /* SettingVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingVC.swift; sourceTree = "<group>"; };
  66 + 7ECF5CF125627FA0001B60C2 /* bridging-header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bridging-header.h"; sourceTree = "<group>"; };
  67 + 95030D28229D2F8D00AD6290 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/Main.strings"; sourceTree = "<group>"; };
  68 + 95030D29229D2F8D00AD6290 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/LaunchScreen.strings"; sourceTree = "<group>"; };
  69 + 952594812293906E00053058 /* HHWebBrowser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HHWebBrowser.swift; sourceTree = "<group>"; };
  70 + 95844E302153A4E800D836F1 /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = System/Library/Frameworks/CoreMotion.framework; sourceTree = SDKROOT; };
  71 + 95CC5FCF20D8A64100310344 /* UIView+xib.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+xib.swift"; sourceTree = "<group>"; };
  72 + 95E3293120D9F76A003906D4 /* HHMSDKDemo.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = HHMSDKDemo.entitlements; sourceTree = "<group>"; };
  73 + 95F31C3D20D0F8C9000BDAC4 /* HHMSDKDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HHMSDKDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
  74 + 95F31C4020D0F8C9000BDAC4 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
  75 + 95F31C4520D0F8C9000BDAC4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
  76 + 95F31C4720D0F8CA000BDAC4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
  77 + 95F31C4A20D0F8CA000BDAC4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
  78 + 95F31C4C20D0F8CA000BDAC4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
  79 + 95F31C5420D24789000BDAC4 /* LoginVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginVC.swift; sourceTree = "<group>"; };
  80 + B8EF2823F6F38130867DF23A /* Pods_HHMSDKDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_HHMSDKDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; };
  81 +/* End PBXFileReference section */
  82 +
  83 +/* Begin PBXFrameworksBuildPhase section */
  84 + 95F31C3A20D0F8C9000BDAC4 /* Frameworks */ = {
  85 + isa = PBXFrameworksBuildPhase;
  86 + buildActionMask = 2147483647;
  87 + files = (
  88 + 95844E312153A4E800D836F1 /* CoreMotion.framework in Frameworks */,
  89 + 6AF58710F6F4704A0DDB54DA /* BuildFile in Frameworks */,
  90 + 8CDC226071D1655432DC3BCC /* Pods_HHMSDKDemo.framework in Frameworks */,
  91 + );
  92 + runOnlyForDeploymentPostprocessing = 0;
  93 + };
  94 +/* End PBXFrameworksBuildPhase section */
  95 +
  96 +/* Begin PBXGroup section */
  97 + 2965255EF491A8B0F6027603 /* Frameworks */ = {
  98 + isa = PBXGroup;
  99 + children = (
  100 + 95844E302153A4E800D836F1 /* CoreMotion.framework */,
  101 + B8EF2823F6F38130867DF23A /* Pods_HHMSDKDemo.framework */,
  102 + );
  103 + name = Frameworks;
  104 + sourceTree = "<group>";
  105 + };
  106 + 7ECF5CA625627CAE001B60C2 /* FileBrowser */ = {
  107 + isa = PBXGroup;
  108 + children = (
  109 + 7ECF5CAD25627CCE001B60C2 /* FBFile.swift */,
  110 + 7ECF5CAE25627CCE001B60C2 /* FileBrowser.h */,
  111 + 7ECF5CB025627CCE001B60C2 /* FileBrowser.swift */,
  112 + 7ECF5CB125627CCE001B60C2 /* FileListPreview.swift */,
  113 + 7ECF5CAC25627CCE001B60C2 /* FileListSearch.swift */,
  114 + 7ECF5CAF25627CCE001B60C2 /* FileListTableView.swift */,
  115 + 7ECF5CA925627CCE001B60C2 /* FileListViewController.swift */,
  116 + 7ECF5CAA25627CCE001B60C2 /* FileParser.swift */,
  117 + 7ECF5CAB25627CCE001B60C2 /* PreviewManager.swift */,
  118 + 7ECF5CA725627CCE001B60C2 /* PreviewTransitionViewController.swift */,
  119 + 7ECF5CB225627CCE001B60C2 /* Resources */,
  120 + 7ECF5CA825627CCE001B60C2 /* WebviewPreviewViewContoller.swift */,
  121 + );
  122 + path = FileBrowser;
  123 + sourceTree = "<group>";
  124 + };
  125 + 7ECF5CB225627CCE001B60C2 /* Resources */ = {
  126 + isa = PBXGroup;
  127 + children = (
  128 + 7ECF5CB325627CCE001B60C2 /* folder@2x.png */,
  129 + 7ECF5CB425627CCE001B60C2 /* zip@2x.png */,
  130 + 7ECF5CB525627CCE001B60C2 /* WebviewPreviewViewContoller.xib */,
  131 + 7ECF5CB625627CCE001B60C2 /* image@2x.png */,
  132 + 7ECF5CB725627CCE001B60C2 /* documents@2x.png */,
  133 + 7ECF5CB825627CCE001B60C2 /* file@2x.png */,
  134 + 7ECF5CB925627CCE001B60C2 /* FileBrowser.xib */,
  135 + 7ECF5CBA25627CCE001B60C2 /* pdf@2x.png */,
  136 + 7ECF5CBB25627CCE001B60C2 /* PreviewTransitionViewController.xib */,
  137 + );
  138 + path = Resources;
  139 + sourceTree = "<group>";
  140 + };
  141 + 9525949C22939A6000053058 /* Res */ = {
  142 + isa = PBXGroup;
  143 + children = (
  144 + 95F31C4420D0F8C9000BDAC4 /* Main.storyboard */,
  145 + 95F31C4720D0F8CA000BDAC4 /* Assets.xcassets */,
  146 + 95F31C4920D0F8CA000BDAC4 /* LaunchScreen.storyboard */,
  147 + 95F31C4C20D0F8CA000BDAC4 /* Info.plist */,
  148 + );
  149 + path = Res;
  150 + sourceTree = "<group>";
  151 + };
  152 + 95CC5FCE20D8A5FB00310344 /* Utils */ = {
  153 + isa = PBXGroup;
  154 + children = (
  155 + 952594812293906E00053058 /* HHWebBrowser.swift */,
  156 + 95CC5FCF20D8A64100310344 /* UIView+xib.swift */,
  157 + );
  158 + path = Utils;
  159 + sourceTree = "<group>";
  160 + };
  161 + 95F31C3420D0F8C9000BDAC4 = {
  162 + isa = PBXGroup;
  163 + children = (
  164 + 95F31C3F20D0F8C9000BDAC4 /* HHMSDKDemo */,
  165 + 95F31C3E20D0F8C9000BDAC4 /* Products */,
  166 + FD5EC59F725CD960E73D7FB2 /* Pods */,
  167 + 2965255EF491A8B0F6027603 /* Frameworks */,
  168 + );
  169 + sourceTree = "<group>";
  170 + };
  171 + 95F31C3E20D0F8C9000BDAC4 /* Products */ = {
  172 + isa = PBXGroup;
  173 + children = (
  174 + 95F31C3D20D0F8C9000BDAC4 /* HHMSDKDemo.app */,
  175 + );
  176 + name = Products;
  177 + sourceTree = "<group>";
  178 + };
  179 + 95F31C3F20D0F8C9000BDAC4 /* HHMSDKDemo */ = {
  180 + isa = PBXGroup;
  181 + children = (
  182 + 7ECF5CA625627CAE001B60C2 /* FileBrowser */,
  183 + 95E3293120D9F76A003906D4 /* HHMSDKDemo.entitlements */,
  184 + 95F31C4020D0F8C9000BDAC4 /* AppDelegate.swift */,
  185 + 95F31C5420D24789000BDAC4 /* LoginVC.swift */,
  186 + 95CC5FCE20D8A5FB00310344 /* Utils */,
  187 + 9525949C22939A6000053058 /* Res */,
  188 + 7ECF5CD025627CDE001B60C2 /* SettingVC.swift */,
  189 + 7ECF5CF125627FA0001B60C2 /* bridging-header.h */,
  190 + );
  191 + path = HHMSDKDemo;
  192 + sourceTree = "<group>";
  193 + };
  194 + FD5EC59F725CD960E73D7FB2 /* Pods */ = {
  195 + isa = PBXGroup;
  196 + children = (
  197 + 17CA3CCBE1A55DDD5C3CA3C4 /* Pods-HHMSDKDemo.debug.xcconfig */,
  198 + 4D6DB950D99E74522E220E53 /* Pods-HHMSDKDemo.release.xcconfig */,
  199 + );
  200 + name = Pods;
  201 + sourceTree = "<group>";
  202 + };
  203 +/* End PBXGroup section */
  204 +
  205 +/* Begin PBXNativeTarget section */
  206 + 95F31C3C20D0F8C9000BDAC4 /* HHMSDKDemo */ = {
  207 + isa = PBXNativeTarget;
  208 + buildConfigurationList = 95F31C4F20D0F8CA000BDAC4 /* Build configuration list for PBXNativeTarget "HHMSDKDemo" */;
  209 + buildPhases = (
  210 + 3F70574BEF14EFDDBC2276D7 /* [CP] Check Pods Manifest.lock */,
  211 + 95F31C3920D0F8C9000BDAC4 /* Sources */,
  212 + 95F31C3A20D0F8C9000BDAC4 /* Frameworks */,
  213 + 95F31C3B20D0F8C9000BDAC4 /* Resources */,
  214 + 2F2866C9626CA31B9760B5C4 /* [CP] Embed Pods Frameworks */,
  215 + F8948772789F21F588832CFB /* [CP] Copy Pods Resources */,
  216 + );
  217 + buildRules = (
  218 + );
  219 + dependencies = (
  220 + );
  221 + name = HHMSDKDemo;
  222 + productName = HHMSDKDemo;
  223 + productReference = 95F31C3D20D0F8C9000BDAC4 /* HHMSDKDemo.app */;
  224 + productType = "com.apple.product-type.application";
  225 + };
  226 +/* End PBXNativeTarget section */
  227 +
  228 +/* Begin PBXProject section */
  229 + 95F31C3520D0F8C9000BDAC4 /* Project object */ = {
  230 + isa = PBXProject;
  231 + attributes = {
  232 + LastSwiftUpdateCheck = 0940;
  233 + LastUpgradeCheck = 0940;
  234 + ORGANIZATIONNAME = shmily;
  235 + TargetAttributes = {
  236 + 95F31C3C20D0F8C9000BDAC4 = {
  237 + CreatedOnToolsVersion = 9.4;
  238 + LastSwiftMigration = 1020;
  239 + SystemCapabilities = {
  240 + com.apple.BackgroundModes = {
  241 + enabled = 1;
  242 + };
  243 + com.apple.Push = {
  244 + enabled = 1;
  245 + };
  246 + };
  247 + };
  248 + };
  249 + };
  250 + buildConfigurationList = 95F31C3820D0F8C9000BDAC4 /* Build configuration list for PBXProject "HHMSDKDemo" */;
  251 + compatibilityVersion = "Xcode 9.3";
  252 + developmentRegion = en;
  253 + hasScannedForEncodings = 0;
  254 + knownRegions = (
  255 + en,
  256 + Base,
  257 + "zh-Hant",
  258 + );
  259 + mainGroup = 95F31C3420D0F8C9000BDAC4;
  260 + productRefGroup = 95F31C3E20D0F8C9000BDAC4 /* Products */;
  261 + projectDirPath = "";
  262 + projectRoot = "";
  263 + targets = (
  264 + 95F31C3C20D0F8C9000BDAC4 /* HHMSDKDemo */,
  265 + );
  266 + };
  267 +/* End PBXProject section */
  268 +
  269 +/* Begin PBXResourcesBuildPhase section */
  270 + 95F31C3B20D0F8C9000BDAC4 /* Resources */ = {
  271 + isa = PBXResourcesBuildPhase;
  272 + buildActionMask = 2147483647;
  273 + files = (
  274 + 7ECF5CCC25627CCF001B60C2 /* FileBrowser.xib in Resources */,
  275 + 7ECF5CC925627CCF001B60C2 /* image@2x.png in Resources */,
  276 + 7ECF5CCD25627CCF001B60C2 /* pdf@2x.png in Resources */,
  277 + 7ECF5CC825627CCF001B60C2 /* WebviewPreviewViewContoller.xib in Resources */,
  278 + 7ECF5CCE25627CCF001B60C2 /* PreviewTransitionViewController.xib in Resources */,
  279 + 95F31C4B20D0F8CA000BDAC4 /* LaunchScreen.storyboard in Resources */,
  280 + 7ECF5CC725627CCF001B60C2 /* zip@2x.png in Resources */,
  281 + 95F31C4820D0F8CA000BDAC4 /* Assets.xcassets in Resources */,
  282 + 7ECF5CC625627CCF001B60C2 /* folder@2x.png in Resources */,
  283 + 95F31C4620D0F8C9000BDAC4 /* Main.storyboard in Resources */,
  284 + 7ECF5CCB25627CCF001B60C2 /* file@2x.png in Resources */,
  285 + 7ECF5CCA25627CCF001B60C2 /* documents@2x.png in Resources */,
  286 + );
  287 + runOnlyForDeploymentPostprocessing = 0;
  288 + };
  289 +/* End PBXResourcesBuildPhase section */
  290 +
  291 +/* Begin PBXShellScriptBuildPhase section */
  292 + 2F2866C9626CA31B9760B5C4 /* [CP] Embed Pods Frameworks */ = {
  293 + isa = PBXShellScriptBuildPhase;
  294 + buildActionMask = 2147483647;
  295 + files = (
  296 + );
  297 + inputFileListPaths = (
  298 + "${PODS_ROOT}/Target Support Files/Pods-HHMSDKDemo/Pods-HHMSDKDemo-frameworks-${CONFIGURATION}-input-files.xcfilelist",
  299 + );
  300 + name = "[CP] Embed Pods Frameworks";
  301 + outputFileListPaths = (
  302 + "${PODS_ROOT}/Target Support Files/Pods-HHMSDKDemo/Pods-HHMSDKDemo-frameworks-${CONFIGURATION}-output-files.xcfilelist",
  303 + );
  304 + runOnlyForDeploymentPostprocessing = 0;
  305 + shellPath = /bin/sh;
  306 + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-HHMSDKDemo/Pods-HHMSDKDemo-frameworks.sh\"\n";
  307 + showEnvVarsInLog = 0;
  308 + };
  309 + 3F70574BEF14EFDDBC2276D7 /* [CP] Check Pods Manifest.lock */ = {
  310 + isa = PBXShellScriptBuildPhase;
  311 + buildActionMask = 2147483647;
  312 + files = (
  313 + );
  314 + inputPaths = (
  315 + "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
  316 + "${PODS_ROOT}/Manifest.lock",
  317 + );
  318 + name = "[CP] Check Pods Manifest.lock";
  319 + outputPaths = (
  320 + "$(DERIVED_FILE_DIR)/Pods-HHMSDKDemo-checkManifestLockResult.txt",
  321 + );
  322 + runOnlyForDeploymentPostprocessing = 0;
  323 + shellPath = /bin/sh;
  324 + 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";
  325 + showEnvVarsInLog = 0;
  326 + };
  327 + F8948772789F21F588832CFB /* [CP] Copy Pods Resources */ = {
  328 + isa = PBXShellScriptBuildPhase;
  329 + buildActionMask = 2147483647;
  330 + files = (
  331 + );
  332 + inputFileListPaths = (
  333 + "${PODS_ROOT}/Target Support Files/Pods-HHMSDKDemo/Pods-HHMSDKDemo-resources-${CONFIGURATION}-input-files.xcfilelist",
  334 + );
  335 + name = "[CP] Copy Pods Resources";
  336 + outputFileListPaths = (
  337 + "${PODS_ROOT}/Target Support Files/Pods-HHMSDKDemo/Pods-HHMSDKDemo-resources-${CONFIGURATION}-output-files.xcfilelist",
  338 + );
  339 + runOnlyForDeploymentPostprocessing = 0;
  340 + shellPath = /bin/sh;
  341 + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-HHMSDKDemo/Pods-HHMSDKDemo-resources.sh\"\n";
  342 + showEnvVarsInLog = 0;
  343 + };
  344 +/* End PBXShellScriptBuildPhase section */
  345 +
  346 +/* Begin PBXSourcesBuildPhase section */
  347 + 95F31C3920D0F8C9000BDAC4 /* Sources */ = {
  348 + isa = PBXSourcesBuildPhase;
  349 + buildActionMask = 2147483647;
  350 + files = (
  351 + 7ECF5CBF25627CCE001B60C2 /* FileParser.swift in Sources */,
  352 + 95CC5FD020D8A64100310344 /* UIView+xib.swift in Sources */,
  353 + 7ECF5CC525627CCF001B60C2 /* FileListPreview.swift in Sources */,
  354 + 7ECF5CC025627CCE001B60C2 /* PreviewManager.swift in Sources */,
  355 + 7ECF5CC125627CCE001B60C2 /* FileListSearch.swift in Sources */,
  356 + 7ECF5CBE25627CCE001B60C2 /* FileListViewController.swift in Sources */,
  357 + 952594822293906E00053058 /* HHWebBrowser.swift in Sources */,
  358 + 7ECF5CD125627CDE001B60C2 /* SettingVC.swift in Sources */,
  359 + 95F31C4120D0F8C9000BDAC4 /* AppDelegate.swift in Sources */,
  360 + 7ECF5CC225627CCE001B60C2 /* FBFile.swift in Sources */,
  361 + 7ECF5CBC25627CCE001B60C2 /* PreviewTransitionViewController.swift in Sources */,
  362 + 7ECF5CC325627CCE001B60C2 /* FileListTableView.swift in Sources */,
  363 + 7ECF5CBD25627CCE001B60C2 /* WebviewPreviewViewContoller.swift in Sources */,
  364 + 95F31C5520D24789000BDAC4 /* LoginVC.swift in Sources */,
  365 + 7ECF5CC425627CCE001B60C2 /* FileBrowser.swift in Sources */,
  366 + );
  367 + runOnlyForDeploymentPostprocessing = 0;
  368 + };
  369 +/* End PBXSourcesBuildPhase section */
  370 +
  371 +/* Begin PBXVariantGroup section */
  372 + 95F31C4420D0F8C9000BDAC4 /* Main.storyboard */ = {
  373 + isa = PBXVariantGroup;
  374 + children = (
  375 + 95F31C4520D0F8C9000BDAC4 /* Base */,
  376 + 95030D28229D2F8D00AD6290 /* zh-Hant */,
  377 + );
  378 + name = Main.storyboard;
  379 + sourceTree = "<group>";
  380 + };
  381 + 95F31C4920D0F8CA000BDAC4 /* LaunchScreen.storyboard */ = {
  382 + isa = PBXVariantGroup;
  383 + children = (
  384 + 95F31C4A20D0F8CA000BDAC4 /* Base */,
  385 + 95030D29229D2F8D00AD6290 /* zh-Hant */,
  386 + );
  387 + name = LaunchScreen.storyboard;
  388 + sourceTree = "<group>";
  389 + };
  390 +/* End PBXVariantGroup section */
  391 +
  392 +/* Begin XCBuildConfiguration section */
  393 + 95F31C4D20D0F8CA000BDAC4 /* Debug */ = {
  394 + isa = XCBuildConfiguration;
  395 + buildSettings = {
  396 + ALWAYS_SEARCH_USER_PATHS = NO;
  397 + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
  398 + CLANG_ANALYZER_NONNULL = YES;
  399 + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
  400 + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
  401 + CLANG_CXX_LIBRARY = "libc++";
  402 + CLANG_ENABLE_MODULES = YES;
  403 + CLANG_ENABLE_OBJC_ARC = YES;
  404 + CLANG_ENABLE_OBJC_WEAK = YES;
  405 + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
  406 + CLANG_WARN_BOOL_CONVERSION = YES;
  407 + CLANG_WARN_COMMA = YES;
  408 + CLANG_WARN_CONSTANT_CONVERSION = YES;
  409 + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
  410 + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
  411 + CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
  412 + CLANG_WARN_EMPTY_BODY = YES;
  413 + CLANG_WARN_ENUM_CONVERSION = YES;
  414 + CLANG_WARN_INFINITE_RECURSION = YES;
  415 + CLANG_WARN_INT_CONVERSION = YES;
  416 + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
  417 + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
  418 + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
  419 + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
  420 + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
  421 + CLANG_WARN_STRICT_PROTOTYPES = YES;
  422 + CLANG_WARN_SUSPICIOUS_MOVE = YES;
  423 + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
  424 + CLANG_WARN_UNREACHABLE_CODE = YES;
  425 + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
  426 + CODE_SIGN_IDENTITY = "iPhone Developer";
  427 + COPY_PHASE_STRIP = NO;
  428 + DEBUG_INFORMATION_FORMAT = dwarf;
  429 + ENABLE_STRICT_OBJC_MSGSEND = YES;
  430 + ENABLE_TESTABILITY = YES;
  431 + GCC_C_LANGUAGE_STANDARD = gnu11;
  432 + GCC_DYNAMIC_NO_PIC = NO;
  433 + GCC_NO_COMMON_BLOCKS = YES;
  434 + GCC_OPTIMIZATION_LEVEL = 0;
  435 + GCC_PREPROCESSOR_DEFINITIONS = (
  436 + "DEBUG=1",
  437 + "$(inherited)",
  438 + );
  439 + GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
  440 + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
  441 + GCC_WARN_UNDECLARED_SELECTOR = YES;
  442 + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
  443 + GCC_WARN_UNUSED_FUNCTION = YES;
  444 + GCC_WARN_UNUSED_VARIABLE = YES;
  445 + IPHONEOS_DEPLOYMENT_TARGET = 11.4;
  446 + MTL_ENABLE_DEBUG_INFO = YES;
  447 + ONLY_ACTIVE_ARCH = YES;
  448 + SDKROOT = iphoneos;
  449 + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
  450 + SWIFT_OPTIMIZATION_LEVEL = "-Onone";
  451 + SWIFT_VERSION = 4.0;
  452 + };
  453 + name = Debug;
  454 + };
  455 + 95F31C4E20D0F8CA000BDAC4 /* Release */ = {
  456 + isa = XCBuildConfiguration;
  457 + buildSettings = {
  458 + ALWAYS_SEARCH_USER_PATHS = NO;
  459 + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
  460 + CLANG_ANALYZER_NONNULL = YES;
  461 + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
  462 + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
  463 + CLANG_CXX_LIBRARY = "libc++";
  464 + CLANG_ENABLE_MODULES = YES;
  465 + CLANG_ENABLE_OBJC_ARC = YES;
  466 + CLANG_ENABLE_OBJC_WEAK = YES;
  467 + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
  468 + CLANG_WARN_BOOL_CONVERSION = YES;
  469 + CLANG_WARN_COMMA = YES;
  470 + CLANG_WARN_CONSTANT_CONVERSION = YES;
  471 + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
  472 + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
  473 + CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
  474 + CLANG_WARN_EMPTY_BODY = YES;
  475 + CLANG_WARN_ENUM_CONVERSION = YES;
  476 + CLANG_WARN_INFINITE_RECURSION = YES;
  477 + CLANG_WARN_INT_CONVERSION = YES;
  478 + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
  479 + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
  480 + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
  481 + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
  482 + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
  483 + CLANG_WARN_STRICT_PROTOTYPES = YES;
  484 + CLANG_WARN_SUSPICIOUS_MOVE = YES;
  485 + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
  486 + CLANG_WARN_UNREACHABLE_CODE = YES;
  487 + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
  488 + CODE_SIGN_IDENTITY = "iPhone Developer";
  489 + COPY_PHASE_STRIP = NO;
  490 + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
  491 + ENABLE_NS_ASSERTIONS = NO;
  492 + ENABLE_STRICT_OBJC_MSGSEND = YES;
  493 + GCC_C_LANGUAGE_STANDARD = gnu11;
  494 + GCC_NO_COMMON_BLOCKS = YES;
  495 + GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
  496 + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
  497 + GCC_WARN_UNDECLARED_SELECTOR = YES;
  498 + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
  499 + GCC_WARN_UNUSED_FUNCTION = YES;
  500 + GCC_WARN_UNUSED_VARIABLE = YES;
  501 + IPHONEOS_DEPLOYMENT_TARGET = 11.4;
  502 + MTL_ENABLE_DEBUG_INFO = NO;
  503 + SDKROOT = iphoneos;
  504 + SWIFT_COMPILATION_MODE = wholemodule;
  505 + SWIFT_OPTIMIZATION_LEVEL = "-O";
  506 + SWIFT_VERSION = 4.0;
  507 + VALIDATE_PRODUCT = YES;
  508 + };
  509 + name = Release;
  510 + };
  511 + 95F31C5020D0F8CA000BDAC4 /* Debug */ = {
  512 + isa = XCBuildConfiguration;
  513 + baseConfigurationReference = 17CA3CCBE1A55DDD5C3CA3C4 /* Pods-HHMSDKDemo.debug.xcconfig */;
  514 + buildSettings = {
  515 + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
  516 + CLANG_ENABLE_MODULES = YES;
  517 + CODE_SIGN_ENTITLEMENTS = HHMSDKDemo/HHMSDKDemo.entitlements;
  518 + CODE_SIGN_IDENTITY = "Apple Development";
  519 + CODE_SIGN_STYLE = Automatic;
  520 + CURRENT_PROJECT_VERSION = 2020.1113.13;
  521 + DEVELOPMENT_TEAM = SX7LU85BSD;
  522 + ENABLE_BITCODE = NO;
  523 + FRAMEWORK_SEARCH_PATHS = "$(inherited)";
  524 + INFOPLIST_FILE = "$(SRCROOT)/HHMSDKDemo/Res/Info.plist";
  525 + IPHONEOS_DEPLOYMENT_TARGET = 9.3;
  526 + LD_RUNPATH_SEARCH_PATHS = (
  527 + "$(inherited)",
  528 + "@executable_path/Frameworks",
  529 + );
  530 + MARKETING_VERSION = 3.0.6;
  531 + PRODUCT_BUNDLE_IDENTIFIER = com.hh.hhvdoctorSDK;
  532 + PRODUCT_NAME = "$(TARGET_NAME)";
  533 + PROVISIONING_PROFILE_SPECIFIER = "";
  534 + SWIFT_OBJC_BRIDGING_HEADER = "/Users/chengyanfang/Documents/hh/iOS_SDK/SDKs/HHDoctorSDK_TX_demo_iOS/HHMSDKDemo/bridging-header.h";
  535 + SWIFT_OPTIMIZATION_LEVEL = "-Onone";
  536 + SWIFT_VERSION = 5.0;
  537 + TARGETED_DEVICE_FAMILY = 1;
  538 + };
  539 + name = Debug;
  540 + };
  541 + 95F31C5120D0F8CA000BDAC4 /* Release */ = {
  542 + isa = XCBuildConfiguration;
  543 + baseConfigurationReference = 4D6DB950D99E74522E220E53 /* Pods-HHMSDKDemo.release.xcconfig */;
  544 + buildSettings = {
  545 + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
  546 + CLANG_ENABLE_MODULES = YES;
  547 + CODE_SIGN_ENTITLEMENTS = HHMSDKDemo/HHMSDKDemo.entitlements;
  548 + CODE_SIGN_IDENTITY = "Apple Development";
  549 + CODE_SIGN_STYLE = Automatic;
  550 + CURRENT_PROJECT_VERSION = 2020.1113.13;
  551 + DEVELOPMENT_TEAM = SX7LU85BSD;
  552 + ENABLE_BITCODE = NO;
  553 + FRAMEWORK_SEARCH_PATHS = "$(inherited)";
  554 + INFOPLIST_FILE = "$(SRCROOT)/HHMSDKDemo/Res/Info.plist";
  555 + IPHONEOS_DEPLOYMENT_TARGET = 9.3;
  556 + LD_RUNPATH_SEARCH_PATHS = (
  557 + "$(inherited)",
  558 + "@executable_path/Frameworks",
  559 + );
  560 + MARKETING_VERSION = 3.0.6;
  561 + PRODUCT_BUNDLE_IDENTIFIER = com.hh.hhvdoctorSDK;
  562 + PRODUCT_NAME = "$(TARGET_NAME)";
  563 + PROVISIONING_PROFILE_SPECIFIER = "";
  564 + SWIFT_OBJC_BRIDGING_HEADER = "/Users/chengyanfang/Documents/hh/iOS_SDK/SDKs/HHDoctorSDK_TX_demo_iOS/HHMSDKDemo/bridging-header.h";
  565 + SWIFT_VERSION = 5.0;
  566 + TARGETED_DEVICE_FAMILY = 1;
  567 + };
  568 + name = Release;
  569 + };
  570 +/* End XCBuildConfiguration section */
  571 +
  572 +/* Begin XCConfigurationList section */
  573 + 95F31C3820D0F8C9000BDAC4 /* Build configuration list for PBXProject "HHMSDKDemo" */ = {
  574 + isa = XCConfigurationList;
  575 + buildConfigurations = (
  576 + 95F31C4D20D0F8CA000BDAC4 /* Debug */,
  577 + 95F31C4E20D0F8CA000BDAC4 /* Release */,
  578 + );
  579 + defaultConfigurationIsVisible = 0;
  580 + defaultConfigurationName = Release;
  581 + };
  582 + 95F31C4F20D0F8CA000BDAC4 /* Build configuration list for PBXNativeTarget "HHMSDKDemo" */ = {
  583 + isa = XCConfigurationList;
  584 + buildConfigurations = (
  585 + 95F31C5020D0F8CA000BDAC4 /* Debug */,
  586 + 95F31C5120D0F8CA000BDAC4 /* Release */,
  587 + );
  588 + defaultConfigurationIsVisible = 0;
  589 + defaultConfigurationName = Release;
  590 + };
  591 +/* End XCConfigurationList section */
  592 + };
  593 + rootObject = 95F31C3520D0F8C9000BDAC4 /* Project object */;
  594 +}
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<Workspace
  3 + version = "1.0">
  4 + <FileRef
  5 + location = "self:HHMSDKDemo.xcodeproj">
  6 + </FileRef>
  7 +</Workspace>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>IDEDidComputeMac32BitWarning</key>
  6 + <true/>
  7 +</dict>
  8 +</plist>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<Scheme
  3 + LastUpgradeVersion = "1020"
  4 + version = "1.3">
  5 + <BuildAction
  6 + parallelizeBuildables = "YES"
  7 + buildImplicitDependencies = "YES">
  8 + <BuildActionEntries>
  9 + <BuildActionEntry
  10 + buildForTesting = "YES"
  11 + buildForRunning = "YES"
  12 + buildForProfiling = "YES"
  13 + buildForArchiving = "YES"
  14 + buildForAnalyzing = "YES">
  15 + <BuildableReference
  16 + BuildableIdentifier = "primary"
  17 + BlueprintIdentifier = "95F31C3C20D0F8C9000BDAC4"
  18 + BuildableName = "HHMSDKDemo.app"
  19 + BlueprintName = "HHMSDKDemo"
  20 + ReferencedContainer = "container:HHMSDKDemo.xcodeproj">
  21 + </BuildableReference>
  22 + </BuildActionEntry>
  23 + </BuildActionEntries>
  24 + </BuildAction>
  25 + <TestAction
  26 + buildConfiguration = "Debug"
  27 + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
  28 + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
  29 + shouldUseLaunchSchemeArgsEnv = "YES">
  30 + <Testables>
  31 + </Testables>
  32 + <MacroExpansion>
  33 + <BuildableReference
  34 + BuildableIdentifier = "primary"
  35 + BlueprintIdentifier = "95F31C3C20D0F8C9000BDAC4"
  36 + BuildableName = "HHMSDKDemo.app"
  37 + BlueprintName = "HHMSDKDemo"
  38 + ReferencedContainer = "container:HHMSDKDemo.xcodeproj">
  39 + </BuildableReference>
  40 + </MacroExpansion>
  41 + <AdditionalOptions>
  42 + </AdditionalOptions>
  43 + </TestAction>
  44 + <LaunchAction
  45 + buildConfiguration = "Debug"
  46 + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
  47 + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
  48 + disableMainThreadChecker = "YES"
  49 + launchStyle = "0"
  50 + useCustomWorkingDirectory = "NO"
  51 + ignoresPersistentStateOnLaunch = "NO"
  52 + debugDocumentVersioning = "YES"
  53 + debugServiceExtension = "internal"
  54 + allowLocationSimulation = "YES">
  55 + <BuildableProductRunnable
  56 + runnableDebuggingMode = "0">
  57 + <BuildableReference
  58 + BuildableIdentifier = "primary"
  59 + BlueprintIdentifier = "95F31C3C20D0F8C9000BDAC4"
  60 + BuildableName = "HHMSDKDemo.app"
  61 + BlueprintName = "HHMSDKDemo"
  62 + ReferencedContainer = "container:HHMSDKDemo.xcodeproj">
  63 + </BuildableReference>
  64 + </BuildableProductRunnable>
  65 + <AdditionalOptions>
  66 + </AdditionalOptions>
  67 + </LaunchAction>
  68 + <ProfileAction
  69 + buildConfiguration = "Release"
  70 + shouldUseLaunchSchemeArgsEnv = "YES"
  71 + savedToolIdentifier = ""
  72 + useCustomWorkingDirectory = "NO"
  73 + debugDocumentVersioning = "YES">
  74 + <BuildableProductRunnable
  75 + runnableDebuggingMode = "0">
  76 + <BuildableReference
  77 + BuildableIdentifier = "primary"
  78 + BlueprintIdentifier = "95F31C3C20D0F8C9000BDAC4"
  79 + BuildableName = "HHMSDKDemo.app"
  80 + BlueprintName = "HHMSDKDemo"
  81 + ReferencedContainer = "container:HHMSDKDemo.xcodeproj">
  82 + </BuildableReference>
  83 + </BuildableProductRunnable>
  84 + </ProfileAction>
  85 + <AnalyzeAction
  86 + buildConfiguration = "Debug">
  87 + </AnalyzeAction>
  88 + <ArchiveAction
  89 + buildConfiguration = "Release"
  90 + revealArchiveInOrganizer = "YES">
  91 + </ArchiveAction>
  92 +</Scheme>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<Scheme
  3 + LastUpgradeVersion = "1020"
  4 + version = "1.3">
  5 + <BuildAction
  6 + parallelizeBuildables = "YES"
  7 + buildImplicitDependencies = "YES">
  8 + <BuildActionEntries>
  9 + <BuildActionEntry
  10 + buildForTesting = "YES"
  11 + buildForRunning = "YES"
  12 + buildForProfiling = "YES"
  13 + buildForArchiving = "YES"
  14 + buildForAnalyzing = "YES">
  15 + <BuildableReference
  16 + BuildableIdentifier = "primary"
  17 + BlueprintIdentifier = "95259483229392B200053058"
  18 + BuildableName = "HHMedicineDemo.app"
  19 + BlueprintName = "HHMedicineDemo"
  20 + ReferencedContainer = "container:HHMSDKDemo.xcodeproj">
  21 + </BuildableReference>
  22 + </BuildActionEntry>
  23 + </BuildActionEntries>
  24 + </BuildAction>
  25 + <TestAction
  26 + buildConfiguration = "Debug"
  27 + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
  28 + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
  29 + shouldUseLaunchSchemeArgsEnv = "YES">
  30 + <Testables>
  31 + </Testables>
  32 + <MacroExpansion>
  33 + <BuildableReference
  34 + BuildableIdentifier = "primary"
  35 + BlueprintIdentifier = "95259483229392B200053058"
  36 + BuildableName = "HHMedicineDemo.app"
  37 + BlueprintName = "HHMedicineDemo"
  38 + ReferencedContainer = "container:HHMSDKDemo.xcodeproj">
  39 + </BuildableReference>
  40 + </MacroExpansion>
  41 + <AdditionalOptions>
  42 + </AdditionalOptions>
  43 + </TestAction>
  44 + <LaunchAction
  45 + buildConfiguration = "Debug"
  46 + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
  47 + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
  48 + disableMainThreadChecker = "YES"
  49 + launchStyle = "0"
  50 + useCustomWorkingDirectory = "NO"
  51 + ignoresPersistentStateOnLaunch = "NO"
  52 + debugDocumentVersioning = "YES"
  53 + debugServiceExtension = "internal"
  54 + allowLocationSimulation = "YES">
  55 + <BuildableProductRunnable
  56 + runnableDebuggingMode = "0">
  57 + <BuildableReference
  58 + BuildableIdentifier = "primary"
  59 + BlueprintIdentifier = "95259483229392B200053058"
  60 + BuildableName = "HHMedicineDemo.app"
  61 + BlueprintName = "HHMedicineDemo"
  62 + ReferencedContainer = "container:HHMSDKDemo.xcodeproj">
  63 + </BuildableReference>
  64 + </BuildableProductRunnable>
  65 + <AdditionalOptions>
  66 + </AdditionalOptions>
  67 + </LaunchAction>
  68 + <ProfileAction
  69 + buildConfiguration = "Release"
  70 + shouldUseLaunchSchemeArgsEnv = "YES"
  71 + savedToolIdentifier = ""
  72 + useCustomWorkingDirectory = "NO"
  73 + debugDocumentVersioning = "YES">
  74 + <BuildableProductRunnable
  75 + runnableDebuggingMode = "0">
  76 + <BuildableReference
  77 + BuildableIdentifier = "primary"
  78 + BlueprintIdentifier = "95259483229392B200053058"
  79 + BuildableName = "HHMedicineDemo.app"
  80 + BlueprintName = "HHMedicineDemo"
  81 + ReferencedContainer = "container:HHMSDKDemo.xcodeproj">
  82 + </BuildableReference>
  83 + </BuildableProductRunnable>
  84 + </ProfileAction>
  85 + <AnalyzeAction
  86 + buildConfiguration = "Debug">
  87 + </AnalyzeAction>
  88 + <ArchiveAction
  89 + buildConfiguration = "Release"
  90 + revealArchiveInOrganizer = "YES">
  91 + </ArchiveAction>
  92 +</Scheme>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<Workspace
  3 + version = "1.0">
  4 + <FileRef
  5 + location = "group:HHMSDKDemo.xcodeproj">
  6 + </FileRef>
  7 + <FileRef
  8 + location = "group:Pods/Pods.xcodeproj">
  9 + </FileRef>
  10 +</Workspace>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>IDEDidComputeMac32BitWarning</key>
  6 + <true/>
  7 +</dict>
  8 +</plist>
No preview for this file type
  1 +//
  2 +// AppDelegate.swift
  3 +// hhVDoctorSDK
  4 +//
  5 +// Created by shmilyshijian@foxmail.com on 07/10/2019.
  6 +// Copyright (c) 2019 shmilyshijian@foxmail.com. All rights reserved.
  7 +//
  8 +
  9 +import UIKit
  10 +import hhVDoctorSDK
  11 +
  12 +@UIApplicationMain
  13 +class AppDelegate: UIResponder, UIApplicationDelegate {
  14 +
  15 + var window: UIWindow?
  16 +
  17 + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
  18 + let option = HHSDKOptions(productId: "3000", isDebug: true, isDevelop: true)
  19 +
  20 + option.logCallback = {
  21 + print($0)
  22 + }
  23 + HHMSDK.default.start(option: option)
  24 +
  25 + return true
  26 + }
  27 +
  28 +
  29 +
  30 + func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
  31 +
  32 + print(url)
  33 +
  34 + return true
  35 + }
  36 +
  37 +
  38 + func applicationWillResignActive(_ application: UIApplication) {
  39 + // 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.
  40 + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
  41 + }
  42 +
  43 + func applicationDidEnterBackground(_ application: UIApplication) {
  44 + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
  45 + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
  46 + }
  47 +
  48 + func applicationWillEnterForeground(_ application: UIApplication) {
  49 + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
  50 + }
  51 +
  52 + func applicationDidBecomeActive(_ application: UIApplication) {
  53 + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
  54 + }
  55 +
  56 + func applicationWillTerminate(_ application: UIApplication) {
  57 + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
  58 + }
  59 +
  60 +
  61 +}
  62 +
No preview for this file type
  1 +//
  2 +// FBFile.swift
  3 +// FileBrowser
  4 +//
  5 +// Created by Roy Marmelstein on 14/02/2016.
  6 +// Copyright © 2016 Roy Marmelstein. All rights reserved.
  7 +//
  8 +
  9 +import Foundation
  10 +import UIKit
  11 +
  12 +/// FBFile is a class representing a file in FileBrowser
  13 +@objc open class FBFile: NSObject {
  14 + /// Display name. String.
  15 + @objc public let displayName: String
  16 + // is Directory. Bool.
  17 + public let isDirectory: Bool
  18 + /// File extension.
  19 + public let fileExtension: String?
  20 + /// File attributes (including size, creation date etc).
  21 + public let fileAttributes: NSDictionary?
  22 + /// NSURL file path.
  23 + public let filePath: URL
  24 + // FBFileType
  25 + public let type: FBFileType
  26 +
  27 + open func delete()
  28 + {
  29 + do
  30 + {
  31 + try FileManager.default.removeItem(at: self.filePath)
  32 + }
  33 + catch
  34 + {
  35 + print("An error occured when trying to delete file:\(self.filePath) Error:\(error)")
  36 + }
  37 + }
  38 +
  39 + /**
  40 + Initialize an FBFile object with a filePath
  41 +
  42 + - parameter filePath: NSURL filePath
  43 +
  44 + - returns: FBFile object.
  45 + */
  46 + init(filePath: URL) {
  47 + self.filePath = filePath
  48 + let isDirectory = checkDirectory(filePath)
  49 + self.isDirectory = isDirectory
  50 + if self.isDirectory {
  51 + self.fileAttributes = nil
  52 + self.fileExtension = nil
  53 + self.type = .Directory
  54 + }
  55 + else {
  56 + self.fileAttributes = getFileAttributes(self.filePath)
  57 + self.fileExtension = filePath.pathExtension
  58 + if let fileExtension = fileExtension {
  59 + self.type = FBFileType(rawValue: fileExtension) ?? .Default
  60 + }
  61 + else {
  62 + self.type = .Default
  63 + }
  64 + }
  65 + self.displayName = filePath.lastPathComponent
  66 + }
  67 +}
  68 +
  69 +/**
  70 + FBFile type
  71 + */
  72 +public enum FBFileType: String {
  73 + /// Directory
  74 + case Directory = "directory"
  75 + /// GIF file
  76 + case GIF = "gif"
  77 + /// JPG file
  78 + case JPG = "jpg"
  79 + /// PLIST file
  80 + case JSON = "json"
  81 + /// PDF file
  82 + case PDF = "pdf"
  83 + /// PLIST file
  84 + case PLIST = "plist"
  85 + /// PNG file
  86 + case PNG = "png"
  87 + /// ZIP file
  88 + case ZIP = "zip"
  89 + /// Any file
  90 + case Default = "file"
  91 +
  92 + /**
  93 + Get representative image for file type
  94 +
  95 + - returns: UIImage for file type
  96 + */
  97 + public func image() -> UIImage? {
  98 + let bundle = Bundle(for: FileParser.self)
  99 + var fileName = String()
  100 + switch self {
  101 + case .Directory: fileName = "folder@2x.png"
  102 + case .JPG, .PNG, .GIF: fileName = "image@2x.png"
  103 + case .PDF: fileName = "pdf@2x.png"
  104 + case .ZIP: fileName = "zip@2x.png"
  105 + default: fileName = "file@2x.png"
  106 + }
  107 + let file = UIImage(named: fileName, in: bundle, compatibleWith: nil)
  108 + return file
  109 + }
  110 +}
  111 +
  112 +/**
  113 + Check if file path NSURL is directory or file.
  114 +
  115 + - parameter filePath: NSURL file path.
  116 +
  117 + - returns: isDirectory Bool.
  118 + */
  119 +func checkDirectory(_ filePath: URL) -> Bool {
  120 + var isDirectory = false
  121 + do {
  122 + var resourceValue: AnyObject?
  123 + try (filePath as NSURL).getResourceValue(&resourceValue, forKey: URLResourceKey.isDirectoryKey)
  124 + if let number = resourceValue as? NSNumber , number == true {
  125 + isDirectory = true
  126 + }
  127 + }
  128 + catch { }
  129 + return isDirectory
  130 +}
  131 +
  132 +func getFileAttributes(_ filePath: URL) -> NSDictionary? {
  133 + let path = filePath.path
  134 + let fileManager = FileParser.sharedInstance.fileManager
  135 + do {
  136 + let attributes = try fileManager.attributesOfItem(atPath: path) as NSDictionary
  137 + return attributes
  138 + } catch {}
  139 + return nil
  140 +}
  1 +//
  2 +// FileBrowser.h
  3 +// FileBrowser
  4 +//
  5 +// Created by Roy Marmelstein on 07/02/2016.
  6 +// Copyright © 2016 Roy Marmelstein. All rights reserved.
  7 +//
  8 +
  9 +#import <UIKit/UIKit.h>
  10 +
  11 +//! Project version number for FileBrowser.
  12 +FOUNDATION_EXPORT double FileBrowserVersionNumber;
  13 +
  14 +//! Project version string for FileBrowser.
  15 +FOUNDATION_EXPORT const unsigned char FileBrowserVersionString[];
  16 +
  17 +// In this header, you should import all the public headers of your framework using statements like #import <FileBrowser/PublicHeader.h>
  18 +
  19 +
  1 +//
  2 +// FileBrowser.swift
  3 +// FileBrowser
  4 +//
  5 +// Created by Roy Marmelstein on 14/02/2016.
  6 +// Copyright © 2016 Roy Marmelstein. All rights reserved.
  7 +//
  8 +
  9 +import UIKit
  10 +
  11 +/// File browser containing navigation controller.
  12 +open class FileBrowser: UINavigationController {
  13 +
  14 + let parser = FileParser.sharedInstance
  15 +
  16 + var fileList: FileListViewController?
  17 +
  18 + /// File types to exclude from the file browser.
  19 + open var excludesFileExtensions: [String]? {
  20 + didSet {
  21 + parser.excludesFileExtensions = excludesFileExtensions
  22 + }
  23 + }
  24 +
  25 + /// File paths to exclude from the file browser.
  26 + open var excludesFilepaths: [URL]? {
  27 + didSet {
  28 + parser.excludesFilepaths = excludesFilepaths
  29 + }
  30 + }
  31 +
  32 + /// Override default preview and actionsheet behaviour in favour of custom file handling.
  33 + open var didSelectFile: ((FBFile) -> ())? {
  34 + didSet {
  35 + fileList?.didSelectFile = didSelectFile
  36 + }
  37 + }
  38 +
  39 + public convenience init() {
  40 + let parser = FileParser.sharedInstance
  41 + let path = parser.documentsURL()
  42 + self.init(initialPath: path, allowEditing: true)
  43 + }
  44 +
  45 + /// Initialise file browser.
  46 + ///
  47 + /// - Parameters:
  48 + /// - initialPath: NSURL filepath to containing directory.
  49 + /// - allowEditing: Whether to allow editing.
  50 + /// - showCancelButton: Whether to show the cancel button.
  51 + public convenience init(initialPath: URL? = nil, allowEditing: Bool = false, showCancelButton: Bool = true) {
  52 +
  53 + let validInitialPath = initialPath ?? FileParser.sharedInstance.documentsURL()
  54 +
  55 + let fileListViewController = FileListViewController(initialPath: validInitialPath, showCancelButton: showCancelButton)
  56 + fileListViewController.allowEditing = allowEditing
  57 + self.init(rootViewController: fileListViewController)
  58 + self.view.backgroundColor = UIColor.white
  59 + self.fileList = fileListViewController
  60 + }
  61 +}
  1 +//
  2 +// FileListPreview.swift
  3 +// FileBrowser
  4 +//
  5 +// Created by Roy Marmelstein on 13/02/2016.
  6 +// Copyright © 2016 Roy Marmelstein. All rights reserved.
  7 +//
  8 +
  9 +import Foundation
  10 +import QuickLook
  11 +
  12 +extension FileListViewController: UIViewControllerPreviewingDelegate {
  13 +
  14 + //MARK: UIViewControllerPreviewingDelegate
  15 +
  16 + func registerFor3DTouch() {
  17 + if #available(iOS 9.0, *) {
  18 + if self.traitCollection.forceTouchCapability == UIForceTouchCapability.available {
  19 + registerForPreviewing(with: self, sourceView: tableView)
  20 + }
  21 + }
  22 + }
  23 +
  24 + func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
  25 + if #available(iOS 9.0, *) {
  26 + if let indexPath = tableView.indexPathForRow(at: location) {
  27 + let selectedFile = fileForIndexPath(indexPath)
  28 + previewingContext.sourceRect = tableView.rectForRow(at: indexPath)
  29 + if selectedFile.isDirectory == false {
  30 + return previewManager.previewViewControllerForFile(selectedFile, fromNavigation: false)
  31 + }
  32 + }
  33 + }
  34 + return nil
  35 + }
  36 +
  37 + func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) {
  38 + if let previewTransitionViewController = viewControllerToCommit as? PreviewTransitionViewController {
  39 + self.navigationController?.pushViewController(previewTransitionViewController.quickLookPreviewController, animated: true)
  40 + }
  41 + else {
  42 + self.navigationController?.pushViewController(viewControllerToCommit, animated: true)
  43 + }
  44 +
  45 + }
  46 +
  47 +}
  48 +
  1 +//
  2 +// FileListSearch.swift
  3 +// FileBrowser
  4 +//
  5 +// Created by Roy Marmelstein on 14/02/2016.
  6 +// Copyright © 2016 Roy Marmelstein. All rights reserved.
  7 +//
  8 +
  9 +import Foundation
  10 +import UIKit
  11 +
  12 +extension FileListViewController: UISearchBarDelegate, UISearchControllerDelegate, UISearchResultsUpdating {
  13 +
  14 + // MARK: UISearchControllerDelegate
  15 + func willPresentSearchController(_ searchController: UISearchController) {
  16 + self.tableView.contentInset = UIEdgeInsets.init(top: 20, left: 0, bottom: 0, right: 0)
  17 + }
  18 +
  19 + func willDismissSearchController(_ searchController: UISearchController) {
  20 + self.tableView.contentInset = UIEdgeInsets.init(top: 0, left: 0, bottom: 0, right: 0)
  21 + }
  22 +
  23 + // MARK: UISearchBarDelegate
  24 + func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
  25 + filterContentForSearchText(searchBar.text!)
  26 + }
  27 +
  28 + // MARK: UISearchResultsUpdating
  29 + func updateSearchResults(for searchController: UISearchController) {
  30 + filterContentForSearchText(searchController.searchBar.text!)
  31 + }
  32 +}
  1 +//
  2 +// FlieListTableView.swift
  3 +// FileBrowser
  4 +//
  5 +// Created by Roy Marmelstein on 14/02/2016.
  6 +// Copyright © 2016 Roy Marmelstein. All rights reserved.
  7 +//
  8 +
  9 +import Foundation
  10 +import UIKit
  11 +
  12 +extension FileListViewController: UITableViewDataSource, UITableViewDelegate {
  13 +
  14 + //MARK: UITableViewDataSource, UITableViewDelegate
  15 +
  16 + func numberOfSections(in tableView: UITableView) -> Int {
  17 + if searchController.isActive {
  18 + return 1
  19 + }
  20 + return sections.count
  21 + }
  22 +
  23 + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  24 + if searchController.isActive {
  25 + return filteredFiles.count
  26 + }
  27 + return sections[section].count
  28 + }
  29 +
  30 + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  31 + let cellIdentifier = "FileCell"
  32 + var cell = UITableViewCell(style: .subtitle, reuseIdentifier: cellIdentifier)
  33 + if let reuseCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) {
  34 + cell = reuseCell
  35 + }
  36 + cell.selectionStyle = .blue
  37 + let selectedFile = fileForIndexPath(indexPath)
  38 + cell.textLabel?.text = selectedFile.displayName
  39 + cell.imageView?.image = selectedFile.type.image()
  40 + return cell
  41 + }
  42 +
  43 + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  44 + let selectedFile = fileForIndexPath(indexPath)
  45 + searchController.isActive = false
  46 + if selectedFile.isDirectory {
  47 + let fileListViewController = FileListViewController(initialPath: selectedFile.filePath)
  48 + fileListViewController.didSelectFile = didSelectFile
  49 + self.navigationController?.pushViewController(fileListViewController, animated: true)
  50 + }
  51 + else {
  52 + if let didSelectFile = didSelectFile {
  53 + self.dismiss()
  54 + didSelectFile(selectedFile)
  55 + }
  56 + else {
  57 + let filePreview = previewManager.previewViewControllerForFile(selectedFile, fromNavigation: true)
  58 + self.navigationController?.pushViewController(filePreview, animated: true)
  59 + }
  60 + }
  61 + tableView.deselectRow(at: indexPath, animated: true)
  62 + }
  63 +
  64 + func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
  65 + if searchController.isActive {
  66 + return nil
  67 + }
  68 + if sections[section].count > 0 {
  69 + return collation.sectionTitles[section]
  70 + }
  71 + else {
  72 + return nil
  73 + }
  74 + }
  75 +
  76 + func sectionIndexTitles(for tableView: UITableView) -> [String]? {
  77 + if searchController.isActive {
  78 + return nil
  79 + }
  80 + return collation.sectionIndexTitles
  81 + }
  82 +
  83 + func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int {
  84 + if searchController.isActive {
  85 + return 0
  86 + }
  87 + return collation.section(forSectionIndexTitle: index)
  88 + }
  89 +
  90 + func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
  91 + if (editingStyle == UITableViewCell.EditingStyle.delete) {
  92 + let selectedFile = fileForIndexPath(indexPath)
  93 + selectedFile.delete()
  94 +
  95 + prepareData()
  96 + tableView.reloadSections([indexPath.section], with: UITableView.RowAnimation.automatic)
  97 + }
  98 + }
  99 +
  100 + func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
  101 + return allowEditing
  102 + }
  103 +
  104 +
  105 +}
  1 +//
  2 +// FileListViewController.swift
  3 +// FileBrowser
  4 +//
  5 +// Created by Roy Marmelstein on 12/02/2016.
  6 +// Copyright © 2016 Roy Marmelstein. All rights reserved.
  7 +//
  8 +
  9 +import UIKit
  10 +
  11 +class FileListViewController: UIViewController {
  12 +
  13 + // TableView
  14 + @IBOutlet weak var tableView: UITableView!
  15 + let collation = UILocalizedIndexedCollation.current()
  16 +
  17 + /// Data
  18 + var didSelectFile: ((FBFile) -> ())?
  19 + var files = [FBFile]()
  20 + var initialPath: URL?
  21 + let parser = FileParser.sharedInstance
  22 + let previewManager = PreviewManager()
  23 + var sections: [[FBFile]] = []
  24 + var allowEditing: Bool = false
  25 +
  26 + // Search controller
  27 + var filteredFiles = [FBFile]()
  28 + let searchController: UISearchController = {
  29 + let searchController = UISearchController(searchResultsController: nil)
  30 + searchController.searchBar.searchBarStyle = .minimal
  31 + searchController.searchBar.backgroundColor = UIColor.white
  32 + searchController.dimsBackgroundDuringPresentation = false
  33 + return searchController
  34 + }()
  35 +
  36 +
  37 + //MARK: Lifecycle
  38 + convenience init (initialPath: URL) {
  39 + self.init(initialPath: initialPath, showCancelButton: true)
  40 + }
  41 +
  42 + convenience init (initialPath: URL, showCancelButton: Bool) {
  43 + self.init(nibName: "FileBrowser", bundle: Bundle(for: FileListViewController.self))
  44 + self.edgesForExtendedLayout = UIRectEdge()
  45 +
  46 + // Set initial path
  47 + self.initialPath = initialPath
  48 + self.title = initialPath.lastPathComponent
  49 +
  50 + // Set search controller delegates
  51 + searchController.searchResultsUpdater = self
  52 + searchController.searchBar.delegate = self
  53 + searchController.delegate = self
  54 +
  55 + if showCancelButton {
  56 + // Add dismiss button
  57 + let dismissButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(FileListViewController.dismiss(button:)))
  58 + self.navigationItem.rightBarButtonItem = dismissButton
  59 + }
  60 + }
  61 +
  62 + deinit{
  63 + if #available(iOS 9.0, *) {
  64 + searchController.loadViewIfNeeded()
  65 + } else {
  66 + searchController.loadView()
  67 + }
  68 + }
  69 +
  70 + func prepareData() {
  71 + // Prepare data
  72 + if let initialPath = initialPath {
  73 + files = parser.filesForDirectory(initialPath)
  74 + indexFiles()
  75 + }
  76 + }
  77 +
  78 + //MARK: UIViewController
  79 +
  80 + override func viewDidLoad() {
  81 +
  82 + prepareData()
  83 +
  84 + // Set search bar
  85 + tableView.tableHeaderView = searchController.searchBar
  86 +
  87 + // Register for 3D touch
  88 + self.registerFor3DTouch()
  89 + }
  90 +
  91 + override func viewWillAppear(_ animated: Bool) {
  92 + super.viewWillAppear(animated)
  93 +
  94 + // Scroll to hide search bar
  95 + self.tableView.contentOffset = CGPoint(x: 0, y: searchController.searchBar.frame.size.height)
  96 +
  97 + // Make sure navigation bar is visible
  98 + self.navigationController?.isNavigationBarHidden = false
  99 + }
  100 +
  101 + @objc func dismiss(button: UIBarButtonItem = UIBarButtonItem()) {
  102 + self.dismiss(animated: true, completion: nil)
  103 + }
  104 +
  105 + //MARK: Data
  106 +
  107 + func indexFiles() {
  108 + let selector: Selector = #selector(getter: FBFile.displayName)
  109 + sections = Array(repeating: [], count: collation.sectionTitles.count)
  110 + if let sortedObjects = collation.sortedArray(from: files, collationStringSelector: selector) as? [FBFile]{
  111 + for object in sortedObjects {
  112 + let sectionNumber = collation.section(for: object, collationStringSelector: selector)
  113 + sections[sectionNumber].append(object)
  114 + }
  115 + }
  116 + }
  117 +
  118 + func fileForIndexPath(_ indexPath: IndexPath) -> FBFile {
  119 + var file: FBFile
  120 + if searchController.isActive {
  121 + file = filteredFiles[(indexPath as NSIndexPath).row]
  122 + }
  123 + else {
  124 + file = sections[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row]
  125 + }
  126 + return file
  127 + }
  128 +
  129 + func filterContentForSearchText(_ searchText: String) {
  130 + filteredFiles = files.filter({ (file: FBFile) -> Bool in
  131 + return file.displayName.lowercased().contains(searchText.lowercased())
  132 + })
  133 + tableView.reloadData()
  134 + }
  135 +
  136 +}
  137 +
  1 +//
  2 +// FileParser.swift
  3 +// FileBrowser
  4 +//
  5 +// Created by Roy Marmelstein on 13/02/2016.
  6 +// Copyright © 2016 Roy Marmelstein. All rights reserved.
  7 +//
  8 +
  9 +import Foundation
  10 +
  11 +class FileParser {
  12 +
  13 + static let sharedInstance = FileParser()
  14 +
  15 + var _excludesFileExtensions = [String]()
  16 +
  17 + /// Mapped for case insensitivity
  18 + var excludesFileExtensions: [String]? {
  19 + get {
  20 + return _excludesFileExtensions.map({$0.lowercased()})
  21 + }
  22 + set {
  23 + if let newValue = newValue {
  24 + _excludesFileExtensions = newValue
  25 + }
  26 + }
  27 + }
  28 +
  29 + var excludesFilepaths: [URL]?
  30 +
  31 + let fileManager = FileManager.default
  32 +
  33 + func documentsURL() -> URL {
  34 + return fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0] as URL
  35 + }
  36 +
  37 + func filesForDirectory(_ directoryPath: URL) -> [FBFile] {
  38 + var files = [FBFile]()
  39 + var filePaths = [URL]()
  40 + // Get contents
  41 + do {
  42 + filePaths = try self.fileManager.contentsOfDirectory(at: directoryPath, includingPropertiesForKeys: [], options: [.skipsHiddenFiles])
  43 + } catch {
  44 + return files
  45 + }
  46 + // Parse
  47 + for filePath in filePaths {
  48 + let file = FBFile(filePath: filePath)
  49 + if let excludesFileExtensions = excludesFileExtensions, let fileExtensions = file.fileExtension , excludesFileExtensions.contains(fileExtensions) {
  50 + continue
  51 + }
  52 + if let excludesFilepaths = excludesFilepaths , excludesFilepaths.contains(file.filePath) {
  53 + continue
  54 + }
  55 + if file.displayName.isEmpty == false {
  56 + files.append(file)
  57 + }
  58 + }
  59 + // Sort
  60 + files = files.sorted(){$0.displayName < $1.displayName}
  61 + return files
  62 + }
  63 +
  64 +}
  1 +//
  2 +// PreviewManager.swift
  3 +// FileBrowser
  4 +//
  5 +// Created by Roy Marmelstein on 16/02/2016.
  6 +// Copyright © 2016 Roy Marmelstein. All rights reserved.
  7 +//
  8 +
  9 +import Foundation
  10 +import QuickLook
  11 +
  12 +class PreviewManager: NSObject, QLPreviewControllerDataSource {
  13 +
  14 + var filePath: URL?
  15 +
  16 + func previewViewControllerForFile(_ file: FBFile, fromNavigation: Bool) -> UIViewController {
  17 +
  18 + if file.type == .PLIST || file.type == .JSON{
  19 + let webviewPreviewViewContoller = WebviewPreviewViewContoller(nibName: "WebviewPreviewViewContoller", bundle: Bundle(for: WebviewPreviewViewContoller.self))
  20 + webviewPreviewViewContoller.file = file
  21 + return webviewPreviewViewContoller
  22 + }
  23 + else {
  24 + let previewTransitionViewController = PreviewTransitionViewController(nibName: "PreviewTransitionViewController", bundle: Bundle(for: PreviewTransitionViewController.self))
  25 + previewTransitionViewController.quickLookPreviewController.dataSource = self
  26 +
  27 + self.filePath = file.filePath as URL
  28 + if fromNavigation == true {
  29 + return previewTransitionViewController.quickLookPreviewController
  30 + }
  31 + return previewTransitionViewController
  32 + }
  33 + }
  34 +
  35 +
  36 + func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
  37 + return 1
  38 + }
  39 +
  40 + func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
  41 + let item = PreviewItem()
  42 + if let filePath = filePath {
  43 + item.filePath = filePath
  44 + }
  45 + return item
  46 + }
  47 +
  48 +}
  49 +
  50 +class PreviewItem: NSObject, QLPreviewItem {
  51 +
  52 + /*!
  53 + * @abstract The URL of the item to preview.
  54 + * @discussion The URL must be a file URL.
  55 + */
  56 +
  57 + var filePath: URL?
  58 + public var previewItemURL: URL? {
  59 + if let filePath = filePath {
  60 + return filePath
  61 + }
  62 + return nil
  63 + }
  64 +
  65 +}
  1 +//
  2 +// PreviewTransitionViewController.swift
  3 +// FileBrowser
  4 +//
  5 +// Created by Roy Marmelstein on 16/02/2016.
  6 +// Copyright © 2016 Roy Marmelstein. All rights reserved.
  7 +//
  8 +
  9 +import UIKit
  10 +import QuickLook
  11 +
  12 +/// Preview Transition View Controller was created because of a bug in QLPreviewController. It seems that QLPreviewController has issues being presented from a 3D touch peek-pop gesture and is produced an unbalanced presentation warning. By wrapping it in a container, we are solving this issue.
  13 +class PreviewTransitionViewController: UIViewController {
  14 +
  15 + @IBOutlet weak var containerView: UIView!
  16 +
  17 + let quickLookPreviewController = QLPreviewController()
  18 +
  19 + override func viewDidLoad() {
  20 + super.viewDidLoad()
  21 + self.addChild(quickLookPreviewController)
  22 + containerView.addSubview(quickLookPreviewController.view)
  23 + quickLookPreviewController.view.frame = containerView.bounds
  24 + quickLookPreviewController.didMove(toParent: self)
  25 + }
  26 +
  27 +}
  1 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2 +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9532" systemVersion="15C50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
  3 + <dependencies>
  4 + <deployment identifier="iOS"/>
  5 + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9530"/>
  6 + </dependencies>
  7 + <objects>
  8 + <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="FileBrowser" customModule="FileBrowser" customModuleProvider="target">
  9 + <connections>
  10 + <outlet property="tableView" destination="DSW-B9-8cg" id="7xS-pS-2d4"/>
  11 + <outlet property="view" destination="iN0-l3-epB" id="2JG-i3-EEX"/>
  12 + </connections>
  13 + </placeholder>
  14 + <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
  15 + <view contentMode="scaleToFill" id="iN0-l3-epB">
  16 + <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
  17 + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
  18 + <subviews>
  19 + <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="DSW-B9-8cg">
  20 + <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
  21 + <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
  22 + <connections>
  23 + <outlet property="dataSource" destination="-1" id="Hco-nQ-PWA"/>
  24 + <outlet property="delegate" destination="-1" id="UPO-be-USP"/>
  25 + </connections>
  26 + </tableView>
  27 + </subviews>
  28 + <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
  29 + <constraints>
  30 + <constraint firstAttribute="bottom" secondItem="DSW-B9-8cg" secondAttribute="bottom" id="D1e-43-tqH"/>
  31 + <constraint firstItem="DSW-B9-8cg" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="mNB-8b-mrx"/>
  32 + <constraint firstAttribute="trailing" secondItem="DSW-B9-8cg" secondAttribute="trailing" id="pvd-E6-fRi"/>
  33 + <constraint firstItem="DSW-B9-8cg" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="s7s-YR-TLU"/>
  34 + </constraints>
  35 + </view>
  36 + </objects>
  37 +</document>
  1 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2 +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9532" systemVersion="15C50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
  3 + <dependencies>
  4 + <deployment identifier="iOS"/>
  5 + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9532"/>
  6 + </dependencies>
  7 + <objects>
  8 + <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="PreviewTransitionViewController" customModule="FileBrowser" customModuleProvider="target">
  9 + <connections>
  10 + <outlet property="containerView" destination="XU1-oS-O9g" id="1iD-NB-doP"/>
  11 + <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
  12 + </connections>
  13 + </placeholder>
  14 + <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
  15 + <view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
  16 + <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
  17 + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
  18 + <subviews>
  19 + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="XU1-oS-O9g">
  20 + <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
  21 + <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
  22 + </view>
  23 + </subviews>
  24 + <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
  25 + <constraints>
  26 + <constraint firstItem="XU1-oS-O9g" firstAttribute="leading" secondItem="i5M-Pr-FkT" secondAttribute="leading" id="16b-EN-UAr"/>
  27 + <constraint firstItem="XU1-oS-O9g" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" id="LcQ-I8-kyx"/>
  28 + <constraint firstAttribute="bottom" secondItem="XU1-oS-O9g" secondAttribute="bottom" id="VKY-GO-mL1"/>
  29 + <constraint firstAttribute="trailing" secondItem="XU1-oS-O9g" secondAttribute="trailing" id="kGR-cW-okX"/>
  30 + </constraints>
  31 + </view>
  32 + </objects>
  33 +</document>
  1 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2 +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9532" systemVersion="15C50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
  3 + <dependencies>
  4 + <deployment identifier="iOS"/>
  5 + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9530"/>
  6 + </dependencies>
  7 + <objects>
  8 + <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="WebviewPreviewViewContoller" customModule="FileBrowser" customModuleProvider="target">
  9 + <connections>
  10 + <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
  11 + </connections>
  12 + </placeholder>
  13 + <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
  14 + <view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
  15 + <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
  16 + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
  17 + <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
  18 + </view>
  19 + </objects>
  20 +</document>
  1 +//
  2 +// WebviewPreviewViewContoller.swift
  3 +// FileBrowser
  4 +//
  5 +// Created by Roy Marmelstein on 16/02/2016.
  6 +// Copyright © 2016 Roy Marmelstein. All rights reserved.
  7 +//
  8 +
  9 +import UIKit
  10 +import WebKit
  11 +
  12 +/// Webview for rendering items QuickLook will struggle with.
  13 +class WebviewPreviewViewContoller: UIViewController {
  14 +
  15 + var webView = WKWebView()
  16 +
  17 + var file: FBFile? {
  18 + didSet {
  19 + self.title = file?.displayName
  20 + self.processForDisplay()
  21 + }
  22 + }
  23 +
  24 + //MARK: Lifecycle
  25 +
  26 + override func viewDidLoad() {
  27 + super.viewDidLoad()
  28 + self.view.addSubview(webView)
  29 +
  30 + // Add share button
  31 + let shareButton = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(WebviewPreviewViewContoller.shareFile(_:)))
  32 + self.navigationItem.rightBarButtonItem = shareButton
  33 + }
  34 +
  35 + override func viewWillLayoutSubviews() {
  36 + super.viewWillLayoutSubviews()
  37 + webView.frame = self.view.bounds
  38 + }
  39 +
  40 + //MARK: Share
  41 +
  42 + @objc func shareFile(_ sender: UIBarButtonItem) {
  43 + guard let file = file else {
  44 + return
  45 + }
  46 + let activityViewController = UIActivityViewController(activityItems: [file.filePath], applicationActivities: nil)
  47 +
  48 + if UIDevice.current.userInterfaceIdiom == .pad &&
  49 + activityViewController.responds(to: #selector(getter: popoverPresentationController)) {
  50 + activityViewController.popoverPresentationController?.barButtonItem = sender
  51 + }
  52 +
  53 + self.present(activityViewController, animated: true, completion: nil)
  54 + }
  55 +
  56 + //MARK: Processing
  57 +
  58 + func processForDisplay() {
  59 + guard let file = file, let data = try? Data(contentsOf: file.filePath as URL) else {
  60 + return
  61 + }
  62 + var rawString: String?
  63 +
  64 + // Prepare plist for display
  65 + if file.type == .PLIST {
  66 + do {
  67 + if let plistDescription = try (PropertyListSerialization.propertyList(from: data, options: [], format: nil) as AnyObject).description {
  68 + rawString = plistDescription
  69 + }
  70 + } catch {}
  71 + }
  72 +
  73 + // Prepare json file for display
  74 + else if file.type == .JSON {
  75 + do {
  76 + let jsonObject = try JSONSerialization.jsonObject(with: data, options: [])
  77 + if JSONSerialization.isValidJSONObject(jsonObject) {
  78 + let prettyJSON = try JSONSerialization.data(withJSONObject: jsonObject, options: .prettyPrinted)
  79 + var jsonString = String(data: prettyJSON, encoding: String.Encoding.utf8)
  80 + // Unescape forward slashes
  81 + jsonString = jsonString?.replacingOccurrences(of: "\\/", with: "/")
  82 + rawString = jsonString
  83 + }
  84 + } catch {}
  85 + }
  86 +
  87 + // Default prepare for display
  88 + if rawString == nil {
  89 + rawString = String(data: data, encoding: String.Encoding.utf8)
  90 + }
  91 +
  92 + // Convert and display string
  93 + if let convertedString = convertSpecialCharacters(rawString) {
  94 + let htmlString = "<html><head><meta name='viewport' content='initial-scale=1.0, user-scalable=no'></head><body><pre>\(convertedString)</pre></body></html>"
  95 + webView.loadHTMLString(htmlString, baseURL: nil)
  96 + }
  97 +
  98 + }
  99 +
  100 +
  101 + // Make sure we convert HTML special characters
  102 + // Code from https://gist.github.com/mikesteele/70ae98d04fdc35cb1d5f
  103 + func convertSpecialCharacters(_ string: String?) -> String? {
  104 + guard let string = string else {
  105 + return nil
  106 + }
  107 + var newString = string
  108 + let char_dictionary = [
  109 + "&amp;": "&",
  110 + "&lt;": "<",
  111 + "&gt;": ">",
  112 + "&quot;": "\"",
  113 + "&apos;": "'"
  114 + ];
  115 + for (escaped_char, unescaped_char) in char_dictionary {
  116 + newString = newString.replacingOccurrences(of: escaped_char, with: unescaped_char, options: NSString.CompareOptions.regularExpression, range: nil)
  117 + }
  118 + return newString
  119 + }
  120 +}
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>aps-environment</key>
  6 + <string>development</string>
  7 +</dict>
  8 +</plist>
  1 +//
  2 +// LoginVC.swift
  3 +// hhVDoctorSDK_Example
  4 +//
  5 +// Created by Shi Jian on 2019/8/13.
  6 +// Copyright © 2019 CocoaPods. All rights reserved.
  7 +//
  8 +
  9 +import UIKit
  10 +import hhVDoctorSDK
  11 +
  12 +class LoginVC: UIViewController {
  13 +
  14 + @IBOutlet weak var mTextView: UITextView!
  15 + @IBOutlet weak var mDescLbl: UILabel!
  16 + @IBOutlet weak var mCallBtn: UIButton!
  17 + @IBOutlet weak var mLoginBtn: UIButton!
  18 + @IBOutlet weak var mMemberBtn: UIButton!
  19 + @IBOutlet weak var mPidText: UITextField!
  20 + @IBOutlet weak var mSkipHomeBt : UIButton!
  21 +
  22 +
  23 + fileprivate lazy var mTestBt : UIButton = {
  24 + let view = UIButton()
  25 + view.setTitle("自定义View", for: .normal)
  26 + return view
  27 + }()
  28 +
  29 + override func viewDidLoad() {
  30 + super.viewDidLoad()
  31 +
  32 + HHMSDK.default.add(delegate: self)
  33 +
  34 + NotificationCenter.default.addObserver(self, selector: #selector(logout), name: Notification.Name(rawValue: "onEnvChange"), object: nil)
  35 + }
  36 +
  37 +
  38 +
  39 + deinit {
  40 + NotificationCenter.default.removeObserver(self)
  41 + }
  42 +
  43 + @IBAction func doLogin(_ sender: UIButton) {
  44 +
  45 + HMDefaultOpt.productId = mPidText.text ?? ""
  46 +
  47 + self.mDescLbl.text = "登录中。。。。。"
  48 + if let userToken = mTextView.text {
  49 + HHMSDK.default.login(userToken: userToken) { [weak self] in
  50 + self?.loginComplete($0)
  51 + }
  52 + return
  53 + }
  54 +
  55 + HHMSDK.default.login(userToken: mTextView.text) { [weak self] in
  56 + self?.loginComplete($0)
  57 + }
  58 + }
  59 +
  60 + private func loginComplete(_ error: String?) {
  61 + self.view.endEditing(true)
  62 + if let aError = error {
  63 + self.mDescLbl.text = aError
  64 + } else {
  65 + self.mDescLbl.text = "登录成功啦"
  66 + mLoginBtn.isHidden = true
  67 + mCallBtn.isHidden = false
  68 + mMemberBtn.isHidden = false
  69 + mSkipHomeBt.isHidden = false
  70 + }
  71 + }
  72 +
  73 + @IBAction func doCallDoctor(_ sender: UIButton) {
  74 + HHMSDK.default.startCall(.adult)
  75 + }
  76 +
  77 + func doFetchLog(_ sender: UIBarButtonItem) {
  78 + present(FileBrowser(), animated: true, completion: nil)
  79 + }
  80 +
  81 +
  82 + @IBAction func doSelectMem(_ sender: UIButton) {
  83 + HHMSDK.default.startMemberCall()
  84 + }
  85 +
  86 +
  87 + @IBAction func doLogout(_ sender: UIBarButtonItem) {
  88 + logout()
  89 + }
  90 +
  91 +
  92 + @IBAction func skipToSetting(_ sender: UIBarButtonItem) {
  93 + self.navigationController?.pushViewController(SettingVC(), animated: true)
  94 + }
  95 +
  96 +
  97 + @IBAction func skipToHome(_ sender : UIButton) {
  98 + HHMSDK.default.skipChatHome()
  99 + }
  100 +
  101 + override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
  102 + self.view.endEditing(true)
  103 + }
  104 +
  105 + @objc func logout() {
  106 + HHMSDK.default.logout { [weak self] in
  107 + self?.mLoginBtn.isHidden = false
  108 + self?.mCallBtn.isHidden = true
  109 + self?.mMemberBtn.isHidden = true
  110 + self?.mSkipHomeBt.isHidden = true
  111 +
  112 + if let aError = $0 {
  113 + self?.mDescLbl.text = "退出登录失败:\(aError)"
  114 + } else {
  115 + self?.mDescLbl.text = "退出登录成功"
  116 + }
  117 + }
  118 + }
  119 +
  120 +}
  121 +
  122 +
  123 +
  124 +
  125 +extension LoginVC: HHMVideoDelegate {
  126 + func callStateChange(_ state: HHMCallingState) {
  127 +
  128 + }
  129 +
  130 + func callDidEstablish() {
  131 +
  132 + }
  133 +
  134 + func onFail(error: Error) {
  135 +
  136 + }
  137 +
  138 + func getChatParentView(_ view: UIView) {
  139 +
  140 + }
  141 +
  142 + func onCancel() {
  143 +
  144 + }
  145 +
  146 + func receivedOrder(_ orderId: String) {
  147 + }
  148 +
  149 + func callDidFinish() {
  150 +
  151 + }
  152 +
  153 + func onExtensionDoctor() {
  154 +
  155 + }
  156 +
  157 + func onReceive(_ callID: String) {
  158 +
  159 + }
  160 +
  161 + func onResponse(_ accept: Bool) {
  162 +
  163 + }
  164 +
  165 + func onLeakPermission(_ type: PermissionType) {
  166 +
  167 + }
  168 +
  169 +
  170 +}
No preview for this file type
  1 +{
  2 + "images" : [
  3 + {
  4 + "size" : "20x20",
  5 + "idiom" : "iphone",
  6 + "filename" : "icon-iphone-20@2x.png",
  7 + "scale" : "2x"
  8 + },
  9 + {
  10 + "size" : "20x20",
  11 + "idiom" : "iphone",
  12 + "filename" : "icon-iphone-20@3x.png",
  13 + "scale" : "3x"
  14 + },
  15 + {
  16 + "size" : "29x29",
  17 + "idiom" : "iphone",
  18 + "filename" : "icon-iphone-29@1x.png",
  19 + "scale" : "1x"
  20 + },
  21 + {
  22 + "size" : "29x29",
  23 + "idiom" : "iphone",
  24 + "filename" : "icon-iphone-29@2x.png",
  25 + "scale" : "2x"
  26 + },
  27 + {
  28 + "size" : "29x29",
  29 + "idiom" : "iphone",
  30 + "filename" : "icon-iphone-29@3x.png",
  31 + "scale" : "3x"
  32 + },
  33 + {
  34 + "size" : "40x40",
  35 + "idiom" : "iphone",
  36 + "filename" : "icon-iphone-40@2x.png",
  37 + "scale" : "2x"
  38 + },
  39 + {
  40 + "size" : "40x40",
  41 + "idiom" : "iphone",
  42 + "filename" : "icon-iphone-40@3x.png",
  43 + "scale" : "3x"
  44 + },
  45 + {
  46 + "size" : "57x57",
  47 + "idiom" : "iphone",
  48 + "filename" : "icon-iphone-57@1x.png",
  49 + "scale" : "1x"
  50 + },
  51 + {
  52 + "size" : "57x57",
  53 + "idiom" : "iphone",
  54 + "filename" : "icon-iphone-57@2x.png",
  55 + "scale" : "2x"
  56 + },
  57 + {
  58 + "size" : "60x60",
  59 + "idiom" : "iphone",
  60 + "filename" : "icon-iphone-60@2x.png",
  61 + "scale" : "2x"
  62 + },
  63 + {
  64 + "size" : "60x60",
  65 + "idiom" : "iphone",
  66 + "filename" : "icon-iphone-60@3x.png",
  67 + "scale" : "3x"
  68 + },
  69 + {
  70 + "size" : "20x20",
  71 + "idiom" : "ipad",
  72 + "filename" : "icon-ipad-20@1x.png",
  73 + "scale" : "1x"
  74 + },
  75 + {
  76 + "size" : "20x20",
  77 + "idiom" : "ipad",
  78 + "filename" : "icon-ipad-20@2x.png",
  79 + "scale" : "2x"
  80 + },
  81 + {
  82 + "size" : "29x29",
  83 + "idiom" : "ipad",
  84 + "filename" : "icon-ipad-29@1x.png",
  85 + "scale" : "1x"
  86 + },
  87 + {
  88 + "size" : "29x29",
  89 + "idiom" : "ipad",
  90 + "filename" : "icon-ipad-29@2x.png",
  91 + "scale" : "2x"
  92 + },
  93 + {
  94 + "size" : "40x40",
  95 + "idiom" : "ipad",
  96 + "filename" : "icon-ipad-40@1x.png",
  97 + "scale" : "1x"
  98 + },
  99 + {
  100 + "size" : "40x40",
  101 + "idiom" : "ipad",
  102 + "filename" : "icon-ipad-40@2x.png",
  103 + "scale" : "2x"
  104 + },
  105 + {
  106 + "size" : "76x76",
  107 + "idiom" : "ipad",
  108 + "filename" : "icon-ipad-76@1x.png",
  109 + "scale" : "1x"
  110 + },
  111 + {
  112 + "size" : "76x76",
  113 + "idiom" : "ipad",
  114 + "filename" : "icon-ipad-76@2x.png",
  115 + "scale" : "2x"
  116 + },
  117 + {
  118 + "size" : "83.5x83.5",
  119 + "idiom" : "ipad",
  120 + "filename" : "icon-ipad-83.5@2x.png",
  121 + "scale" : "2x"
  122 + },
  123 + {
  124 + "size" : "1024x1024",
  125 + "idiom" : "ios-marketing",
  126 + "filename" : "icon-ios-marketing-1024@1x.png",
  127 + "scale" : "1x"
  128 + },
  129 + {
  130 + "size" : "60x60",
  131 + "idiom" : "car",
  132 + "filename" : "icon-car-60@2x.png",
  133 + "scale" : "2x"
  134 + },
  135 + {
  136 + "size" : "60x60",
  137 + "idiom" : "car",
  138 + "filename" : "icon-car-60@3x.png",
  139 + "scale" : "3x"
  140 + },
  141 + {
  142 + "size" : "24x24",
  143 + "idiom" : "watch",
  144 + "filename" : "icon-watch-24@2x.png",
  145 + "scale" : "2x",
  146 + "role" : "notificationCenter",
  147 + "subtype" : "38mm"
  148 + },
  149 + {
  150 + "size" : "27.5x27.5",
  151 + "idiom" : "watch",
  152 + "filename" : "icon-watch-27.5@2x.png",
  153 + "scale" : "2x",
  154 + "role" : "notificationCenter",
  155 + "subtype" : "42mm"
  156 + },
  157 + {
  158 + "size" : "29x29",
  159 + "idiom" : "watch",
  160 + "filename" : "icon-watch-29@2x.png",
  161 + "role" : "companionSettings",
  162 + "scale" : "2x"
  163 + },
  164 + {
  165 + "size" : "29x29",
  166 + "idiom" : "watch",
  167 + "filename" : "icon-watch-29@3x.png",
  168 + "role" : "companionSettings",
  169 + "scale" : "3x"
  170 + },
  171 + {
  172 + "size" : "40x40",
  173 + "idiom" : "watch",
  174 + "filename" : "icon-watch-40@2x.png",
  175 + "scale" : "2x",
  176 + "role" : "appLauncher",
  177 + "subtype" : "38mm"
  178 + },
  179 + {
  180 + "size" : "44x44",
  181 + "idiom" : "watch",
  182 + "scale" : "2x",
  183 + "role" : "appLauncher",
  184 + "subtype" : "40mm"
  185 + },
  186 + {
  187 + "size" : "50x50",
  188 + "idiom" : "watch",
  189 + "scale" : "2x",
  190 + "role" : "appLauncher",
  191 + "subtype" : "44mm"
  192 + },
  193 + {
  194 + "size" : "86x86",
  195 + "idiom" : "watch",
  196 + "filename" : "icon-watch-86@2x.png",
  197 + "scale" : "2x",
  198 + "role" : "quickLook",
  199 + "subtype" : "38mm"
  200 + },
  201 + {
  202 + "size" : "98x98",
  203 + "idiom" : "watch",
  204 + "filename" : "icon-watch-98@2x.png",
  205 + "scale" : "2x",
  206 + "role" : "quickLook",
  207 + "subtype" : "42mm"
  208 + },
  209 + {
  210 + "size" : "108x108",
  211 + "idiom" : "watch",
  212 + "scale" : "2x",
  213 + "role" : "quickLook",
  214 + "subtype" : "44mm"
  215 + },
  216 + {
  217 + "size" : "1024x1024",
  218 + "idiom" : "watch-marketing",
  219 + "filename" : "icon-watch-marketing-1024@1x.png",
  220 + "scale" : "1x"
  221 + },
  222 + {
  223 + "size" : "16x16",
  224 + "idiom" : "mac",
  225 + "filename" : "icon-mac-16@1x.png",
  226 + "scale" : "1x"
  227 + },
  228 + {
  229 + "size" : "16x16",
  230 + "idiom" : "mac",
  231 + "filename" : "icon-mac-16@2x.png",
  232 + "scale" : "2x"
  233 + },
  234 + {
  235 + "size" : "32x32",
  236 + "idiom" : "mac",
  237 + "filename" : "icon-mac-32@1x.png",
  238 + "scale" : "1x"
  239 + },
  240 + {
  241 + "size" : "32x32",
  242 + "idiom" : "mac",
  243 + "filename" : "icon-mac-32@2x.png",
  244 + "scale" : "2x"
  245 + },
  246 + {
  247 + "size" : "128x128",
  248 + "idiom" : "mac",
  249 + "filename" : "icon-mac-128@1x.png",
  250 + "scale" : "1x"
  251 + },
  252 + {
  253 + "size" : "128x128",
  254 + "idiom" : "mac",
  255 + "filename" : "icon-mac-128@2x.png",
  256 + "scale" : "2x"
  257 + },
  258 + {
  259 + "size" : "256x256",
  260 + "idiom" : "mac",
  261 + "filename" : "icon-mac-256@1x.png",
  262 + "scale" : "1x"
  263 + },
  264 + {
  265 + "size" : "256x256",
  266 + "idiom" : "mac",
  267 + "filename" : "icon-mac-256@2x.png",
  268 + "scale" : "2x"
  269 + },
  270 + {
  271 + "size" : "512x512",
  272 + "idiom" : "mac",
  273 + "filename" : "icon-mac-512@1x.png",
  274 + "scale" : "1x"
  275 + },
  276 + {
  277 + "size" : "512x512",
  278 + "idiom" : "mac",
  279 + "filename" : "icon-mac-512@2x.png",
  280 + "scale" : "2x"
  281 + }
  282 + ],
  283 + "info" : {
  284 + "version" : 1,
  285 + "author" : "xcode"
  286 + }
  287 +}
  1 +{
  2 + "info" : {
  3 + "version" : 1,
  4 + "author" : "xcode"
  5 + }
  6 +}
  1 +{
  2 + "images" : [
  3 + {
  4 + "idiom" : "universal",
  5 + "scale" : "1x"
  6 + },
  7 + {
  8 + "idiom" : "universal",
  9 + "scale" : "2x"
  10 + },
  11 + {
  12 + "idiom" : "universal",
  13 + "filename" : "未命名.png",
  14 + "scale" : "3x"
  15 + }
  16 + ],
  17 + "info" : {
  18 + "version" : 1,
  19 + "author" : "xcode"
  20 + }
  21 +}
  1 +{
  2 + "images" : [
  3 + {
  4 + "idiom" : "universal",
  5 + "scale" : "1x"
  6 + },
  7 + {
  8 + "idiom" : "universal",
  9 + "scale" : "2x"
  10 + },
  11 + {
  12 + "idiom" : "universal",
  13 + "filename" : "未命名.png",
  14 + "scale" : "3x"
  15 + }
  16 + ],
  17 + "info" : {
  18 + "version" : 1,
  19 + "author" : "xcode"
  20 + }
  21 +}
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
  3 + <device id="retina4_7" orientation="portrait">
  4 + <adaptation id="fullscreen"/>
  5 + </device>
  6 + <dependencies>
  7 + <deployment identifier="iOS"/>
  8 + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
  9 + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
  10 + </dependencies>
  11 + <scenes>
  12 + <!--View Controller-->
  13 + <scene sceneID="EHf-IW-A2E">
  14 + <objects>
  15 + <viewController id="01J-lp-oVM" sceneMemberID="viewController">
  16 + <layoutGuides>
  17 + <viewControllerLayoutGuide type="top" id="mxh-vO-G0r"/>
  18 + <viewControllerLayoutGuide type="bottom" id="KRc-2I-rx2"/>
  19 + </layoutGuides>
  20 + <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
  21 + <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
  22 + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
  23 + <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
  24 + </view>
  25 + </viewController>
  26 + <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
  27 + </objects>
  28 + <point key="canvasLocation" x="53" y="375"/>
  29 + </scene>
  30 + </scenes>
  31 +</document>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17506" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="gh6-uF-nli">
  3 + <device id="retina4_7" orientation="portrait" appearance="light"/>
  4 + <dependencies>
  5 + <deployment identifier="iOS"/>
  6 + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17505"/>
  7 + <capability name="System colors in document resources" minToolsVersion="11.0"/>
  8 + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
  9 + </dependencies>
  10 + <scenes>
  11 + <!--LoginVC-->
  12 + <scene sceneID="ZuK-Ew-nhs">
  13 + <objects>
  14 + <viewController id="H9G-Cx-5aF" customClass="LoginVC" customModule="HHTMedicSDK" customModuleProvider="target" sceneMemberID="viewController">
  15 + <layoutGuides>
  16 + <viewControllerLayoutGuide type="top" id="pvb-0q-YKi"/>
  17 + <viewControllerLayoutGuide type="bottom" id="N1D-F5-d1D"/>
  18 + </layoutGuides>
  19 + <view key="view" contentMode="scaleToFill" id="Hxg-q0-rWs">
  20 + <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
  21 + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
  22 + <subviews>
  23 + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="UserToken" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WDq-Dc-IOR">
  24 + <rect key="frame" x="36" y="142" width="72.5" height="21"/>
  25 + <constraints>
  26 + <constraint firstAttribute="height" constant="21" id="Qym-cy-jy5"/>
  27 + </constraints>
  28 + <fontDescription key="fontDescription" type="system" pointSize="15"/>
  29 + <color key="textColor" red="0.39215686274509803" green="0.39215686274509803" blue="0.39215686274509803" alpha="1" colorSpace="calibratedRGB"/>
  30 + <nil key="highlightedColor"/>
  31 + </label>
  32 + <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" text="EC313F3198AF4F1972484E49E718D4DED7B294C6D4F4B9CB52C7CC1AF9E5140B" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="tXq-br-C4i">
  33 + <rect key="frame" x="141" y="102.5" width="198" height="100"/>
  34 + <color key="backgroundColor" systemColor="systemBackgroundColor"/>
  35 + <constraints>
  36 + <constraint firstAttribute="height" constant="100" id="Zws-8I-LUM"/>
  37 + </constraints>
  38 + <color key="textColor" systemColor="labelColor"/>
  39 + <fontDescription key="fontDescription" type="system" pointSize="14"/>
  40 + <textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
  41 + <userDefinedRuntimeAttributes>
  42 + <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
  43 + <real key="value" value="5"/>
  44 + </userDefinedRuntimeAttribute>
  45 + <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
  46 + <color key="value" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
  47 + </userDefinedRuntimeAttribute>
  48 + <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
  49 + <real key="value" value="1"/>
  50 + </userDefinedRuntimeAttribute>
  51 + </userDefinedRuntimeAttributes>
  52 + </textView>
  53 + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="poL-z9-aP0">
  54 + <rect key="frame" x="46" y="222.5" width="283" height="50"/>
  55 + <color key="backgroundColor" red="0.4823529412" green="0.81176470590000005" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
  56 + <constraints>
  57 + <constraint firstAttribute="height" constant="50" id="fmI-rh-0vj"/>
  58 + </constraints>
  59 + <fontDescription key="fontDescription" type="system" pointSize="18"/>
  60 + <state key="normal" title="登录">
  61 + <color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
  62 + </state>
  63 + <connections>
  64 + <action selector="doLogin:" destination="H9G-Cx-5aF" eventType="touchUpInside" id="IZB-Q4-BaE"/>
  65 + </connections>
  66 + </button>
  67 + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3Ez-hY-hE0">
  68 + <rect key="frame" x="187.5" y="632" width="0.0" height="0.0"/>
  69 + <fontDescription key="fontDescription" type="system" pointSize="17"/>
  70 + <color key="textColor" systemColor="systemRedColor"/>
  71 + <nil key="highlightedColor"/>
  72 + </label>
  73 + <button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="8W4-aR-lG5">
  74 + <rect key="frame" x="46" y="297.5" width="283" height="50"/>
  75 + <color key="backgroundColor" red="0.4823529412" green="0.81176470590000005" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
  76 + <constraints>
  77 + <constraint firstAttribute="height" constant="50" id="f5W-D8-mbx"/>
  78 + </constraints>
  79 + <fontDescription key="fontDescription" type="system" pointSize="18"/>
  80 + <state key="normal" title="呼叫">
  81 + <color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
  82 + </state>
  83 + <connections>
  84 + <action selector="doCallDoctor:" destination="H9G-Cx-5aF" eventType="touchUpInside" id="pFm-6N-W2f"/>
  85 + </connections>
  86 + </button>
  87 + <button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="8oo-l9-0xS">
  88 + <rect key="frame" x="46" y="367.5" width="283" height="50"/>
  89 + <color key="backgroundColor" red="0.4823529412" green="0.81176470590000005" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
  90 + <constraints>
  91 + <constraint firstAttribute="height" constant="50" id="7i8-xT-rsZ"/>
  92 + </constraints>
  93 + <fontDescription key="fontDescription" type="system" pointSize="18"/>
  94 + <state key="normal" title="选成员呼叫">
  95 + <color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
  96 + </state>
  97 + <connections>
  98 + <action selector="doSelectMem:" destination="H9G-Cx-5aF" eventType="touchUpInside" id="SnD-7P-d52"/>
  99 + </connections>
  100 + </button>
  101 + <button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="HAJ-cu-o1I">
  102 + <rect key="frame" x="46" y="427.5" width="283" height="50"/>
  103 + <color key="backgroundColor" red="0.026365790516138077" green="0.7069585919380188" blue="0.95850151777267456" alpha="0.9990234375" colorSpace="custom" customColorSpace="sRGB"/>
  104 + <constraints>
  105 + <constraint firstAttribute="height" constant="50" id="VyT-1E-E2P"/>
  106 + </constraints>
  107 + <state key="normal" title="跳转首页">
  108 + <color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
  109 + </state>
  110 + <connections>
  111 + <action selector="skipToHome:" destination="H9G-Cx-5aF" eventType="touchUpInside" id="Ogg-hL-Exq"/>
  112 + </connections>
  113 + </button>
  114 + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="SDKProductID" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vGE-5O-Jnp">
  115 + <rect key="frame" x="36" y="74" width="99" height="18"/>
  116 + <fontDescription key="fontDescription" type="system" pointSize="15"/>
  117 + <color key="textColor" red="0.39215686274509803" green="0.39215686274509803" blue="0.39215686274509803" alpha="1" colorSpace="calibratedRGB"/>
  118 + <nil key="highlightedColor"/>
  119 + </label>
  120 + <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="3000" borderStyle="roundedRect" placeholder="PID" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="LMZ-Wb-ONz">
  121 + <rect key="frame" x="150" y="64" width="150" height="34"/>
  122 + <constraints>
  123 + <constraint firstAttribute="width" constant="150" id="prH-ou-yPD"/>
  124 + </constraints>
  125 + <fontDescription key="fontDescription" type="system" pointSize="14"/>
  126 + <textInputTraits key="textInputTraits"/>
  127 + </textField>
  128 + </subviews>
  129 + <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
  130 + <constraints>
  131 + <constraint firstItem="poL-z9-aP0" firstAttribute="leading" secondItem="Hxg-q0-rWs" secondAttribute="leadingMargin" constant="30" id="08P-cp-x8V"/>
  132 + <constraint firstItem="N1D-F5-d1D" firstAttribute="top" secondItem="3Ez-hY-hE0" secondAttribute="bottom" constant="35" id="3Cc-qG-aGS"/>
  133 + <constraint firstAttribute="trailingMargin" secondItem="tXq-br-C4i" secondAttribute="trailing" constant="20" id="5SM-6s-gZW"/>
  134 + <constraint firstItem="8W4-aR-lG5" firstAttribute="leading" secondItem="poL-z9-aP0" secondAttribute="leading" id="759-Km-ew6"/>
  135 + <constraint firstItem="8oo-l9-0xS" firstAttribute="top" secondItem="8W4-aR-lG5" secondAttribute="bottom" constant="20" id="EAP-M1-bdr"/>
  136 + <constraint firstItem="8W4-aR-lG5" firstAttribute="trailing" secondItem="poL-z9-aP0" secondAttribute="trailing" id="F1C-Hs-hbp"/>
  137 + <constraint firstItem="LMZ-Wb-ONz" firstAttribute="top" secondItem="pvb-0q-YKi" secondAttribute="bottom" constant="20" id="Iah-4z-DFT"/>
  138 + <constraint firstItem="vGE-5O-Jnp" firstAttribute="leading" secondItem="Hxg-q0-rWs" secondAttribute="leadingMargin" constant="20" id="Iya-4o-Iwp"/>
  139 + <constraint firstItem="poL-z9-aP0" firstAttribute="centerX" secondItem="Hxg-q0-rWs" secondAttribute="centerX" id="JXA-Aj-bZr"/>
  140 + <constraint firstItem="tXq-br-C4i" firstAttribute="leading" secondItem="WDq-Dc-IOR" secondAttribute="trailing" constant="32.5" id="NTI-wJ-aEi"/>
  141 + <constraint firstAttribute="trailingMargin" secondItem="poL-z9-aP0" secondAttribute="trailing" constant="30" id="Rmf-K6-ydN"/>
  142 + <constraint firstItem="vGE-5O-Jnp" firstAttribute="top" secondItem="pvb-0q-YKi" secondAttribute="bottom" constant="30" id="Rsv-UR-KGj"/>
  143 + <constraint firstItem="WDq-Dc-IOR" firstAttribute="top" secondItem="vGE-5O-Jnp" secondAttribute="bottom" constant="50" id="UuJ-ZL-pny"/>
  144 + <constraint firstItem="8oo-l9-0xS" firstAttribute="leading" secondItem="8W4-aR-lG5" secondAttribute="leading" id="ZWz-DC-qe9"/>
  145 + <constraint firstItem="tXq-br-C4i" firstAttribute="centerY" secondItem="WDq-Dc-IOR" secondAttribute="centerY" id="d6z-rc-7Hm"/>
  146 + <constraint firstItem="HAJ-cu-o1I" firstAttribute="leading" secondItem="Hxg-q0-rWs" secondAttribute="leadingMargin" constant="30" id="gbT-y9-FiN"/>
  147 + <constraint firstItem="8oo-l9-0xS" firstAttribute="trailing" secondItem="8W4-aR-lG5" secondAttribute="trailing" id="hEl-M1-WZ9"/>
  148 + <constraint firstItem="8W4-aR-lG5" firstAttribute="centerX" secondItem="Hxg-q0-rWs" secondAttribute="centerX" id="k7H-CD-dJB"/>
  149 + <constraint firstItem="8W4-aR-lG5" firstAttribute="top" secondItem="poL-z9-aP0" secondAttribute="bottom" constant="25" id="lbY-4y-PGG"/>
  150 + <constraint firstAttribute="trailingMargin" secondItem="HAJ-cu-o1I" secondAttribute="trailing" constant="30" id="n3M-dU-lw9"/>
  151 + <constraint firstItem="LMZ-Wb-ONz" firstAttribute="leading" secondItem="Hxg-q0-rWs" secondAttribute="leading" constant="150" id="n6s-bX-QgY"/>
  152 + <constraint firstItem="3Ez-hY-hE0" firstAttribute="centerX" secondItem="Hxg-q0-rWs" secondAttribute="centerX" id="tNe-km-eME"/>
  153 + <constraint firstItem="WDq-Dc-IOR" firstAttribute="leading" secondItem="Hxg-q0-rWs" secondAttribute="leadingMargin" constant="20" id="wmc-fH-91m"/>
  154 + <constraint firstItem="poL-z9-aP0" firstAttribute="top" secondItem="tXq-br-C4i" secondAttribute="bottom" constant="20" id="xXs-dA-lRG"/>
  155 + <constraint firstItem="HAJ-cu-o1I" firstAttribute="top" secondItem="8oo-l9-0xS" secondAttribute="bottom" constant="10" id="xc5-7d-vGv"/>
  156 + </constraints>
  157 + </view>
  158 + <navigationItem key="navigationItem" id="83O-Gf-RkC">
  159 + <barButtonItem key="leftBarButtonItem" title="Logout" id="3UJ-cd-D74">
  160 + <connections>
  161 + <action selector="doLogout:" destination="H9G-Cx-5aF" id="Fig-Ir-vhd"/>
  162 + </connections>
  163 + </barButtonItem>
  164 + <barButtonItem key="rightBarButtonItem" title="Setting" id="b2y-iJ-fLR">
  165 + <connections>
  166 + <action selector="skipToSetting:" destination="H9G-Cx-5aF" id="pUD-da-DSc"/>
  167 + <segue destination="o3F-Mf-qyV" kind="show" id="hvD-3C-d6A"/>
  168 + </connections>
  169 + </barButtonItem>
  170 + </navigationItem>
  171 + <connections>
  172 + <outlet property="mCallBtn" destination="8W4-aR-lG5" id="2EB-0y-WTr"/>
  173 + <outlet property="mDescLbl" destination="3Ez-hY-hE0" id="qh2-su-Z4g"/>
  174 + <outlet property="mLoginBtn" destination="poL-z9-aP0" id="iZz-fi-zBw"/>
  175 + <outlet property="mMemberBtn" destination="8oo-l9-0xS" id="jkY-bH-DFI"/>
  176 + <outlet property="mPidText" destination="LMZ-Wb-ONz" id="3LE-zP-K1g"/>
  177 + <outlet property="mSkipHomeBt" destination="HAJ-cu-o1I" id="TNg-Ha-66n"/>
  178 + <outlet property="mTextView" destination="tXq-br-C4i" id="jhn-qC-kjs"/>
  179 + </connections>
  180 + </viewController>
  181 + <placeholder placeholderIdentifier="IBFirstResponder" id="v4Z-Mu-IOA" userLabel="First Responder" sceneMemberID="firstResponder"/>
  182 + </objects>
  183 + <point key="canvasLocation" x="1276" y="-564.46776611694156"/>
  184 + </scene>
  185 + <!--SettingVC-->
  186 + <scene sceneID="pv9-J4-of0">
  187 + <objects>
  188 + <viewController id="o3F-Mf-qyV" customClass="SettingVC" customModule="HHTMedicSDK" customModuleProvider="target" sceneMemberID="viewController">
  189 + <layoutGuides>
  190 + <viewControllerLayoutGuide type="top" id="B3S-wn-Uqm"/>
  191 + <viewControllerLayoutGuide type="bottom" id="YOS-cd-yhV"/>
  192 + </layoutGuides>
  193 + <view key="view" contentMode="scaleToFill" id="ikE-2s-Q0T">
  194 + <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
  195 + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
  196 + <subviews>
  197 + <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="eh5-6k-Uxb">
  198 + <rect key="frame" x="0.0" y="44" width="375" height="623"/>
  199 + <color key="backgroundColor" systemColor="systemBackgroundColor"/>
  200 + <prototypes>
  201 + <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="SettingCell" id="Bgf-fW-wAR" customClass="SettingCell" customModule="HHTMedicSDK" customModuleProvider="target">
  202 + <rect key="frame" x="0.0" y="28" width="375" height="43.5"/>
  203 + <autoresizingMask key="autoresizingMask"/>
  204 + <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Bgf-fW-wAR" id="Ied-xa-MDf">
  205 + <rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
  206 + <autoresizingMask key="autoresizingMask"/>
  207 + <subviews>
  208 + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="我的会员" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qh8-Mt-OiA">
  209 + <rect key="frame" x="24" y="13" width="61.5" height="18"/>
  210 + <fontDescription key="fontDescription" type="system" pointSize="15"/>
  211 + <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
  212 + <nil key="highlightedColor"/>
  213 + </label>
  214 + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Ccv-Ta-jof" userLabel="bottomSegView">
  215 + <rect key="frame" x="15" y="43" width="345" height="0.5"/>
  216 + <color key="backgroundColor" red="0.82352941180000006" green="0.82352941180000006" blue="0.82352941180000006" alpha="1" colorSpace="calibratedRGB"/>
  217 + <constraints>
  218 + <constraint firstAttribute="height" constant="0.5" id="Hs2-19-L0z"/>
  219 + </constraints>
  220 + </view>
  221 + <switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Zbo-Ef-REA">
  222 + <rect key="frame" x="314" y="6.5" width="51" height="31"/>
  223 + <connections>
  224 + <action selector="onSwitch:" destination="Bgf-fW-wAR" eventType="valueChanged" id="fsQ-f1-F3c"/>
  225 + </connections>
  226 + </switch>
  227 + <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="arrow" translatesAutoresizingMaskIntoConstraints="NO" id="ouN-jM-aYb">
  228 + <rect key="frame" x="347" y="12.5" width="12" height="19"/>
  229 + <constraints>
  230 + <constraint firstAttribute="width" constant="12" id="4sn-RK-Yle"/>
  231 + <constraint firstAttribute="height" constant="19" id="cd4-xL-CV1"/>
  232 + </constraints>
  233 + </imageView>
  234 + </subviews>
  235 + <constraints>
  236 + <constraint firstAttribute="bottom" secondItem="Ccv-Ta-jof" secondAttribute="bottom" id="4tv-UT-sC0"/>
  237 + <constraint firstAttribute="trailing" secondItem="Ccv-Ta-jof" secondAttribute="trailing" constant="15" id="CQB-Br-Dcz"/>
  238 + <constraint firstAttribute="trailing" secondItem="ouN-jM-aYb" secondAttribute="trailing" constant="16" id="ST8-J9-K8Z"/>
  239 + <constraint firstItem="Zbo-Ef-REA" firstAttribute="centerY" secondItem="Ied-xa-MDf" secondAttribute="centerY" id="a3J-Lx-2dJ"/>
  240 + <constraint firstItem="Zbo-Ef-REA" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="qh8-Mt-OiA" secondAttribute="trailing" constant="8" symbolic="YES" id="d1F-ka-Lpo"/>
  241 + <constraint firstItem="qh8-Mt-OiA" firstAttribute="centerY" secondItem="Ied-xa-MDf" secondAttribute="centerY" id="dIf-jB-2Aa"/>
  242 + <constraint firstAttribute="trailing" secondItem="Zbo-Ef-REA" secondAttribute="trailing" constant="12" id="iEC-zB-Dx3"/>
  243 + <constraint firstItem="Ccv-Ta-jof" firstAttribute="leading" secondItem="Ied-xa-MDf" secondAttribute="leading" constant="15" id="kT1-L4-hKw"/>
  244 + <constraint firstItem="ouN-jM-aYb" firstAttribute="centerY" secondItem="Ied-xa-MDf" secondAttribute="centerY" id="nS2-Xg-HjM"/>
  245 + <constraint firstItem="qh8-Mt-OiA" firstAttribute="leading" secondItem="Ied-xa-MDf" secondAttribute="leadingMargin" constant="8" id="xE3-E4-gep"/>
  246 + </constraints>
  247 + </tableViewCellContentView>
  248 + <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
  249 + <connections>
  250 + <outlet property="mArrow" destination="ouN-jM-aYb" id="MBw-6c-SMX"/>
  251 + <outlet property="mSwitch" destination="Zbo-Ef-REA" id="0GG-mU-DNJ"/>
  252 + <outlet property="mTitleLabel" destination="qh8-Mt-OiA" id="5C1-GX-cGS"/>
  253 + </connections>
  254 + </tableViewCell>
  255 + </prototypes>
  256 + </tableView>
  257 + </subviews>
  258 + <color key="backgroundColor" systemColor="systemBackgroundColor"/>
  259 + <constraints>
  260 + <constraint firstItem="eh5-6k-Uxb" firstAttribute="top" secondItem="B3S-wn-Uqm" secondAttribute="bottom" id="8Xy-Ig-Yrc"/>
  261 + <constraint firstItem="eh5-6k-Uxb" firstAttribute="leading" secondItem="ikE-2s-Q0T" secondAttribute="leading" id="NZa-4U-bs1"/>
  262 + <constraint firstAttribute="trailing" secondItem="eh5-6k-Uxb" secondAttribute="trailing" id="izp-CQ-b8W"/>
  263 + <constraint firstItem="YOS-cd-yhV" firstAttribute="top" secondItem="eh5-6k-Uxb" secondAttribute="bottom" id="vxB-av-hT1"/>
  264 + </constraints>
  265 + </view>
  266 + <navigationItem key="navigationItem" id="iuy-if-vaC"/>
  267 + <connections>
  268 + <outlet property="mTableView" destination="eh5-6k-Uxb" id="6LO-na-jqN"/>
  269 + </connections>
  270 + </viewController>
  271 + <placeholder placeholderIdentifier="IBFirstResponder" id="dpQ-t3-68Q" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
  272 + </objects>
  273 + <point key="canvasLocation" x="2416" y="-561"/>
  274 + </scene>
  275 + <!--Navigation Controller-->
  276 + <scene sceneID="Ua6-og-koi">
  277 + <objects>
  278 + <navigationController automaticallyAdjustsScrollViewInsets="NO" id="gh6-uF-nli" sceneMemberID="viewController">
  279 + <toolbarItems/>
  280 + <navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="cEw-75-F2t">
  281 + <rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
  282 + <autoresizingMask key="autoresizingMask"/>
  283 + </navigationBar>
  284 + <nil name="viewControllers"/>
  285 + <connections>
  286 + <segue destination="H9G-Cx-5aF" kind="relationship" relationship="rootViewController" id="5Cg-Jb-tFa"/>
  287 + </connections>
  288 + </navigationController>
  289 + <placeholder placeholderIdentifier="IBFirstResponder" id="AC6-lg-e6E" userLabel="First Responder" sceneMemberID="firstResponder"/>
  290 + </objects>
  291 + <point key="canvasLocation" x="133.59999999999999" y="-564.46776611694156"/>
  292 + </scene>
  293 + </scenes>
  294 + <resources>
  295 + <image name="arrow" width="6" height="9.5"/>
  296 + <systemColor name="labelColor">
  297 + <color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
  298 + </systemColor>
  299 + <systemColor name="systemBackgroundColor">
  300 + <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
  301 + </systemColor>
  302 + <systemColor name="systemRedColor">
  303 + <color red="1" green="0.23137254901960785" blue="0.18823529411764706" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
  304 + </systemColor>
  305 + </resources>
  306 +</document>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>CFBundleDevelopmentRegion</key>
  6 + <string>$(DEVELOPMENT_LANGUAGE)</string>
  7 + <key>CFBundleDisplayName</key>
  8 + <string>视频SDK&lt;腾讯版&gt;</string>
  9 + <key>CFBundleExecutable</key>
  10 + <string>$(EXECUTABLE_NAME)</string>
  11 + <key>CFBundleIdentifier</key>
  12 + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
  13 + <key>CFBundleInfoDictionaryVersion</key>
  14 + <string>6.0</string>
  15 + <key>CFBundleName</key>
  16 + <string>$(PRODUCT_NAME)</string>
  17 + <key>CFBundlePackageType</key>
  18 + <string>APPL</string>
  19 + <key>CFBundleShortVersionString</key>
  20 + <string>$(MARKETING_VERSION)</string>
  21 + <key>CFBundleURLTypes</key>
  22 + <array>
  23 + <dict>
  24 + <key>CFBundleTypeRole</key>
  25 + <string>Editor</string>
  26 + <key>CFBundleURLName</key>
  27 + <string>jtDoctors</string>
  28 + </dict>
  29 + <dict>
  30 + <key>CFBundleTypeRole</key>
  31 + <string>Editor</string>
  32 + <key>CFBundleURLName</key>
  33 + <string>eleme</string>
  34 + <key>CFBundleURLSchemes</key>
  35 + <array>
  36 + <string>cash.tb.ele.me</string>
  37 + </array>
  38 + </dict>
  39 + <dict>
  40 + <key>CFBundleTypeRole</key>
  41 + <string>Editor</string>
  42 + <key>CFBundleURLSchemes</key>
  43 + <array>
  44 + <string>HHPay</string>
  45 + </array>
  46 + </dict>
  47 + <dict>
  48 + <key>CFBundleTypeRole</key>
  49 + <string>Editor</string>
  50 + <key>CFBundleURLSchemes</key>
  51 + <array>
  52 + <string>hh-medic.com</string>
  53 + </array>
  54 + </dict>
  55 + <dict>
  56 + <key>CFBundleTypeRole</key>
  57 + <string>Editor</string>
  58 + <key>CFBundleURLSchemes</key>
  59 + <array>
  60 + <string>alipays</string>
  61 + </array>
  62 + </dict>
  63 + </array>
  64 + <key>CFBundleVersion</key>
  65 + <string>$(CURRENT_PROJECT_VERSION)</string>
  66 + <key>LSApplicationQueriesSchemes</key>
  67 + <array>
  68 + <string>jtDoctors</string>
  69 + </array>
  70 + <key>LSRequiresIPhoneOS</key>
  71 + <true/>
  72 + <key>NSCameraUsageDescription</key>
  73 + <string>应用需使用相机权限,以便您向医生进行视频咨询。</string>
  74 + <key>NSMicrophoneUsageDescription</key>
  75 + <string>应用需使用麦克风权限,以便您向医生进行视频咨询。</string>
  76 + <key>NSPhotoLibraryUsageDescription</key>
  77 + <string>应用需要使用相册权限,以便您向医生发送健康资料。</string>
  78 + <key>UIBackgroundModes</key>
  79 + <array>
  80 + <string>audio</string>
  81 + </array>
  82 + <key>UILaunchStoryboardName</key>
  83 + <string>LaunchScreen</string>
  84 + <key>UIMainStoryboardFile</key>
  85 + <string>Main</string>
  86 + <key>UIRequiredDeviceCapabilities</key>
  87 + <array>
  88 + <string>armv7</string>
  89 + </array>
  90 + <key>UISupportedInterfaceOrientations</key>
  91 + <array>
  92 + <string>UIInterfaceOrientationPortrait</string>
  93 + <string>UIInterfaceOrientationLandscapeLeft</string>
  94 + <string>UIInterfaceOrientationLandscapeRight</string>
  95 + </array>
  96 + <key>UISupportedInterfaceOrientations~ipad</key>
  97 + <array>
  98 + <string>UIInterfaceOrientationPortrait</string>
  99 + <string>UIInterfaceOrientationPortraitUpsideDown</string>
  100 + <string>UIInterfaceOrientationLandscapeLeft</string>
  101 + <string>UIInterfaceOrientationLandscapeRight</string>
  102 + </array>
  103 +</dict>
  104 +</plist>
  1 +
  2 +/* Class = "UIButton"; normalTitle = "登录"; ObjectID = "2kg-pY-iKv"; */
  3 +"2kg-pY-iKv.normalTitle" = "登录";
  4 +
  5 +/* Class = "UIBarButtonItem"; title = "退出登录"; ObjectID = "4RM-f4-f9F"; */
  6 +"4RM-f4-f9F.title" = "退出登录";
  7 +
  8 +/* Class = "UINavigationItem"; title = "选择功能"; ObjectID = "4yA-pt-Rni"; */
  9 +"4yA-pt-Rni.title" = "选择功能";
  10 +
  11 +/* Class = "UILabel"; text = "病历详情"; ObjectID = "5GK-Mz-7TS"; */
  12 +"5GK-Mz-7TS.text" = "病历详情";
  13 +
  14 +/* Class = "UILabel"; text = "病历列表"; ObjectID = "6kM-Rr-8VS"; */
  15 +"6kM-Rr-8VS.text" = "病历列表";
  16 +
  17 +/* Class = "UILabel"; text = "呼叫 + 代理"; ObjectID = "B2q-aP-Gz6"; */
  18 +"B2q-aP-Gz6.text" = "呼叫 + 代理";
  19 +
  20 +/* Class = "UIViewController"; title = "基础呼叫"; ObjectID = "BYZ-38-t0r"; */
  21 +"BYZ-38-t0r.title" = "基础呼叫";
  22 +
  23 +/* Class = "UITableViewSection"; headerTitle = "基础功能"; ObjectID = "CJa-GO-2lr"; */
  24 +"CJa-GO-2lr.headerTitle" = "基础功能";
  25 +
  26 +/* Class = "UIViewController"; title = "呼叫+代理"; ObjectID = "Lgg-lI-rF9"; */
  27 +"Lgg-lI-rF9.title" = "呼叫+代理";
  28 +
  29 +/* Class = "UIButton"; normalTitle = "成人"; ObjectID = "PcZ-Ef-iOf"; */
  30 +"PcZ-Ef-iOf.normalTitle" = "成人";
  31 +
  32 +/* Class = "UINavigationItem"; title = "HHMSDK demo"; ObjectID = "Qyt-dy-OuG"; */
  33 +"Qyt-dy-OuG.title" = "HHMSDK demo";
  34 +
  35 +/* Class = "UIButton"; normalTitle = "成人"; ObjectID = "cFf-AB-SPw"; */
  36 +"cFf-AB-SPw.normalTitle" = "成人";
  37 +
  38 +/* Class = "UIButton"; normalTitle = "儿童"; ObjectID = "cKb-i3-JxQ"; */
  39 +"cKb-i3-JxQ.normalTitle" = "儿童";
  40 +
  41 +/* Class = "UIViewController"; title = "HHMSDK demo"; ObjectID = "cO3-cq-YaO"; */
  42 +"cO3-cq-YaO.title" = "HHMSDK demo";
  43 +
  44 +/* Class = "UIButton"; normalTitle = "儿童"; ObjectID = "iae-tc-tmZ"; */
  45 +"iae-tc-tmZ.normalTitle" = "儿童";
  46 +
  47 +/* Class = "UITableViewSection"; headerTitle = "病历"; ObjectID = "nLB-DQ-UD2"; */
  48 +"nLB-DQ-UD2.headerTitle" = "病历";
  49 +
  50 +/* Class = "UILabel"; text = "基础呼叫"; ObjectID = "rX9-H9-IL5"; */
  51 +"rX9-H9-IL5.text" = "基础呼叫";
  1 +//
  2 +// SettingVC.swift
  3 +// hhVDoctorSDK
  4 +//
  5 +// Created by 程言方 on 2020/11/13.
  6 +// Copyright © 2020 CocoaPods. All rights reserved.
  7 +//
  8 +
  9 +import UIKit
  10 +import hhVDoctorSDK
  11 +
  12 +class SettingVC : UIViewController {
  13 +
  14 + @IBOutlet weak var mTableView : UITableView!
  15 +
  16 + private var sections = [(String,[(String,Bool,Bool)])]()
  17 +
  18 + override public func viewDidLoad() {
  19 +
  20 + super.viewDidLoad()
  21 +
  22 + setUpUI()
  23 +
  24 + setUpData()
  25 + }
  26 +
  27 + override func viewWillAppear(_ animated: Bool) {
  28 +
  29 + }
  30 +
  31 +
  32 + func setUpUI(){
  33 + title = "设置"
  34 +
  35 + mTableView.separatorStyle = .none
  36 + mTableView.rowHeight = UITableView.automaticDimension
  37 + mTableView.delegate = self
  38 + mTableView.dataSource = self
  39 + mTableView.separatorStyle = .none
  40 + }
  41 +
  42 +
  43 + func setUpData() {
  44 +
  45 +
  46 + let baseSetting = ("基础设置",[
  47 + ("测试环境",HHSDKOptions.default.isDevelopment,true),
  48 + ("扩展参数",false,false),
  49 + ])
  50 + sections.append(baseSetting)
  51 +
  52 +
  53 +
  54 + let videoSetting = ("音视频设置", [
  55 + ("呼叫是否过滤生日性别",HHSDKOptions.default.mVideoOptions.filterCallerInfo,true),
  56 + ("是否开启美颜",HHSDKOptions.default.mVideoOptions.allowBeauty,true),
  57 + ("是否可以选择多人视频",HHSDKOptions.default.mVideoOptions.allowMulti,true),
  58 + ("是否可以增加成员",HHSDKOptions.default.mVideoOptions.allowAddMember,true),
  59 + ("视频完成后是否有评价",HHSDKOptions.default.mVideoOptions.allowEvaluate,true),
  60 + ])
  61 + sections.append(videoSetting)
  62 +
  63 +
  64 +
  65 + let infoListSetting = ("信息流设置",[
  66 + ("是否过滤总结卡片",HHSDKOptions.default.mMessageOptions.isFilterSummary,true),
  67 + ("是否过滤药卡",HHSDKOptions.default.mMessageOptions.isFilterMedicinal,true),
  68 + ("小助手默认头像",false,false),
  69 + ("小助手默认昵称",false,false),
  70 + ("信息流默认标题",false,false),
  71 + ("开启定位",false,true),
  72 + ])
  73 + sections.append(infoListSetting)
  74 +
  75 +
  76 +
  77 + let userCenterSetting = ("个人中心设置",[
  78 + ("是否隐藏个人中心入口",HHSDKOptions.default.mUserCenterOptions.hideUserCenter,true),
  79 + ("是否展示激活码入口",HHSDKOptions.default.mUserCenterOptions.enableActivate,true),
  80 + ("是否展示档案库入口",HHSDKOptions.default.mUserCenterOptions.enableMedical,true),
  81 + ("档案库是否可以添加成员",HHSDKOptions.default.mUserCenterOptions.canAddMember,true),
  82 +
  83 + ])
  84 + sections.append(userCenterSetting)
  85 +
  86 +
  87 + mTableView.reloadData()
  88 + }
  89 +}
  90 +
  91 +
  92 +
  93 +extension SettingVC : UITableViewDelegate,UITableViewDataSource {
  94 +
  95 + func numberOfSections(in tableView: UITableView) -> Int {
  96 + return sections.count
  97 + }
  98 +
  99 + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  100 + return sections[section].1.count
  101 + }
  102 +
  103 + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  104 + let cell = tableView.dequeueReusableCell(withIdentifier: "SettingCell") as? SettingCell
  105 + let cellInfo = sections[indexPath.section].1[indexPath.row]
  106 + cell?.configCell(title: cellInfo.0, isOpen: cellInfo.1,isSwitch: cellInfo.2)
  107 +
  108 + let view = UIView()
  109 + view.backgroundColor = .white
  110 + cell?.selectedBackgroundView = view
  111 +
  112 +
  113 + cell?.switchCallback = { [weak self] isOn in
  114 + self?.onConfigChange(indexPath: indexPath, isOpen: isOn)
  115 + }
  116 +
  117 +
  118 + return cell ?? UITableViewCell()
  119 + }
  120 +
  121 +
  122 + func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
  123 + sections[section].0
  124 + }
  125 +
  126 +
  127 + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  128 +
  129 + switch (indexPath.section,indexPath.row) {
  130 +
  131 + case (0,1):
  132 +
  133 + showEditAlter(title: "扩展参数",info: HHSDKOptions.default.mExtension) { info in
  134 + HHSDKOptions.default.mExtension = info
  135 + }
  136 +
  137 + break
  138 +
  139 + case (2,2):
  140 +
  141 + showEditAlter(title: "小助手默认头像",info: HHSDKOptions.default.mExtension) { info in
  142 + HHSDKOptions.default.mMessageOptions.defaultDocHeader = info
  143 + }
  144 +
  145 + break
  146 +
  147 + case (2,3):
  148 +
  149 + showEditAlter(title: "小助手默认昵称",info: HHSDKOptions.default.mExtension) { info in
  150 + HHSDKOptions.default.mMessageOptions.defaultDocName = info
  151 + }
  152 +
  153 + break
  154 +
  155 + case (2,4):
  156 +
  157 + showEditAlter(title: "信息流默认标题",info: HHSDKOptions.default.mExtension) { info in
  158 + HHSDKOptions.default.mMessageOptions.messageTitle = info
  159 + }
  160 +
  161 + break
  162 + default:
  163 + break
  164 +
  165 + }
  166 + }
  167 +
  168 +}
  169 +
  170 +
  171 +extension SettingVC {
  172 +
  173 +
  174 + func onConfigChange(indexPath : IndexPath , isOpen : Bool) {
  175 +
  176 + switch (indexPath.section,indexPath.row) {
  177 +
  178 + case (0,0):
  179 + HHMSDK.default.switchEnv(isOpen)
  180 + NotificationCenter.default.post(name: Notification.Name(rawValue: "onEnvChange"), object: nil)
  181 + break
  182 +
  183 + case (1,0):
  184 + HHSDKOptions.default.mVideoOptions.filterCallerInfo = isOpen
  185 +
  186 + case (1,1):
  187 + HHSDKOptions.default.mVideoOptions.allowBeauty = isOpen
  188 +
  189 + case (1,2):
  190 + HHSDKOptions.default.mVideoOptions.allowMulti = isOpen
  191 +
  192 + case (1,3):
  193 + HHSDKOptions.default.mVideoOptions.allowAddMember = isOpen
  194 +
  195 + case (1,4):
  196 + HHSDKOptions.default.mVideoOptions.allowEvaluate = isOpen
  197 +
  198 + case (2,0):
  199 + HHSDKOptions.default.mMessageOptions.isFilterSummary = isOpen
  200 +
  201 + case (2,1):
  202 + HHSDKOptions.default.mMessageOptions.isFilterMedicinal = isOpen
  203 +
  204 + case (2,5):
  205 +
  206 +// if isOpen {
  207 +// HHMSDK.default.aliPayHook = {(url,scheme,callback) in
  208 +// let isOk = AlipaySDK.defaultService()?.payInterceptor(withUrl: url, fromScheme: scheme, callback: { (result) in
  209 +// callback(result as? [String : Any] ?? ["test":""])
  210 +// })
  211 +//
  212 +//
  213 +// return isOk ?? false
  214 +// }
  215 +// }else{
  216 +//
  217 +// HHMSDK.default.aliPayHook = nil
  218 +// }
  219 +
  220 + if isOpen {
  221 + HHLocation.default.startLocation(lng: "116.431941", lat: "39.940199")
  222 +
  223 + }else{
  224 +
  225 + HHLocation.default.closeLocation()
  226 + }
  227 +
  228 + case (3,0):
  229 + HHSDKOptions.default.mUserCenterOptions.hideUserCenter = isOpen
  230 +
  231 + case (3,1):
  232 + HHSDKOptions.default.mUserCenterOptions.enableActivate = isOpen
  233 +
  234 + case (3,2):
  235 + HHSDKOptions.default.mUserCenterOptions.enableMedical = isOpen
  236 +
  237 + case (3,3):
  238 + HHSDKOptions.default.mUserCenterOptions.canAddMember = isOpen
  239 +
  240 + default:
  241 + break
  242 + }
  243 +
  244 +
  245 + }
  246 +
  247 +
  248 +
  249 + func showEditAlter(title : String , info : String , callback : @escaping ((String)->Void)) {
  250 +
  251 + let alert = UIAlertController(title: title, message: nil, preferredStyle: .alert)
  252 +
  253 + alert.addTextField { (textField) in
  254 + textField.text = info
  255 + }
  256 +
  257 + let cancelAction = UIAlertAction(title: "取消", style: .cancel) { _ in
  258 +
  259 + alert.dismiss(animated: true, completion: nil)
  260 + }
  261 +
  262 + cancelAction.setValue(UIColor.gray, forKey: "titleTextColor")
  263 +
  264 + alert.addAction(cancelAction)
  265 +
  266 + alert.addAction(UIAlertAction(title: "确定", style: .default, handler: {(_) in
  267 +
  268 + let info = alert.textFields?.first?.text
  269 +
  270 + guard info?.count ?? 0 > 0 else { return }
  271 +
  272 + callback(info ?? "")
  273 +
  274 + }))
  275 +
  276 + present(alert, animated: true, completion: nil)
  277 +
  278 + }
  279 +
  280 +}
  281 +
  282 +
  283 +
  284 +
  285 +
  286 +class SettingCell: UITableViewCell {
  287 +
  288 + @IBOutlet weak var mTitleLabel: UILabel!
  289 +
  290 + @IBOutlet weak var mSwitch : UISwitch!
  291 +
  292 + @IBOutlet weak var mArrow : UIImageView!
  293 +
  294 + var switchCallback : ((Bool) -> Void)?
  295 +
  296 + override func awakeFromNib() {
  297 + super.awakeFromNib()
  298 + // Initialization code
  299 + }
  300 +
  301 +
  302 + func configCell(title: String, isOpen : Bool, isSwitch: Bool) {
  303 + mTitleLabel.text = title
  304 + mSwitch.isOn = isOpen
  305 +
  306 + if isSwitch {
  307 + mSwitch.isHidden = false
  308 + mArrow.isHidden = true
  309 + }else{
  310 + mSwitch.isHidden = true
  311 + mArrow.isHidden = false
  312 + }
  313 + }
  314 +
  315 + @IBAction func onSwitch(_ sender : UISwitch) {
  316 + switchCallback?(sender.isOn)
  317 + }
  318 +}
No preview for this file type
  1 +//
  2 +// CavsBrowser.swift
  3 +// Cavs
  4 +//
  5 +// Created by mk on 2017/10/30.
  6 +// Copyright © 2017年 Johnson. All rights reserved.
  7 +//
  8 +
  9 +import UIKit
  10 +import SnapKit
  11 +import WebKit
  12 +
  13 +let ob_progress = "estimatedProgress"
  14 +let ob_title = "title"
  15 +
  16 +class HHWebBrowser: UIViewController, WKUIDelegate, WKNavigationDelegate {
  17 + /// 网页url
  18 + var urlString: String?
  19 +// {
  20 +// didSet {
  21 +// loadUrl()
  22 +// }
  23 +// }
  24 +
  25 + /// 网页名称
  26 + var titleString: String?
  27 +
  28 + /// webView
  29 + lazy var mWebView: WKWebView = {
  30 + let configuretion = WKWebViewConfiguration()
  31 + configuretion.preferences.javaScriptCanOpenWindowsAutomatically = true
  32 + let wkView = WKWebView(frame: CGRect.zero , configuration: configuretion)
  33 +
  34 + return wkView
  35 +
  36 + }()
  37 + /// 进度条
  38 + lazy var mProgress: UIProgressView = {
  39 + let webPV = UIProgressView(frame: CGRect(x: 0, y: 0, width: self.view.bounds.size.width, height: 5))
  40 + webPV.transform = CGAffineTransform(scaleX: 1.0, y: 2.0)
  41 + return webPV
  42 + }()
  43 +
  44 + private var navi: UINavigationController?
  45 + private var gesDelegate: UIGestureRecognizerDelegate?
  46 +
  47 +
  48 +
  49 + init(_ URL: String, title: String = "") {
  50 + self.urlString = URL
  51 + self.titleString = title
  52 + super.init(nibName: nil, bundle: nil)
  53 + }
  54 +
  55 + required init?(coder aDecoder: NSCoder) {
  56 + fatalError("init(coder:) has not been implemented")
  57 + }
  58 +
  59 + override public func viewDidLoad() {
  60 + super.viewDidLoad()
  61 + initUI()
  62 +
  63 + print("122222")
  64 +
  65 + self.navi = self.navigationController
  66 + self.gesDelegate = self.navigationController?.interactivePopGestureRecognizer?.delegate
  67 + }
  68 +
  69 + private func initUI() {
  70 + view.addSubview(mWebView)
  71 + view.addSubview(mProgress)
  72 +
  73 + mWebView.snp.makeConstraints({ (make) in
  74 + make.edges.equalTo(self.view).inset(UIEdgeInsets.init(top: 0, left: 0, bottom: 0, right: 0))
  75 + })
  76 +
  77 + navigationItem.rightBarButtonItem = nil
  78 + navigationItem.leftBarButtonItem = UIBarButtonItem(image: UIImage(named: "back_app2"), style: .done, target: self, action: #selector(clickGoBackBtn))
  79 +// navigationItem.leftBarButtonItem?.target = self
  80 +// navigationItem.leftBarButtonItem?.action = #selector(clickGoBackBtn)
  81 +
  82 + settingWeb()
  83 +
  84 + loadUrl()
  85 + }
  86 +
  87 + override func viewWillAppear(_ animated: Bool) {
  88 + super.viewWillAppear(animated)
  89 + self.navi?.interactivePopGestureRecognizer?.delegate = nil
  90 + }
  91 +
  92 + override func viewWillDisappear(_ animated: Bool) {
  93 + super.viewWillDisappear(animated)
  94 + self.navi?.interactivePopGestureRecognizer?.delegate = self.gesDelegate
  95 + }
  96 +
  97 + fileprivate func settingWeb() {
  98 + mWebView.uiDelegate = self
  99 + mWebView.navigationDelegate = self
  100 + mWebView.allowsBackForwardNavigationGestures = true
  101 + mWebView.addObserver(self, forKeyPath: ob_progress, options: .new, context: nil)
  102 + mWebView.addObserver(self, forKeyPath: ob_title, options: .new, context: nil)
  103 + }
  104 +
  105 + @objc func clickGoBackBtn() {
  106 + guard mWebView.canGoBack else { clickCloseBtn(); return }
  107 + mWebView.goBack()
  108 + }
  109 +
  110 + @objc func clickCloseBtn() {
  111 + guard let navVC = navigationController else { return }
  112 + navVC.popViewController(animated: true)
  113 + }
  114 +
  115 + private func loadUrl() {
  116 + if let webURL = URL(string: urlString ?? "") {
  117 + let request = URLRequest(url: webURL)
  118 + mWebView.load(request)
  119 + }
  120 + }
  121 +
  122 + public override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
  123 + guard let path = keyPath else { return }
  124 + switch path
  125 + {
  126 + case ob_title:
  127 + bindTitle(change)
  128 +
  129 + case ob_progress:
  130 + updateProgress()
  131 +
  132 + default:
  133 +
  134 + break
  135 + }
  136 + }
  137 +
  138 + // 此代理方法如果不实现,则不会实现网页跳转
  139 + public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
  140 + if navigationAction.targetFrame == nil {
  141 + webView.load(navigationAction.request)
  142 + }
  143 +
  144 + decisionHandler(.allow)
  145 + }
  146 +
  147 + public func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void)
  148 + {
  149 + let alertC = UIAlertController(title: "提示", message: message, preferredStyle: .alert)
  150 + alertC.addAction(UIAlertAction(title: "确定", style: .default, handler: { (aAction) in
  151 + completionHandler()
  152 + }))
  153 +
  154 + alertC.addAction(UIAlertAction(title: "取消", style: .default, handler: { (_) in
  155 + completionHandler()
  156 + }))
  157 +
  158 + present(alertC, animated: true, completion: nil)
  159 + }
  160 +
  161 + func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
  162 + print("runJavaScriptConfirmPanelWithMessage")
  163 +
  164 + let alert = UIAlertController(title: "提示", message: message, preferredStyle: .alert)
  165 + alert.addAction(UIAlertAction(title: "取消", style: .default, handler: { (_) in
  166 + completionHandler(false)
  167 + }))
  168 +
  169 + alert.addAction(UIAlertAction(title: "确认", style: .default, handler: { (_) in
  170 + completionHandler(true)
  171 + }))
  172 +
  173 + self.present(alert, animated: true, completion: nil)
  174 + }
  175 +
  176 + func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void) {
  177 + let alert = UIAlertController(title: prompt, message: "", preferredStyle: .alert)
  178 + alert.addTextField { (textField) in
  179 + textField.text = defaultText
  180 + }
  181 +
  182 + alert.addAction(UIAlertAction(title: "完成", style: .default, handler: { (_) in
  183 + completionHandler(alert.textFields?.first?.text)
  184 + }))
  185 +
  186 + self.present(alert, animated: true, completion: nil)
  187 + }
  188 +
  189 + public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
  190 + webView.canGoBack ? addCloseItem() : delCloseItem()
  191 + }
  192 +
  193 + public func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
  194 +// print("start")
  195 + }
  196 +
  197 + func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
  198 + print("----------- something error")
  199 + print(error.localizedDescription)
  200 + }
  201 +
  202 + private func addCloseItem() {
  203 + guard navigationItem.rightBarButtonItem == nil else { return }
  204 + let item = UIBarButtonItem(title: "关闭", style: .plain, target: self, action: #selector(clickCloseBtn))
  205 + item.setTitleTextAttributes([NSAttributedString.Key.font: UIFont.systemFont(ofSize: 15)], for: .normal)
  206 + navigationItem.rightBarButtonItem = item
  207 + }
  208 +
  209 + private func delCloseItem() {
  210 + guard let _ = navigationItem.rightBarButtonItem else { return }
  211 + navigationItem.rightBarButtonItem = nil
  212 + }
  213 +
  214 + deinit {
  215 + mWebView.removeObserver(self, forKeyPath: ob_progress)
  216 + mWebView.removeObserver(self, forKeyPath: ob_title)
  217 + }
  218 +}
  219 +
  220 +extension HHWebBrowser {
  221 + fileprivate func bindTitle(_ change: [NSKeyValueChangeKey : Any]?) {
  222 + if !(titleString ?? "").isEmpty {
  223 + title = titleString
  224 + } else {
  225 + if let aDic = change {
  226 + title = aDic[NSKeyValueChangeKey(rawValue: "new")] as? String
  227 + }
  228 + }
  229 + }
  230 +
  231 + fileprivate func updateProgress() {
  232 +// print("progress: \(mWebView.estimatedProgress)")
  233 + mProgress.isHidden = mWebView.estimatedProgress == 1
  234 + mProgress.setProgress(Float((mWebView.estimatedProgress)), animated: true)
  235 + }
  236 +}
  1 +//
  2 +// UIView+xib.swift
  3 +// HHMSDKDemo
  4 +//
  5 +// Created by Shi Jian on 2018/6/19.
  6 +// Copyright © 2018年 shmily. All rights reserved.
  7 +//
  8 +import UIKit
  9 +
  10 +// MARK: - Interface Builder中显示UIView的属性
  11 +extension UIView
  12 +{
  13 + // 圆角
  14 + @IBInspectable var cornerRadius: CGFloat {
  15 + get {
  16 + return layer.cornerRadius
  17 + }
  18 + set {
  19 + self.layer.masksToBounds = true
  20 + layer.cornerRadius = newValue
  21 + }
  22 + }
  23 + // 边界宽度
  24 + @IBInspectable var borderWidth: CGFloat {
  25 + get {
  26 + return layer.borderWidth
  27 + }
  28 + set {
  29 + self.layer.masksToBounds = true
  30 + layer.borderWidth = newValue
  31 + }
  32 + }
  33 + // 边界颜色
  34 + @IBInspectable var borderColor: UIColor {
  35 + get {
  36 + return UIColor(cgColor: layer.borderColor!)
  37 + }
  38 + set {
  39 + layer.borderColor = newValue.cgColor
  40 + }
  41 + }
  42 +}
No preview for this file type
  1 +//
  2 +// bridging-header.h
  3 +// HHMSDKDemo
  4 +//
  5 +// Created by 程言方 on 2020/11/16.
  6 +// Copyright © 2020 shmily. All rights reserved.
  7 +//
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>CFBundleDevelopmentRegion</key>
  6 + <string>$(DEVELOPMENT_LANGUAGE)</string>
  7 + <key>CFBundleDisplayName</key>
  8 + <string>药SDK demo</string>
  9 + <key>CFBundleExecutable</key>
  10 + <string>$(EXECUTABLE_NAME)</string>
  11 + <key>CFBundleIdentifier</key>
  12 + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
  13 + <key>CFBundleInfoDictionaryVersion</key>
  14 + <string>6.0</string>
  15 + <key>CFBundleName</key>
  16 + <string>$(PRODUCT_NAME)</string>
  17 + <key>CFBundlePackageType</key>
  18 + <string>APPL</string>
  19 + <key>CFBundleShortVersionString</key>
  20 + <string>1.2.0</string>
  21 + <key>CFBundleURLTypes</key>
  22 + <array>
  23 + <dict>
  24 + <key>CFBundleTypeRole</key>
  25 + <string>Editor</string>
  26 + <key>CFBundleURLSchemes</key>
  27 + <array>
  28 + <string>hh-medic.com</string>
  29 + </array>
  30 + </dict>
  31 + </array>
  32 + <key>CFBundleVersion</key>
  33 + <string>19.05.3015</string>
  34 + <key>LSRequiresIPhoneOS</key>
  35 + <true/>
  36 + <key>NSCameraUsageDescription</key>
  37 + <string>应用需使用相机权限,以便您向医生进行视频咨询。</string>
  38 + <key>NSLocationWhenInUseUsageDescription</key>
  39 + <string>应用需要使用定位权限,以帮您推荐合适的医院</string>
  40 + <key>NSMicrophoneUsageDescription</key>
  41 + <string>应用需使用麦克风权限,以便您向医生进行视频咨询。</string>
  42 + <key>NSPhotoLibraryUsageDescription</key>
  43 + <string>应用需要使用相册权限,以便您向医生发送健康资料。</string>
  44 + <key>UIBackgroundModes</key>
  45 + <array>
  46 + <string>audio</string>
  47 + </array>
  48 + <key>UILaunchStoryboardName</key>
  49 + <string>LaunchScreen</string>
  50 + <key>UIMainStoryboardFile</key>
  51 + <string>Main</string>
  52 + <key>UIRequiredDeviceCapabilities</key>
  53 + <array>
  54 + <string>armv7</string>
  55 + </array>
  56 + <key>UIRequiresFullScreen</key>
  57 + <true/>
  58 + <key>UISupportedInterfaceOrientations</key>
  59 + <array>
  60 + <string>UIInterfaceOrientationPortrait</string>
  61 + </array>
  62 + <key>UISupportedInterfaceOrientations~ipad</key>
  63 + <array>
  64 + <string>UIInterfaceOrientationPortrait</string>
  65 + <string>UIInterfaceOrientationPortraitUpsideDown</string>
  66 + <string>UIInterfaceOrientationLandscapeLeft</string>
  67 + <string>UIInterfaceOrientationLandscapeRight</string>
  68 + </array>
  69 +</dict>
  70 +</plist>
  1 +MIT License
  2 +
  3 +Copyright (c) 2018 HHMedic
  4 +
  5 +Permission is hereby granted, free of charge, to any person obtaining a copy
  6 +of this software and associated documentation files (the "Software"), to deal
  7 +in the Software without restriction, including without limitation the rights
  8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9 +copies of the Software, and to permit persons to whom the Software is
  10 +furnished to do so, subject to the following conditions:
  11 +
  12 +The above copyright notice and this permission notice shall be included in all
  13 +copies or substantial portions of the Software.
  14 +
  15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21 +SOFTWARE.
  1 +platform :ios, '9.0'
  2 +
  3 +use_frameworks!
  4 +
  5 +
  6 +# 和缓视频医生 SDK demo
  7 +target 'HHMSDKDemo' do
  8 + project './HHMSDKDemo.xcodeproj'
  9 + pod 'SVProgressHUD'
  10 + pod 'SnapKit'
  11 + pod 'HHVDoctorSDK', :git => "http://code.hh-medic.com/hh_public/hhvDoctorSDK.ios.git", :branch => 'feature/medic'
  12 +
  13 +end
  14 +
  1 +# HHVDoctorSDK 接入说明
  2 +
  3 +<p align="right">
  4 +北京和缓医疗科技有限公司<br/>
  5 +网址:https://www.hh-medic.com <br/>
  6 +地址:北京市东城区东直门来福士7层
  7 +</p>
  8 +
  9 + * [HHDoctorSDK 接入说明](#hhdoctorsdk-接入说明)
  10 + * [0. 更新日志](#0-更新日志)
  11 + * [1. 集成方式](#1-集成方式)
  12 + * [1.1. 手动集成](#11-手动集成)
  13 + * [1.2. 自动集成(推荐)](#12-自动集成推荐)
  14 + * [1.3. 调用规则](#13-调用规则)
  15 + * [2. 初始化](#2-初始化)
  16 + * [3. 登录账户](#3-登录账户)
  17 + * [3.1. 登录](#31-登录)
  18 + * [3.2. 登出](#32-登出)
  19 + * [4. 视频呼叫](#4-视频呼叫)
  20 + * [5. 代理(delegate)(可选)](#5-代理delegate可选)
  21 + * [5.1. 加入](#51-加入)
  22 + * [5.2. 移除](#52-移除)
  23 + * [6. 其他配置](#6-其他配置)
  24 + * [6.1. APNs](#61-apns)
  25 + * [6.2. Background Modes](#62-background-modes)
  26 + * [6.3. 扩展参数](#63-extension-params)
  27 + * [问题说明](#问题说明)
  28 + * [支付宝 SDK 冲突](#支付宝-sdk-冲突)
  29 + * [swift 4.1](#swift-41)
  30 +
  31 +## 0. 更新日志
  32 +
  33 +> 3.0.6
  34 +
  35 + - HHMVideoDelegate增加getChatParentView(_ view : UIView),以便开发者在呼叫页面添加自定义view
  36 +
  37 +> 2.0.2
  38 +
  39 + - 适配 Xcode 10, swift4.2
  40 +
  41 +
  42 +## 1. 集成方式
  43 +
  44 +说明: 接入 HHDoctorSDK 大概会使 ipa 包增加 15M.
  45 + HHDoctorSDK 提供两种集成方式:您既可以通过 CocoaPods 自动集成我们的 SDK,也可以通过手动下载 SDK, 然后添加到您的项目中。
  46 +我们提供的下载地址:
  47 +
  48 + 我们提供了发布仓库: [HHVDoctorSDK](https://code.hh-medic.com/hh_public/h'hhhvDoctorSDK.ios)
  49 + 集成demo地址: [HHDoctorSDK_demo_iOS](https://github.com/HHMedic/HHDoctorSDK_demo_iOS)
  50 +
  51 +由于呼叫视频需要相机相册权限,需要在info.plist中添加对应的权限,否则会导致无法调用。
  52 +
  53 +```
  54 +<key>NSPhotoLibraryUsageDescription</key>
  55 +<string>应用需要使用相册权限,以便您向医生发送健康资料。</string>
  56 +<key>NSCameraUsageDescription</key>
  57 +<string>应用需使用相机权限,以便您向医生进行视频咨询。</string>
  58 +<key>NSMicrophoneUsageDescription</key>
  59 +<string>应用需使用麦克风权限,以便您向医生进行视频咨询。</string>
  60 +```
  61 +
  62 +### 1.1. 手动集成
  63 +
  64 +1. 根据自己工程需要,下载对应版本的 HHMSDK,得到 NIMSDK.framework ,NIMAVChat.framework,NVS.framework,SecurityKit.framework 和 HHDoctorSDK.framework,以及未链接的全部三方依赖库 ,将他们导入工程。
  65 +2. 添加其他 HHDoctorSDK 依赖库。
  66 +
  67 + - SystemConfiguration.framework
  68 + - MobileCoreServices.framework
  69 + - AVFoundation.framwork
  70 + - CoreTelephony.framework
  71 + - CoreMedia.framework
  72 + - VideoToolbox.framework
  73 + - AudioToolbox.framework
  74 + - libz
  75 + - libsqlite3.0
  76 + - libc++
  77 +3.`Build Settings` -> `Other Linker Flags` 里,添加选项 `-ObjC`
  78 +4.`Build Settings` -> `Enable Bitcode` 里,设置为 `No`
  79 +5. 如果需要在后台时保持音频通话状态,在 `Capabilities` -> `Background Modes` 里勾选 `audio, airplay, and Picture in Picture`
  80 +
  81 +### 1.2. 自动集成(推荐)
  82 +*`Podfile` 文件中加入
  83 +
  84 +```shell
  85 +use_frameworks!
  86 +pod 'HHVDoctorSDK', :git => "http://code.hh-medic.com/hh_public/hhvDoctorSDK.ios.git"
  87 +```
  88 +* 安装
  89 +
  90 +``` shell
  91 +pod install
  92 +```
  93 +
  94 +### 1.3. 调用规则
  95 +所有 HHDoctorSDK 业务均通过 HHMSDK 单例调用
  96 +
  97 +```swift
  98 +public class HHMSDK : NSObject {
  99 +
  100 + public static let `default`: HHDoctorSDK.HHMSDK
  101 +}
  102 +```
  103 +
  104 +## 2. 初始化
  105 +在使用 HHDoctorSDK 任何方法之前,都应该首先调用初始化方法。正常业务情况下,初始化方法有仅只应调用一次。
  106 +
  107 +HHSDKOptions 选项参数列表
  108 +
  109 +参数|类型|说明
  110 +------|---|--------
  111 +productId|String|和缓分配的产品ID(必填)
  112 +isDevelopment|Bool|服务器模式(测试/正式)
  113 +isDebug|Bool|调试模式(是否打印日志)
  114 +APNs|String |推送证书名(由和缓生成)
  115 +hudManager| HHHUDable|自定义 progressHUD
  116 +hudDisTime| Double|hud 自动消失时间
  117 +
  118 +调用示例
  119 +
  120 +```swift
  121 +let option = HHSDKOptions(isDebug: true, isDevelop: true)
  122 +option.cerName = "2cDevTest"
  123 +// let option = HHSDKOptions()
  124 +// option.isDevelopment = true
  125 +// option.isDebug = true
  126 +// option.hudDisTime = 2
  127 +HHMSDK.default.start(option: option)
  128 +```
  129 +
  130 +
  131 +## 3. 登录账户
  132 +在对医生视频呼叫之前,需要先登录账号信息。账号的 uuid 由和缓提供。
  133 +### 3.1. 登录
  134 +
  135 +*注意: 不能多次调用登录 SDK,否则会导致视频故障。*
  136 +
  137 +* 原型
  138 +
  139 +```swift
  140 +public class HHMSDK : NSObject {
  141 +
  142 + /// 登录账号
  143 + ///
  144 + /// - Parameters:
  145 + /// - uuid: 用户的 唯一标志符
  146 + /// - completion: 完成回调
  147 + public func login(uuid: Int, completion: @escaping HHMedicSDK.HHLoginHandler)
  148 +}
  149 +```
  150 +
  151 +* 调用示例
  152 +
  153 +```swift
  154 +// 登录
  155 +HHMSDK.default.login(uuid: 100001531) { (error) in
  156 + if let aError = error {
  157 + print("登录错误: " + aError.localizedDescription)
  158 + }
  159 +}
  160 +```
  161 +error 为登录错误信息,成功则为 nil。
  162 +
  163 +### 3.2. 登出
  164 +应用层登出/注销/切换自己的账号时需要调用 HHMSDK 的登出操作,该操作会通知和缓服务器进行 APNs 推送信息的解绑操作,避免用户已登出但推送依然发送到当前设备的情况发生。
  165 +
  166 +* 原型
  167 +
  168 +```swift
  169 +public class HHMSDK : NSObject {
  170 +
  171 + /// 登出
  172 + public func logout()
  173 +}
  174 +```
  175 +
  176 +* 调用示例
  177 +
  178 +```swift
  179 +// 登出
  180 +HHMSDK.default.logout()
  181 +```
  182 +
  183 +## 4. 视频呼叫
  184 +根据实际场景的不同,可以进行成人、儿童方向的向医生咨询。
  185 +
  186 +* 原型
  187 +
  188 +```swift
  189 +public class HHMSDK : NSObject {
  190 +
  191 + /// 主叫发起通话
  192 + ///
  193 + /// - Parameter type: 呼叫类型
  194 + public func startCall(_ type: HHMedicSDK.HHCallType)
  195 +}
  196 +```
  197 +
  198 +* 调用示例
  199 +
  200 +```swift
  201 +// 咨询儿童问题
  202 +HHMSDK.default.startCall(.child)
  203 +
  204 +// 咨询成人问题
  205 +HHMSDK.default.startCall(.adult)
  206 +```
  207 +
  208 +HHCallType 枚举列表
  209 +
  210 +值 | 说明
  211 +--------- | -------------
  212 +child | 儿童
  213 +adult | 成人
  214 +
  215 +## 5. 代理(delegate)(可选)
  216 +代理主要用于视频过程中的状态反馈。如果不需要状态反馈,可以不考虑该代理。
  217 +所有的代理方法都是可选的,可以根据自己的实际需要实现不同的代理方法。
  218 +
  219 +* 原型
  220 +
  221 +```swift
  222 +/// 视频管理器代理
  223 +public protocol HHMVideoDelegate : NSObjectProtocol {
  224 +
  225 + /// 主动视频时的呼叫状态变化
  226 + ///
  227 + /// - Parameter state: 当前呼叫状态
  228 + public func callStateChange(_ state: HHMedicSDK.HHMCallingState)
  229 +
  230 + /// 通话已接通
  231 + public func callDidEstablish()
  232 +
  233 + /// 呼叫失败
  234 + public func onFail(error: Error)
  235 +
  236 + public func onCancel()
  237 +
  238 + /// 通话已结束 (接通之后才有结束)
  239 + public func callDidFinish()
  240 +
  241 + /// 转呼医生
  242 + public func onExtensionDoctor()
  243 +
  244 + /// 接收到呼叫(被呼叫方)
  245 + ///
  246 + /// - Parameters:
  247 + /// - callID: 呼叫的 id
  248 + /// - from: 呼叫人 id
  249 + public func onReceive(_ callID: String, from: String)
  250 +
  251 + /// 收到视频呼入时的操作(被呼叫方)
  252 + ///
  253 + /// - Parameter accept: 接受或者拒接
  254 + public func onResponse(_ accept: Bool)
  255 +
  256 + /// 缺少必要权限
  257 + ///
  258 + /// - Parameter type: 缺少的权限类型
  259 + public func onLeakPermission(_ type: HHMedicSDK.PermissionType)
  260 +}
  261 +```
  262 +
  263 +### 5.1. 加入
  264 +代理支持同时设置多个。
  265 +
  266 +```swift
  267 +HHMSDK.default.add(delegate: self)
  268 +```
  269 +
  270 +### 5.2. 移除
  271 +
  272 +```swift
  273 +HHMSDK.default.remove(delegate: self)
  274 +```
  275 +
  276 +
  277 +## 6. 其他配置
  278 +
  279 +### 6.1. APNs
  280 +
  281 +在 appDelegate 中向 SDK 传入 deviceToken 即可。
  282 +
  283 +```swift
  284 +func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
  285 + HHMSDK.default.updateAPNS(token: deviceToken)
  286 +}
  287 +```
  288 +
  289 +*注意:需要上传 APNs 的 p12 文件,请联系我们上传。*
  290 +
  291 +### 6.2. Background Modes
  292 +
  293 +为了支持用户压后台后音视频的正常使用,需要设置 Background Modes。具体设置如下:
  294 +
  295 +```
  296 +xxx target -> Capabilities -> Background Modes -> 勾选 Audio,Airplay and Picture in Picture
  297 +```
  298 +
  299 +### 6.3. 扩展参数
  300 +
  301 +为了支持收集渠道日志,SDK支持在初始化时传递自定义参数。
  302 +
  303 +```
  304 +let option = HHSDKOptions(productId: "3000", isDebug: true, isDevelop: true)
  305 +option.asyncLogin = false
  306 +option.mExtension = ""
  307 +
  308 +```
  309 +
  310 +
  311 +## 问题说明
  312 +
  313 +### 支付宝 SDK 冲突
  314 +若出现UTDID冲突错误,请切换支付宝 SDK 到无UTDID版本.
  315 +[官方说明](https://docs.open.alipay.com/54/104509/)
  316 +
  317 +
  318 +### swift 4.1
  319 +master 分支已经支持 swift4.2, 如果需要支持 swift4.1, 请切换到对应分支 `swift4.1`
  320 +
  321 +```
  322 +pod 'HHDoctorSDK', :git => "http://code.hh-medic.com/hh_public/HHDoctorSDK.ios.git", :branch => 'swift4.1'
  323 +```