瀏覽代碼

第一次提交 版本为0.0.1

ghost 3 年之前
父節點
當前提交
13eb1890d4
共有 42 個文件被更改,包括 2390 次插入28 次删除
  1. 1 1
      Example/Podfile
  2. 16 0
      Example/Podfile.lock
  3. 22 0
      Example/Pods/Local Podspecs/WHCServieRouter.podspec.json
  4. 16 0
      Example/Pods/Manifest.lock
  5. 789 0
      Example/Pods/Pods.xcodeproj/project.pbxproj
  6. 26 0
      Example/Pods/Target Support Files/Pods-WHCServieRouter_Example/Pods-WHCServieRouter_Example-Info.plist
  7. 26 0
      Example/Pods/Target Support Files/Pods-WHCServieRouter_Example/Pods-WHCServieRouter_Example-acknowledgements.markdown
  8. 58 0
      Example/Pods/Target Support Files/Pods-WHCServieRouter_Example/Pods-WHCServieRouter_Example-acknowledgements.plist
  9. 5 0
      Example/Pods/Target Support Files/Pods-WHCServieRouter_Example/Pods-WHCServieRouter_Example-dummy.m
  10. 185 0
      Example/Pods/Target Support Files/Pods-WHCServieRouter_Example/Pods-WHCServieRouter_Example-frameworks.sh
  11. 16 0
      Example/Pods/Target Support Files/Pods-WHCServieRouter_Example/Pods-WHCServieRouter_Example-umbrella.h
  12. 12 0
      Example/Pods/Target Support Files/Pods-WHCServieRouter_Example/Pods-WHCServieRouter_Example.debug.xcconfig
  13. 6 0
      Example/Pods/Target Support Files/Pods-WHCServieRouter_Example/Pods-WHCServieRouter_Example.modulemap
  14. 12 0
      Example/Pods/Target Support Files/Pods-WHCServieRouter_Example/Pods-WHCServieRouter_Example.release.xcconfig
  15. 26 0
      Example/Pods/Target Support Files/Pods-WHCServieRouter_Tests/Pods-WHCServieRouter_Tests-Info.plist
  16. 3 0
      Example/Pods/Target Support Files/Pods-WHCServieRouter_Tests/Pods-WHCServieRouter_Tests-acknowledgements.markdown
  17. 29 0
      Example/Pods/Target Support Files/Pods-WHCServieRouter_Tests/Pods-WHCServieRouter_Tests-acknowledgements.plist
  18. 5 0
      Example/Pods/Target Support Files/Pods-WHCServieRouter_Tests/Pods-WHCServieRouter_Tests-dummy.m
  19. 185 0
      Example/Pods/Target Support Files/Pods-WHCServieRouter_Tests/Pods-WHCServieRouter_Tests-frameworks.sh
  20. 16 0
      Example/Pods/Target Support Files/Pods-WHCServieRouter_Tests/Pods-WHCServieRouter_Tests-umbrella.h
  21. 11 0
      Example/Pods/Target Support Files/Pods-WHCServieRouter_Tests/Pods-WHCServieRouter_Tests.debug.xcconfig
  22. 6 0
      Example/Pods/Target Support Files/Pods-WHCServieRouter_Tests/Pods-WHCServieRouter_Tests.modulemap
  23. 11 0
      Example/Pods/Target Support Files/Pods-WHCServieRouter_Tests/Pods-WHCServieRouter_Tests.release.xcconfig
  24. 26 0
      Example/Pods/Target Support Files/WHCServieRouter/WHCServieRouter-Info.plist
  25. 5 0
      Example/Pods/Target Support Files/WHCServieRouter/WHCServieRouter-dummy.m
  26. 12 0
      Example/Pods/Target Support Files/WHCServieRouter/WHCServieRouter-prefix.pch
  27. 20 0
      Example/Pods/Target Support Files/WHCServieRouter/WHCServieRouter-umbrella.h
  28. 11 0
      Example/Pods/Target Support Files/WHCServieRouter/WHCServieRouter.debug.xcconfig
  29. 6 0
      Example/Pods/Target Support Files/WHCServieRouter/WHCServieRouter.modulemap
  30. 11 0
      Example/Pods/Target Support Files/WHCServieRouter/WHCServieRouter.release.xcconfig
  31. 1 1
      Example/Tests/Tests-Prefix.pch
  32. 0 19
      Example/WHCServieRouter.xcodeproj/project.pbxproj
  33. 10 0
      Example/WHCServieRouter.xcworkspace/contents.xcworkspacedata
  34. 8 0
      Example/WHCServieRouter.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
  35. 5 7
      WHCServieRouter.podspec
  36. 0 0
      WHCServieRouter/Classes/ReplaceMe.m
  37. 104 0
      WHCServieRouter/Classes/WHCServiceRouter/WHCServieRouter+Router.h
  38. 141 0
      WHCServieRouter/Classes/WHCServiceRouter/WHCServieRouter+Router.m
  39. 113 0
      WHCServieRouter/Classes/WHCServiceRouter/WHCServieRouter.h
  40. 361 0
      WHCServieRouter/Classes/WHCServiceRouter/WHCServieRouter.m
  41. 16 0
      WHCServieRouter/Classes/WHCServiceRouter/WHCServieRouterHeader.h
  42. 58 0
      WHCServieRouter/Classes/WHCServiceRouter/WHCServieRouterProtocol.h

+ 1 - 1
Example/Podfile

@@ -8,6 +8,6 @@ target 'WHCServieRouter_Example' do
   target 'WHCServieRouter_Tests' do
     inherit! :search_paths
 
-    pod 'FBSnapshotTestCase'
+#    pod 'FBSnapshotTestCase'
   end
 end

+ 16 - 0
Example/Podfile.lock

@@ -0,0 +1,16 @@
+PODS:
+  - WHCServieRouter (0.1.0)
+
+DEPENDENCIES:
+  - WHCServieRouter (from `../`)
+
+EXTERNAL SOURCES:
+  WHCServieRouter:
+    :path: "../"
+
+SPEC CHECKSUMS:
+  WHCServieRouter: edd12f081d0a72259c02f4ff6f88f06af1b81a06
+
+PODFILE CHECKSUM: 1628691cfcb9c8acabc0f4959760144b75a24773
+
+COCOAPODS: 1.10.1

+ 22 - 0
Example/Pods/Local Podspecs/WHCServieRouter.podspec.json

@@ -0,0 +1,22 @@
+{
+  "name": "WHCServieRouter",
+  "version": "0.1.0",
+  "summary": "A short description of WHCServieRouter.",
+  "description": "TODO: Add long description of the pod here.",
+  "homepage": "https://github.com/ghost/WHCServieRouter",
+  "license": {
+    "type": "MIT",
+    "file": "LICENSE"
+  },
+  "authors": {
+    "ghost": "fasac"
+  },
+  "source": {
+    "git": "https://github.com/ghost/WHCServieRouter.git",
+    "tag": "0.1.0"
+  },
+  "platforms": {
+    "ios": "9.0"
+  },
+  "source_files": "WHCServieRouter/Classes/**/*"
+}

+ 16 - 0
Example/Pods/Manifest.lock

@@ -0,0 +1,16 @@
+PODS:
+  - WHCServieRouter (0.1.0)
+
+DEPENDENCIES:
+  - WHCServieRouter (from `../`)
+
+EXTERNAL SOURCES:
+  WHCServieRouter:
+    :path: "../"
+
+SPEC CHECKSUMS:
+  WHCServieRouter: edd12f081d0a72259c02f4ff6f88f06af1b81a06
+
+PODFILE CHECKSUM: 1628691cfcb9c8acabc0f4959760144b75a24773
+
+COCOAPODS: 1.10.1

+ 789 - 0
Example/Pods/Pods.xcodeproj/project.pbxproj

@@ -0,0 +1,789 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 46;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		073013C52CD07797D708340E3BBBF449 /* WHCServieRouterHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = ADAC0A14FA3D153646DE2EFC70D4FBAA /* WHCServieRouterHeader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		11246E271DE4F3C54B9E0E0B4692CF64 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; };
+		137908CB8EDF948A01DE57797F1557E4 /* WHCServieRouterProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 631955E0EEB42A8CCB258F2483A7200D /* WHCServieRouterProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		1B5255A78A3017223226E3193C28E6FB /* WHCServieRouter-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = E2ED7C70B27BD1C2BBA502F572F7D3D6 /* WHCServieRouter-dummy.m */; };
+		357AD4B64E2CF5F7D7E53155BDF6E178 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; };
+		382DBEF5A3C80C647D6F377706E177BA /* WHCServieRouter+Router.h in Headers */ = {isa = PBXBuildFile; fileRef = D7DAC46F4A3ABA991D5CD059764D2CCF /* WHCServieRouter+Router.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		8838490AFDDDBA692B99133C6B7A7C7F /* Pods-WHCServieRouter_Tests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6AB898A4B5E57CD94CDA6D4E7B4D3A96 /* Pods-WHCServieRouter_Tests-dummy.m */; };
+		92D56A5B9DDB9CD639883018C34697D3 /* WHCServieRouter.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BD4DD8BACD1F0BBB4862E0A34C8E231 /* WHCServieRouter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		95BB003E30C6C9638A4B9B5BC7C2E4E7 /* Pods-WHCServieRouter_Tests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = D8B67B73854A40D9B969E67748DBE5D0 /* Pods-WHCServieRouter_Tests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		999F4339CBE8C0F20952D0CC4273E206 /* WHCServieRouter.m in Sources */ = {isa = PBXBuildFile; fileRef = 116202E32863A9BE233A2C543EE54F22 /* WHCServieRouter.m */; };
+		B312E5604D98F582A9D9BA8D78D49E0B /* Pods-WHCServieRouter_Example-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = F2DB817FA2E33A36DB387B4E55108434 /* Pods-WHCServieRouter_Example-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		CC1BA0C9D8857DB336C1BE01D3F38A7A /* WHCServieRouter-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = ED7C3D80AC85A4D35EA2BC37CD448A1C /* WHCServieRouter-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		D2B2F94159D6A3ACDA96056824E852C4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; };
+		EE2608CF676394FB563525DCA9A65F1C /* Pods-WHCServieRouter_Example-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = CF9DEAB9F3318509006FF0FD989CFD1A /* Pods-WHCServieRouter_Example-dummy.m */; };
+		F1EBD2680A8A7FE42219A9D6C8F7A35A /* WHCServieRouter+Router.m in Sources */ = {isa = PBXBuildFile; fileRef = DA02375448F8BEB94A689224F9F8809A /* WHCServieRouter+Router.m */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+		3D6B1A7028F6E7D9CA7D1DD1F0728430 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = F92F93F34E99B7C9FC4E583800F19759;
+			remoteInfo = WHCServieRouter;
+		};
+		D75B35FE6326E845B57CD94DA4A48777 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 4497A814413EC9C5753A10CFEDB23310;
+			remoteInfo = "Pods-WHCServieRouter_Example";
+		};
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+		080BB683A24134C39AB54658D680F48F /* Pods-WHCServieRouter_Tests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-WHCServieRouter_Tests-acknowledgements.plist"; sourceTree = "<group>"; };
+		116202E32863A9BE233A2C543EE54F22 /* WHCServieRouter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = WHCServieRouter.m; path = WHCServieRouter/Classes/WHCServiceRouter/WHCServieRouter.m; sourceTree = "<group>"; };
+		1A0B09986A05DCE30E58D37A2370C9B5 /* Pods-WHCServieRouter_Example.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-WHCServieRouter_Example.modulemap"; sourceTree = "<group>"; };
+		2DC6AFAC10D4EACFF8D10102D3A4D6D0 /* Pods-WHCServieRouter_Example-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-WHCServieRouter_Example-acknowledgements.markdown"; sourceTree = "<group>"; };
+		3BD4DD8BACD1F0BBB4862E0A34C8E231 /* WHCServieRouter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = WHCServieRouter.h; path = WHCServieRouter/Classes/WHCServiceRouter/WHCServieRouter.h; sourceTree = "<group>"; };
+		4BF490D1B4C109D0A1DE298C9B872D29 /* WHCServieRouter-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "WHCServieRouter-prefix.pch"; sourceTree = "<group>"; };
+		4EAC913D27836CB6F6AFF2EA45A6A0BF /* Pods_WHCServieRouter_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_WHCServieRouter_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		5331EF0EF520A744093102FD5F614269 /* Pods-WHCServieRouter_Example-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-WHCServieRouter_Example-Info.plist"; sourceTree = "<group>"; };
+		5C1460617418F28D60B5006D722BE8FC /* Pods-WHCServieRouter_Example-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-WHCServieRouter_Example-acknowledgements.plist"; sourceTree = "<group>"; };
+		631955E0EEB42A8CCB258F2483A7200D /* WHCServieRouterProtocol.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = WHCServieRouterProtocol.h; path = WHCServieRouter/Classes/WHCServiceRouter/WHCServieRouterProtocol.h; sourceTree = "<group>"; };
+		6AB898A4B5E57CD94CDA6D4E7B4D3A96 /* Pods-WHCServieRouter_Tests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-WHCServieRouter_Tests-dummy.m"; sourceTree = "<group>"; };
+		73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
+		7BE24155B1DE1F6909D02EE602AD5848 /* Pods-WHCServieRouter_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-WHCServieRouter_Tests.release.xcconfig"; sourceTree = "<group>"; };
+		7FCA395CF9ED4006493E3CAD91435584 /* WHCServieRouter-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "WHCServieRouter-Info.plist"; sourceTree = "<group>"; };
+		85955D518BF1FDEF1B1FEB885BE75B9C /* WHCServieRouter.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = WHCServieRouter.release.xcconfig; sourceTree = "<group>"; };
+		9130F601A9B17510E81D4D533B72FEA1 /* WHCServieRouter.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = WHCServieRouter.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		9735DF67AE6F2C8F062D8BD5776E7B5F /* Pods_WHCServieRouter_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_WHCServieRouter_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
+		A083E6D67246444EACF002471668426B /* WHCServieRouter.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = WHCServieRouter.debug.xcconfig; sourceTree = "<group>"; };
+		ADAC0A14FA3D153646DE2EFC70D4FBAA /* WHCServieRouterHeader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = WHCServieRouterHeader.h; path = WHCServieRouter/Classes/WHCServiceRouter/WHCServieRouterHeader.h; sourceTree = "<group>"; };
+		AF10082A339AA106A811B9F5190C39DA /* Pods-WHCServieRouter_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-WHCServieRouter_Example.release.xcconfig"; sourceTree = "<group>"; };
+		AF8314949EB62F68AA8E5E373DC38C7A /* Pods-WHCServieRouter_Tests-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-WHCServieRouter_Tests-Info.plist"; sourceTree = "<group>"; };
+		B599C15ABAEE06E6925A4BC66C90259D /* WHCServieRouter.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = WHCServieRouter.modulemap; sourceTree = "<group>"; };
+		C3F99B6374A7EB4AAD83FBACD683B9BB /* WHCServieRouter.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; path = WHCServieRouter.podspec; sourceTree = "<group>"; tabWidth = 2; };
+		C6D556435205A96E66E38651075C5267 /* Pods-WHCServieRouter_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-WHCServieRouter_Example.debug.xcconfig"; sourceTree = "<group>"; };
+		CF9DEAB9F3318509006FF0FD989CFD1A /* Pods-WHCServieRouter_Example-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-WHCServieRouter_Example-dummy.m"; sourceTree = "<group>"; };
+		D47FD466685EA9429B05CEDFBE6A3080 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
+		D7DAC46F4A3ABA991D5CD059764D2CCF /* WHCServieRouter+Router.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "WHCServieRouter+Router.h"; path = "WHCServieRouter/Classes/WHCServiceRouter/WHCServieRouter+Router.h"; sourceTree = "<group>"; };
+		D8B67B73854A40D9B969E67748DBE5D0 /* Pods-WHCServieRouter_Tests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-WHCServieRouter_Tests-umbrella.h"; sourceTree = "<group>"; };
+		DA02375448F8BEB94A689224F9F8809A /* WHCServieRouter+Router.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "WHCServieRouter+Router.m"; path = "WHCServieRouter/Classes/WHCServiceRouter/WHCServieRouter+Router.m"; sourceTree = "<group>"; };
+		DB494757D4C42856C460687E71C4D621 /* Pods-WHCServieRouter_Example-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-WHCServieRouter_Example-frameworks.sh"; sourceTree = "<group>"; };
+		DD1E6F0553777F13A5E217559EEDEFF3 /* Pods-WHCServieRouter_Tests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-WHCServieRouter_Tests-acknowledgements.markdown"; sourceTree = "<group>"; };
+		E1F909187FA4FE20E4688CB6541A9F05 /* Pods-WHCServieRouter_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-WHCServieRouter_Tests.debug.xcconfig"; sourceTree = "<group>"; };
+		E2ED7C70B27BD1C2BBA502F572F7D3D6 /* WHCServieRouter-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "WHCServieRouter-dummy.m"; sourceTree = "<group>"; };
+		ED7C3D80AC85A4D35EA2BC37CD448A1C /* WHCServieRouter-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "WHCServieRouter-umbrella.h"; sourceTree = "<group>"; };
+		EF5012CE901E23CE11854484B38A8E73 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
+		F2DB817FA2E33A36DB387B4E55108434 /* Pods-WHCServieRouter_Example-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-WHCServieRouter_Example-umbrella.h"; sourceTree = "<group>"; };
+		FC1DDB564A4115EB0B537666536F3246 /* Pods-WHCServieRouter_Tests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-WHCServieRouter_Tests.modulemap"; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		74F2D8F88707043A5EA74B29B89D41F3 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				D2B2F94159D6A3ACDA96056824E852C4 /* Foundation.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		A2A6B5728DECB317FC24283997BE8AD2 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				357AD4B64E2CF5F7D7E53155BDF6E178 /* Foundation.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		FA44C45C6FB3D7A2BB743192254062FA /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				11246E271DE4F3C54B9E0E0B4692CF64 /* Foundation.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		0A267559E90FA8BAF0825CB299445B48 /* Pods-WHCServieRouter_Tests */ = {
+			isa = PBXGroup;
+			children = (
+				FC1DDB564A4115EB0B537666536F3246 /* Pods-WHCServieRouter_Tests.modulemap */,
+				DD1E6F0553777F13A5E217559EEDEFF3 /* Pods-WHCServieRouter_Tests-acknowledgements.markdown */,
+				080BB683A24134C39AB54658D680F48F /* Pods-WHCServieRouter_Tests-acknowledgements.plist */,
+				6AB898A4B5E57CD94CDA6D4E7B4D3A96 /* Pods-WHCServieRouter_Tests-dummy.m */,
+				AF8314949EB62F68AA8E5E373DC38C7A /* Pods-WHCServieRouter_Tests-Info.plist */,
+				D8B67B73854A40D9B969E67748DBE5D0 /* Pods-WHCServieRouter_Tests-umbrella.h */,
+				E1F909187FA4FE20E4688CB6541A9F05 /* Pods-WHCServieRouter_Tests.debug.xcconfig */,
+				7BE24155B1DE1F6909D02EE602AD5848 /* Pods-WHCServieRouter_Tests.release.xcconfig */,
+			);
+			name = "Pods-WHCServieRouter_Tests";
+			path = "Target Support Files/Pods-WHCServieRouter_Tests";
+			sourceTree = "<group>";
+		};
+		458F0DD8FDD63BDEC58FE52E90007ADE /* WHCServieRouter */ = {
+			isa = PBXGroup;
+			children = (
+				3BD4DD8BACD1F0BBB4862E0A34C8E231 /* WHCServieRouter.h */,
+				116202E32863A9BE233A2C543EE54F22 /* WHCServieRouter.m */,
+				D7DAC46F4A3ABA991D5CD059764D2CCF /* WHCServieRouter+Router.h */,
+				DA02375448F8BEB94A689224F9F8809A /* WHCServieRouter+Router.m */,
+				ADAC0A14FA3D153646DE2EFC70D4FBAA /* WHCServieRouterHeader.h */,
+				631955E0EEB42A8CCB258F2483A7200D /* WHCServieRouterProtocol.h */,
+				DE108AA2EA6FA4191143FA4CBB6B931D /* Pod */,
+				890DF44AC201AC5F651294E61E7C4F19 /* Support Files */,
+			);
+			name = WHCServieRouter;
+			path = ../..;
+			sourceTree = "<group>";
+		};
+		578452D2E740E91742655AC8F1636D1F /* iOS */ = {
+			isa = PBXGroup;
+			children = (
+				73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */,
+			);
+			name = iOS;
+			sourceTree = "<group>";
+		};
+		6ECC668D0396B8B758B052F007F3060D /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				4EAC913D27836CB6F6AFF2EA45A6A0BF /* Pods_WHCServieRouter_Example.framework */,
+				9735DF67AE6F2C8F062D8BD5776E7B5F /* Pods_WHCServieRouter_Tests.framework */,
+				9130F601A9B17510E81D4D533B72FEA1 /* WHCServieRouter.framework */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		6EE9A101B82CEAD5FB4359C04C27BA24 /* Targets Support Files */ = {
+			isa = PBXGroup;
+			children = (
+				DC2AAC596C1BB2FE407265DDD1D03663 /* Pods-WHCServieRouter_Example */,
+				0A267559E90FA8BAF0825CB299445B48 /* Pods-WHCServieRouter_Tests */,
+			);
+			name = "Targets Support Files";
+			sourceTree = "<group>";
+		};
+		890DF44AC201AC5F651294E61E7C4F19 /* Support Files */ = {
+			isa = PBXGroup;
+			children = (
+				B599C15ABAEE06E6925A4BC66C90259D /* WHCServieRouter.modulemap */,
+				E2ED7C70B27BD1C2BBA502F572F7D3D6 /* WHCServieRouter-dummy.m */,
+				7FCA395CF9ED4006493E3CAD91435584 /* WHCServieRouter-Info.plist */,
+				4BF490D1B4C109D0A1DE298C9B872D29 /* WHCServieRouter-prefix.pch */,
+				ED7C3D80AC85A4D35EA2BC37CD448A1C /* WHCServieRouter-umbrella.h */,
+				A083E6D67246444EACF002471668426B /* WHCServieRouter.debug.xcconfig */,
+				85955D518BF1FDEF1B1FEB885BE75B9C /* WHCServieRouter.release.xcconfig */,
+			);
+			name = "Support Files";
+			path = "Example/Pods/Target Support Files/WHCServieRouter";
+			sourceTree = "<group>";
+		};
+		CF1408CF629C7361332E53B88F7BD30C = {
+			isa = PBXGroup;
+			children = (
+				9D940727FF8FB9C785EB98E56350EF41 /* Podfile */,
+				E2259DC04CA90B889975DE59A852F5CE /* Development Pods */,
+				D210D550F4EA176C3123ED886F8F87F5 /* Frameworks */,
+				6ECC668D0396B8B758B052F007F3060D /* Products */,
+				6EE9A101B82CEAD5FB4359C04C27BA24 /* Targets Support Files */,
+			);
+			sourceTree = "<group>";
+		};
+		D210D550F4EA176C3123ED886F8F87F5 /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				578452D2E740E91742655AC8F1636D1F /* iOS */,
+			);
+			name = Frameworks;
+			sourceTree = "<group>";
+		};
+		DC2AAC596C1BB2FE407265DDD1D03663 /* Pods-WHCServieRouter_Example */ = {
+			isa = PBXGroup;
+			children = (
+				1A0B09986A05DCE30E58D37A2370C9B5 /* Pods-WHCServieRouter_Example.modulemap */,
+				2DC6AFAC10D4EACFF8D10102D3A4D6D0 /* Pods-WHCServieRouter_Example-acknowledgements.markdown */,
+				5C1460617418F28D60B5006D722BE8FC /* Pods-WHCServieRouter_Example-acknowledgements.plist */,
+				CF9DEAB9F3318509006FF0FD989CFD1A /* Pods-WHCServieRouter_Example-dummy.m */,
+				DB494757D4C42856C460687E71C4D621 /* Pods-WHCServieRouter_Example-frameworks.sh */,
+				5331EF0EF520A744093102FD5F614269 /* Pods-WHCServieRouter_Example-Info.plist */,
+				F2DB817FA2E33A36DB387B4E55108434 /* Pods-WHCServieRouter_Example-umbrella.h */,
+				C6D556435205A96E66E38651075C5267 /* Pods-WHCServieRouter_Example.debug.xcconfig */,
+				AF10082A339AA106A811B9F5190C39DA /* Pods-WHCServieRouter_Example.release.xcconfig */,
+			);
+			name = "Pods-WHCServieRouter_Example";
+			path = "Target Support Files/Pods-WHCServieRouter_Example";
+			sourceTree = "<group>";
+		};
+		DE108AA2EA6FA4191143FA4CBB6B931D /* Pod */ = {
+			isa = PBXGroup;
+			children = (
+				D47FD466685EA9429B05CEDFBE6A3080 /* LICENSE */,
+				EF5012CE901E23CE11854484B38A8E73 /* README.md */,
+				C3F99B6374A7EB4AAD83FBACD683B9BB /* WHCServieRouter.podspec */,
+			);
+			name = Pod;
+			sourceTree = "<group>";
+		};
+		E2259DC04CA90B889975DE59A852F5CE /* Development Pods */ = {
+			isa = PBXGroup;
+			children = (
+				458F0DD8FDD63BDEC58FE52E90007ADE /* WHCServieRouter */,
+			);
+			name = "Development Pods";
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+		1D44629236E71B8D829E800C3A80DB49 /* Headers */ = {
+			isa = PBXHeadersBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				382DBEF5A3C80C647D6F377706E177BA /* WHCServieRouter+Router.h in Headers */,
+				92D56A5B9DDB9CD639883018C34697D3 /* WHCServieRouter.h in Headers */,
+				073013C52CD07797D708340E3BBBF449 /* WHCServieRouterHeader.h in Headers */,
+				137908CB8EDF948A01DE57797F1557E4 /* WHCServieRouterProtocol.h in Headers */,
+				CC1BA0C9D8857DB336C1BE01D3F38A7A /* WHCServieRouter-umbrella.h in Headers */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		72B84B94E6B32387C4B0E7B74B04477C /* Headers */ = {
+			isa = PBXHeadersBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				95BB003E30C6C9638A4B9B5BC7C2E4E7 /* Pods-WHCServieRouter_Tests-umbrella.h in Headers */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		F45651091451F379549566043C75E45A /* Headers */ = {
+			isa = PBXHeadersBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				B312E5604D98F582A9D9BA8D78D49E0B /* Pods-WHCServieRouter_Example-umbrella.h in Headers */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+		4497A814413EC9C5753A10CFEDB23310 /* Pods-WHCServieRouter_Example */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 37F5B36B0FD05DDD955464C6F3AAC1CA /* Build configuration list for PBXNativeTarget "Pods-WHCServieRouter_Example" */;
+			buildPhases = (
+				F45651091451F379549566043C75E45A /* Headers */,
+				FE1FCC1AAD1F3A429040B361148EA2FA /* Sources */,
+				FA44C45C6FB3D7A2BB743192254062FA /* Frameworks */,
+				D8093B69FCCB3738B67AD488264B1C87 /* Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				90BF2DE820DEFE5820A9212071ACABD2 /* PBXTargetDependency */,
+			);
+			name = "Pods-WHCServieRouter_Example";
+			productName = "Pods-WHCServieRouter_Example";
+			productReference = 4EAC913D27836CB6F6AFF2EA45A6A0BF /* Pods_WHCServieRouter_Example.framework */;
+			productType = "com.apple.product-type.framework";
+		};
+		62CACEE8B616A038DA88E6C93EC3F7FF /* Pods-WHCServieRouter_Tests */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 73352A9314BFD5F6FEB8C2BEC26FA4A6 /* Build configuration list for PBXNativeTarget "Pods-WHCServieRouter_Tests" */;
+			buildPhases = (
+				72B84B94E6B32387C4B0E7B74B04477C /* Headers */,
+				AD272AE127505E9C705E32F8CCC3FAF3 /* Sources */,
+				A2A6B5728DECB317FC24283997BE8AD2 /* Frameworks */,
+				AB3D52835EF4177CBA644842AF7D07AB /* Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				EE1D6A37873A279B635129FF535EB033 /* PBXTargetDependency */,
+			);
+			name = "Pods-WHCServieRouter_Tests";
+			productName = "Pods-WHCServieRouter_Tests";
+			productReference = 9735DF67AE6F2C8F062D8BD5776E7B5F /* Pods_WHCServieRouter_Tests.framework */;
+			productType = "com.apple.product-type.framework";
+		};
+		F92F93F34E99B7C9FC4E583800F19759 /* WHCServieRouter */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = EDE92983702F58C461261B2D9A674CE3 /* Build configuration list for PBXNativeTarget "WHCServieRouter" */;
+			buildPhases = (
+				1D44629236E71B8D829E800C3A80DB49 /* Headers */,
+				DAEDAA2587476CAD528D8938C173A2F2 /* Sources */,
+				74F2D8F88707043A5EA74B29B89D41F3 /* Frameworks */,
+				A73715A07A88F06ECA7E70BC7F394B92 /* Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = WHCServieRouter;
+			productName = WHCServieRouter;
+			productReference = 9130F601A9B17510E81D4D533B72FEA1 /* WHCServieRouter.framework */;
+			productType = "com.apple.product-type.framework";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		BFDFE7DC352907FC980B868725387E98 /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				LastSwiftUpdateCheck = 1100;
+				LastUpgradeCheck = 1100;
+			};
+			buildConfigurationList = 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */;
+			compatibilityVersion = "Xcode 3.2";
+			developmentRegion = en;
+			hasScannedForEncodings = 0;
+			knownRegions = (
+				en,
+				Base,
+			);
+			mainGroup = CF1408CF629C7361332E53B88F7BD30C;
+			productRefGroup = 6ECC668D0396B8B758B052F007F3060D /* Products */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				4497A814413EC9C5753A10CFEDB23310 /* Pods-WHCServieRouter_Example */,
+				62CACEE8B616A038DA88E6C93EC3F7FF /* Pods-WHCServieRouter_Tests */,
+				F92F93F34E99B7C9FC4E583800F19759 /* WHCServieRouter */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+		A73715A07A88F06ECA7E70BC7F394B92 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		AB3D52835EF4177CBA644842AF7D07AB /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		D8093B69FCCB3738B67AD488264B1C87 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		AD272AE127505E9C705E32F8CCC3FAF3 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				8838490AFDDDBA692B99133C6B7A7C7F /* Pods-WHCServieRouter_Tests-dummy.m in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		DAEDAA2587476CAD528D8938C173A2F2 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				F1EBD2680A8A7FE42219A9D6C8F7A35A /* WHCServieRouter+Router.m in Sources */,
+				999F4339CBE8C0F20952D0CC4273E206 /* WHCServieRouter.m in Sources */,
+				1B5255A78A3017223226E3193C28E6FB /* WHCServieRouter-dummy.m in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		FE1FCC1AAD1F3A429040B361148EA2FA /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				EE2608CF676394FB563525DCA9A65F1C /* Pods-WHCServieRouter_Example-dummy.m in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+		90BF2DE820DEFE5820A9212071ACABD2 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			name = WHCServieRouter;
+			target = F92F93F34E99B7C9FC4E583800F19759 /* WHCServieRouter */;
+			targetProxy = 3D6B1A7028F6E7D9CA7D1DD1F0728430 /* PBXContainerItemProxy */;
+		};
+		EE1D6A37873A279B635129FF535EB033 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			name = "Pods-WHCServieRouter_Example";
+			target = 4497A814413EC9C5753A10CFEDB23310 /* Pods-WHCServieRouter_Example */;
+			targetProxy = D75B35FE6326E845B57CD94DA4A48777 /* PBXContainerItemProxy */;
+		};
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+		0BC51087128D3C014BB1E8D8F5545BCC /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = A083E6D67246444EACF002471668426B /* WHCServieRouter.debug.xcconfig */;
+			buildSettings = {
+				"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
+				"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
+				CURRENT_PROJECT_VERSION = 1;
+				DEFINES_MODULE = YES;
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				DYLIB_INSTALL_NAME_BASE = "@rpath";
+				GCC_PREFIX_HEADER = "Target Support Files/WHCServieRouter/WHCServieRouter-prefix.pch";
+				INFOPLIST_FILE = "Target Support Files/WHCServieRouter/WHCServieRouter-Info.plist";
+				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				MODULEMAP_FILE = "Target Support Files/WHCServieRouter/WHCServieRouter.modulemap";
+				PRODUCT_MODULE_NAME = WHCServieRouter;
+				PRODUCT_NAME = WHCServieRouter;
+				SDKROOT = iphoneos;
+				SKIP_INSTALL = YES;
+				SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) ";
+				SWIFT_VERSION = 4.0;
+				TARGETED_DEVICE_FAMILY = "1,2";
+				VERSIONING_SYSTEM = "apple-generic";
+				VERSION_INFO_PREFIX = "";
+			};
+			name = Debug;
+		};
+		25AD9454612BF454A1E3DC4CD4FA8C6D /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_ENABLE_OBJC_WEAK = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_COMMA = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_STRICT_PROTOTYPES = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				ENABLE_TESTABILITY = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu11;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"POD_CONFIGURATION_DEBUG=1",
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+				MTL_FAST_MATH = YES;
+				ONLY_ACTIVE_ARCH = YES;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				STRIP_INSTALLED_PRODUCT = NO;
+				SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+				SWIFT_VERSION = 5.0;
+				SYMROOT = "${SRCROOT}/../build";
+			};
+			name = Debug;
+		};
+		553A7ADAFC0CC0E7532F66E77027D0F0 /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 7BE24155B1DE1F6909D02EE602AD5848 /* Pods-WHCServieRouter_Tests.release.xcconfig */;
+			buildSettings = {
+				ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
+				"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
+				"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
+				CURRENT_PROJECT_VERSION = 1;
+				DEFINES_MODULE = YES;
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				DYLIB_INSTALL_NAME_BASE = "@rpath";
+				INFOPLIST_FILE = "Target Support Files/Pods-WHCServieRouter_Tests/Pods-WHCServieRouter_Tests-Info.plist";
+				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				MACH_O_TYPE = staticlib;
+				MODULEMAP_FILE = "Target Support Files/Pods-WHCServieRouter_Tests/Pods-WHCServieRouter_Tests.modulemap";
+				OTHER_LDFLAGS = "";
+				OTHER_LIBTOOLFLAGS = "";
+				PODS_ROOT = "$(SRCROOT)";
+				PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
+				PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
+				SDKROOT = iphoneos;
+				SKIP_INSTALL = YES;
+				TARGETED_DEVICE_FAMILY = "1,2";
+				VALIDATE_PRODUCT = YES;
+				VERSIONING_SYSTEM = "apple-generic";
+				VERSION_INFO_PREFIX = "";
+			};
+			name = Release;
+		};
+		5E4E683FE33A559CDE5FFD54294DAD3B /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = AF10082A339AA106A811B9F5190C39DA /* Pods-WHCServieRouter_Example.release.xcconfig */;
+			buildSettings = {
+				ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
+				"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
+				"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
+				CURRENT_PROJECT_VERSION = 1;
+				DEFINES_MODULE = YES;
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				DYLIB_INSTALL_NAME_BASE = "@rpath";
+				INFOPLIST_FILE = "Target Support Files/Pods-WHCServieRouter_Example/Pods-WHCServieRouter_Example-Info.plist";
+				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				MACH_O_TYPE = staticlib;
+				MODULEMAP_FILE = "Target Support Files/Pods-WHCServieRouter_Example/Pods-WHCServieRouter_Example.modulemap";
+				OTHER_LDFLAGS = "";
+				OTHER_LIBTOOLFLAGS = "";
+				PODS_ROOT = "$(SRCROOT)";
+				PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
+				PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
+				SDKROOT = iphoneos;
+				SKIP_INSTALL = YES;
+				TARGETED_DEVICE_FAMILY = "1,2";
+				VALIDATE_PRODUCT = YES;
+				VERSIONING_SYSTEM = "apple-generic";
+				VERSION_INFO_PREFIX = "";
+			};
+			name = Release;
+		};
+		66DB8FB03BA52A799DD2917E07312C12 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = C6D556435205A96E66E38651075C5267 /* Pods-WHCServieRouter_Example.debug.xcconfig */;
+			buildSettings = {
+				ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
+				"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
+				"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
+				CURRENT_PROJECT_VERSION = 1;
+				DEFINES_MODULE = YES;
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				DYLIB_INSTALL_NAME_BASE = "@rpath";
+				INFOPLIST_FILE = "Target Support Files/Pods-WHCServieRouter_Example/Pods-WHCServieRouter_Example-Info.plist";
+				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				MACH_O_TYPE = staticlib;
+				MODULEMAP_FILE = "Target Support Files/Pods-WHCServieRouter_Example/Pods-WHCServieRouter_Example.modulemap";
+				OTHER_LDFLAGS = "";
+				OTHER_LIBTOOLFLAGS = "";
+				PODS_ROOT = "$(SRCROOT)";
+				PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
+				PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
+				SDKROOT = iphoneos;
+				SKIP_INSTALL = YES;
+				TARGETED_DEVICE_FAMILY = "1,2";
+				VERSIONING_SYSTEM = "apple-generic";
+				VERSION_INFO_PREFIX = "";
+			};
+			name = Debug;
+		};
+		76D8B158D482A58D7EE5BF79B47727FA /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 85955D518BF1FDEF1B1FEB885BE75B9C /* WHCServieRouter.release.xcconfig */;
+			buildSettings = {
+				"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
+				"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
+				CURRENT_PROJECT_VERSION = 1;
+				DEFINES_MODULE = YES;
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				DYLIB_INSTALL_NAME_BASE = "@rpath";
+				GCC_PREFIX_HEADER = "Target Support Files/WHCServieRouter/WHCServieRouter-prefix.pch";
+				INFOPLIST_FILE = "Target Support Files/WHCServieRouter/WHCServieRouter-Info.plist";
+				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				MODULEMAP_FILE = "Target Support Files/WHCServieRouter/WHCServieRouter.modulemap";
+				PRODUCT_MODULE_NAME = WHCServieRouter;
+				PRODUCT_NAME = WHCServieRouter;
+				SDKROOT = iphoneos;
+				SKIP_INSTALL = YES;
+				SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) ";
+				SWIFT_VERSION = 4.0;
+				TARGETED_DEVICE_FAMILY = "1,2";
+				VALIDATE_PRODUCT = YES;
+				VERSIONING_SYSTEM = "apple-generic";
+				VERSION_INFO_PREFIX = "";
+			};
+			name = Release;
+		};
+		A4701C02F44DB0399B228C0FDC073887 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = E1F909187FA4FE20E4688CB6541A9F05 /* Pods-WHCServieRouter_Tests.debug.xcconfig */;
+			buildSettings = {
+				ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
+				"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
+				"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
+				CURRENT_PROJECT_VERSION = 1;
+				DEFINES_MODULE = YES;
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				DYLIB_INSTALL_NAME_BASE = "@rpath";
+				INFOPLIST_FILE = "Target Support Files/Pods-WHCServieRouter_Tests/Pods-WHCServieRouter_Tests-Info.plist";
+				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				MACH_O_TYPE = staticlib;
+				MODULEMAP_FILE = "Target Support Files/Pods-WHCServieRouter_Tests/Pods-WHCServieRouter_Tests.modulemap";
+				OTHER_LDFLAGS = "";
+				OTHER_LIBTOOLFLAGS = "";
+				PODS_ROOT = "$(SRCROOT)";
+				PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
+				PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
+				SDKROOT = iphoneos;
+				SKIP_INSTALL = YES;
+				TARGETED_DEVICE_FAMILY = "1,2";
+				VERSIONING_SYSTEM = "apple-generic";
+				VERSION_INFO_PREFIX = "";
+			};
+			name = Debug;
+		};
+		CA547D2C7E9A8A153DC2B27FBE00B112 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_ENABLE_OBJC_WEAK = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_COMMA = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_STRICT_PROTOTYPES = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_NS_ASSERTIONS = NO;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu11;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"POD_CONFIGURATION_RELEASE=1",
+					"$(inherited)",
+				);
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				MTL_ENABLE_DEBUG_INFO = NO;
+				MTL_FAST_MATH = YES;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				STRIP_INSTALLED_PRODUCT = NO;
+				SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
+				SWIFT_VERSION = 5.0;
+				SYMROOT = "${SRCROOT}/../build";
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		37F5B36B0FD05DDD955464C6F3AAC1CA /* Build configuration list for PBXNativeTarget "Pods-WHCServieRouter_Example" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				66DB8FB03BA52A799DD2917E07312C12 /* Debug */,
+				5E4E683FE33A559CDE5FFD54294DAD3B /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				25AD9454612BF454A1E3DC4CD4FA8C6D /* Debug */,
+				CA547D2C7E9A8A153DC2B27FBE00B112 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		73352A9314BFD5F6FEB8C2BEC26FA4A6 /* Build configuration list for PBXNativeTarget "Pods-WHCServieRouter_Tests" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				A4701C02F44DB0399B228C0FDC073887 /* Debug */,
+				553A7ADAFC0CC0E7532F66E77027D0F0 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		EDE92983702F58C461261B2D9A674CE3 /* Build configuration list for PBXNativeTarget "WHCServieRouter" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				0BC51087128D3C014BB1E8D8F5545BCC /* Debug */,
+				76D8B158D482A58D7EE5BF79B47727FA /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = BFDFE7DC352907FC980B868725387E98 /* Project object */;
+}

+ 26 - 0
Example/Pods/Target Support Files/Pods-WHCServieRouter_Example/Pods-WHCServieRouter_Example-Info.plist

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+  <key>CFBundleDevelopmentRegion</key>
+  <string>en</string>
+  <key>CFBundleExecutable</key>
+  <string>${EXECUTABLE_NAME}</string>
+  <key>CFBundleIdentifier</key>
+  <string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
+  <key>CFBundleInfoDictionaryVersion</key>
+  <string>6.0</string>
+  <key>CFBundleName</key>
+  <string>${PRODUCT_NAME}</string>
+  <key>CFBundlePackageType</key>
+  <string>FMWK</string>
+  <key>CFBundleShortVersionString</key>
+  <string>1.0.0</string>
+  <key>CFBundleSignature</key>
+  <string>????</string>
+  <key>CFBundleVersion</key>
+  <string>${CURRENT_PROJECT_VERSION}</string>
+  <key>NSPrincipalClass</key>
+  <string></string>
+</dict>
+</plist>

+ 26 - 0
Example/Pods/Target Support Files/Pods-WHCServieRouter_Example/Pods-WHCServieRouter_Example-acknowledgements.markdown

@@ -0,0 +1,26 @@
+# Acknowledgements
+This application makes use of the following third party libraries:
+
+## WHCServieRouter
+
+Copyright (c) 2021 ghost <fasac>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+Generated by CocoaPods - https://cocoapods.org

+ 58 - 0
Example/Pods/Target Support Files/Pods-WHCServieRouter_Example/Pods-WHCServieRouter_Example-acknowledgements.plist

@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>PreferenceSpecifiers</key>
+	<array>
+		<dict>
+			<key>FooterText</key>
+			<string>This application makes use of the following third party libraries:</string>
+			<key>Title</key>
+			<string>Acknowledgements</string>
+			<key>Type</key>
+			<string>PSGroupSpecifier</string>
+		</dict>
+		<dict>
+			<key>FooterText</key>
+			<string>Copyright (c) 2021 ghost &lt;fasac&gt;
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+</string>
+			<key>License</key>
+			<string>MIT</string>
+			<key>Title</key>
+			<string>WHCServieRouter</string>
+			<key>Type</key>
+			<string>PSGroupSpecifier</string>
+		</dict>
+		<dict>
+			<key>FooterText</key>
+			<string>Generated by CocoaPods - https://cocoapods.org</string>
+			<key>Title</key>
+			<string></string>
+			<key>Type</key>
+			<string>PSGroupSpecifier</string>
+		</dict>
+	</array>
+	<key>StringsTable</key>
+	<string>Acknowledgements</string>
+	<key>Title</key>
+	<string>Acknowledgements</string>
+</dict>
+</plist>

+ 5 - 0
Example/Pods/Target Support Files/Pods-WHCServieRouter_Example/Pods-WHCServieRouter_Example-dummy.m

@@ -0,0 +1,5 @@
+#import <Foundation/Foundation.h>
+@interface PodsDummy_Pods_WHCServieRouter_Example : NSObject
+@end
+@implementation PodsDummy_Pods_WHCServieRouter_Example
+@end

+ 185 - 0
Example/Pods/Target Support Files/Pods-WHCServieRouter_Example/Pods-WHCServieRouter_Example-frameworks.sh

@@ -0,0 +1,185 @@
+#!/bin/sh
+set -e
+set -u
+set -o pipefail
+
+function on_error {
+  echo "$(realpath -mq "${0}"):$1: error: Unexpected failure"
+}
+trap 'on_error $LINENO' ERR
+
+if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then
+  # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy
+  # frameworks to, so exit 0 (signalling the script phase was successful).
+  exit 0
+fi
+
+echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
+mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
+
+COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}"
+SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
+BCSYMBOLMAP_DIR="BCSymbolMaps"
+
+
+# This protects against multiple targets copying the same framework dependency at the same time. The solution
+# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
+RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
+
+# Copies and strips a vendored framework
+install_framework()
+{
+  if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
+    local source="${BUILT_PRODUCTS_DIR}/$1"
+  elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
+    local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
+  elif [ -r "$1" ]; then
+    local source="$1"
+  fi
+
+  local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
+
+  if [ -L "${source}" ]; then
+    echo "Symlinked..."
+    source="$(readlink "${source}")"
+  fi
+
+  if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then
+    # Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied
+    find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do
+      echo "Installing $f"
+      install_bcsymbolmap "$f" "$destination"
+      rm "$f"
+    done
+    rmdir "${source}/${BCSYMBOLMAP_DIR}"
+  fi
+
+  # Use filter instead of exclude so missing patterns don't throw errors.
+  echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
+  rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
+
+  local basename
+  basename="$(basename -s .framework "$1")"
+  binary="${destination}/${basename}.framework/${basename}"
+
+  if ! [ -r "$binary" ]; then
+    binary="${destination}/${basename}"
+  elif [ -L "${binary}" ]; then
+    echo "Destination binary is symlinked..."
+    dirname="$(dirname "${binary}")"
+    binary="${dirname}/$(readlink "${binary}")"
+  fi
+
+  # Strip invalid architectures so "fat" simulator / device frameworks work on device
+  if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
+    strip_invalid_archs "$binary"
+  fi
+
+  # Resign the code if required by the build settings to avoid unstable apps
+  code_sign_if_enabled "${destination}/$(basename "$1")"
+
+  # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
+  if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
+    local swift_runtime_libs
+    swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u)
+    for lib in $swift_runtime_libs; do
+      echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
+      rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
+      code_sign_if_enabled "${destination}/${lib}"
+    done
+  fi
+}
+# Copies and strips a vendored dSYM
+install_dsym() {
+  local source="$1"
+  warn_missing_arch=${2:-true}
+  if [ -r "$source" ]; then
+    # Copy the dSYM into the targets temp dir.
+    echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\""
+    rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}"
+
+    local basename
+    basename="$(basename -s .dSYM "$source")"
+    binary_name="$(ls "$source/Contents/Resources/DWARF")"
+    binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}"
+
+    # Strip invalid architectures from the dSYM.
+    if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then
+      strip_invalid_archs "$binary" "$warn_missing_arch"
+    fi
+    if [[ $STRIP_BINARY_RETVAL == 0 ]]; then
+      # Move the stripped file into its final destination.
+      echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
+      rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
+    else
+      # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing.
+      touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM"
+    fi
+  fi
+}
+
+# Used as a return value for each invocation of `strip_invalid_archs` function.
+STRIP_BINARY_RETVAL=0
+
+# Strip invalid architectures
+strip_invalid_archs() {
+  binary="$1"
+  warn_missing_arch=${2:-true}
+  # Get architectures for current target binary
+  binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
+  # Intersect them with the architectures we are building for
+  intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
+  # If there are no archs supported by this binary then warn the user
+  if [[ -z "$intersected_archs" ]]; then
+    if [[ "$warn_missing_arch" == "true" ]]; then
+      echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
+    fi
+    STRIP_BINARY_RETVAL=1
+    return
+  fi
+  stripped=""
+  for arch in $binary_archs; do
+    if ! [[ "${ARCHS}" == *"$arch"* ]]; then
+      # Strip non-valid architectures in-place
+      lipo -remove "$arch" -output "$binary" "$binary"
+      stripped="$stripped $arch"
+    fi
+  done
+  if [[ "$stripped" ]]; then
+    echo "Stripped $binary of architectures:$stripped"
+  fi
+  STRIP_BINARY_RETVAL=0
+}
+
+# Copies the bcsymbolmap files of a vendored framework
+install_bcsymbolmap() {
+    local bcsymbolmap_path="$1"
+    local destination="${BUILT_PRODUCTS_DIR}"
+    echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}""
+    rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"
+}
+
+# Signs a framework with the provided identity
+code_sign_if_enabled() {
+  if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
+    # Use the current code_sign_identity
+    echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
+    local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'"
+
+    if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
+      code_sign_cmd="$code_sign_cmd &"
+    fi
+    echo "$code_sign_cmd"
+    eval "$code_sign_cmd"
+  fi
+}
+
+if [[ "$CONFIGURATION" == "Debug" ]]; then
+  install_framework "${BUILT_PRODUCTS_DIR}/WHCServieRouter/WHCServieRouter.framework"
+fi
+if [[ "$CONFIGURATION" == "Release" ]]; then
+  install_framework "${BUILT_PRODUCTS_DIR}/WHCServieRouter/WHCServieRouter.framework"
+fi
+if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
+  wait
+fi

+ 16 - 0
Example/Pods/Target Support Files/Pods-WHCServieRouter_Example/Pods-WHCServieRouter_Example-umbrella.h

@@ -0,0 +1,16 @@
+#ifdef __OBJC__
+#import <UIKit/UIKit.h>
+#else
+#ifndef FOUNDATION_EXPORT
+#if defined(__cplusplus)
+#define FOUNDATION_EXPORT extern "C"
+#else
+#define FOUNDATION_EXPORT extern
+#endif
+#endif
+#endif
+
+
+FOUNDATION_EXPORT double Pods_WHCServieRouter_ExampleVersionNumber;
+FOUNDATION_EXPORT const unsigned char Pods_WHCServieRouter_ExampleVersionString[];
+

+ 12 - 0
Example/Pods/Target Support Files/Pods-WHCServieRouter_Example/Pods-WHCServieRouter_Example.debug.xcconfig

@@ -0,0 +1,12 @@
+CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
+FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/WHCServieRouter"
+GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
+HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/WHCServieRouter/WHCServieRouter.framework/Headers"
+LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
+OTHER_LDFLAGS = $(inherited) -framework "WHCServieRouter"
+PODS_BUILD_DIR = ${BUILD_DIR}
+PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
+PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
+PODS_ROOT = ${SRCROOT}/Pods
+PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
+USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES

+ 6 - 0
Example/Pods/Target Support Files/Pods-WHCServieRouter_Example/Pods-WHCServieRouter_Example.modulemap

@@ -0,0 +1,6 @@
+framework module Pods_WHCServieRouter_Example {
+  umbrella header "Pods-WHCServieRouter_Example-umbrella.h"
+
+  export *
+  module * { export * }
+}

+ 12 - 0
Example/Pods/Target Support Files/Pods-WHCServieRouter_Example/Pods-WHCServieRouter_Example.release.xcconfig

@@ -0,0 +1,12 @@
+CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
+FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/WHCServieRouter"
+GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
+HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/WHCServieRouter/WHCServieRouter.framework/Headers"
+LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
+OTHER_LDFLAGS = $(inherited) -framework "WHCServieRouter"
+PODS_BUILD_DIR = ${BUILD_DIR}
+PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
+PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
+PODS_ROOT = ${SRCROOT}/Pods
+PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
+USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES

+ 26 - 0
Example/Pods/Target Support Files/Pods-WHCServieRouter_Tests/Pods-WHCServieRouter_Tests-Info.plist

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+  <key>CFBundleDevelopmentRegion</key>
+  <string>en</string>
+  <key>CFBundleExecutable</key>
+  <string>${EXECUTABLE_NAME}</string>
+  <key>CFBundleIdentifier</key>
+  <string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
+  <key>CFBundleInfoDictionaryVersion</key>
+  <string>6.0</string>
+  <key>CFBundleName</key>
+  <string>${PRODUCT_NAME}</string>
+  <key>CFBundlePackageType</key>
+  <string>FMWK</string>
+  <key>CFBundleShortVersionString</key>
+  <string>1.0.0</string>
+  <key>CFBundleSignature</key>
+  <string>????</string>
+  <key>CFBundleVersion</key>
+  <string>${CURRENT_PROJECT_VERSION}</string>
+  <key>NSPrincipalClass</key>
+  <string></string>
+</dict>
+</plist>

+ 3 - 0
Example/Pods/Target Support Files/Pods-WHCServieRouter_Tests/Pods-WHCServieRouter_Tests-acknowledgements.markdown

@@ -0,0 +1,3 @@
+# Acknowledgements
+This application makes use of the following third party libraries:
+Generated by CocoaPods - https://cocoapods.org

+ 29 - 0
Example/Pods/Target Support Files/Pods-WHCServieRouter_Tests/Pods-WHCServieRouter_Tests-acknowledgements.plist

@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>PreferenceSpecifiers</key>
+	<array>
+		<dict>
+			<key>FooterText</key>
+			<string>This application makes use of the following third party libraries:</string>
+			<key>Title</key>
+			<string>Acknowledgements</string>
+			<key>Type</key>
+			<string>PSGroupSpecifier</string>
+		</dict>
+		<dict>
+			<key>FooterText</key>
+			<string>Generated by CocoaPods - https://cocoapods.org</string>
+			<key>Title</key>
+			<string></string>
+			<key>Type</key>
+			<string>PSGroupSpecifier</string>
+		</dict>
+	</array>
+	<key>StringsTable</key>
+	<string>Acknowledgements</string>
+	<key>Title</key>
+	<string>Acknowledgements</string>
+</dict>
+</plist>

+ 5 - 0
Example/Pods/Target Support Files/Pods-WHCServieRouter_Tests/Pods-WHCServieRouter_Tests-dummy.m

@@ -0,0 +1,5 @@
+#import <Foundation/Foundation.h>
+@interface PodsDummy_Pods_WHCServieRouter_Tests : NSObject
+@end
+@implementation PodsDummy_Pods_WHCServieRouter_Tests
+@end

+ 185 - 0
Example/Pods/Target Support Files/Pods-WHCServieRouter_Tests/Pods-WHCServieRouter_Tests-frameworks.sh

@@ -0,0 +1,185 @@
+#!/bin/sh
+set -e
+set -u
+set -o pipefail
+
+function on_error {
+  echo "$(realpath -mq "${0}"):$1: error: Unexpected failure"
+}
+trap 'on_error $LINENO' ERR
+
+if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then
+  # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy
+  # frameworks to, so exit 0 (signalling the script phase was successful).
+  exit 0
+fi
+
+echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
+mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
+
+COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}"
+SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
+BCSYMBOLMAP_DIR="BCSymbolMaps"
+
+
+# This protects against multiple targets copying the same framework dependency at the same time. The solution
+# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
+RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
+
+# Copies and strips a vendored framework
+install_framework()
+{
+  if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
+    local source="${BUILT_PRODUCTS_DIR}/$1"
+  elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
+    local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
+  elif [ -r "$1" ]; then
+    local source="$1"
+  fi
+
+  local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
+
+  if [ -L "${source}" ]; then
+    echo "Symlinked..."
+    source="$(readlink "${source}")"
+  fi
+
+  if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then
+    # Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied
+    find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do
+      echo "Installing $f"
+      install_bcsymbolmap "$f" "$destination"
+      rm "$f"
+    done
+    rmdir "${source}/${BCSYMBOLMAP_DIR}"
+  fi
+
+  # Use filter instead of exclude so missing patterns don't throw errors.
+  echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
+  rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
+
+  local basename
+  basename="$(basename -s .framework "$1")"
+  binary="${destination}/${basename}.framework/${basename}"
+
+  if ! [ -r "$binary" ]; then
+    binary="${destination}/${basename}"
+  elif [ -L "${binary}" ]; then
+    echo "Destination binary is symlinked..."
+    dirname="$(dirname "${binary}")"
+    binary="${dirname}/$(readlink "${binary}")"
+  fi
+
+  # Strip invalid architectures so "fat" simulator / device frameworks work on device
+  if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
+    strip_invalid_archs "$binary"
+  fi
+
+  # Resign the code if required by the build settings to avoid unstable apps
+  code_sign_if_enabled "${destination}/$(basename "$1")"
+
+  # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
+  if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
+    local swift_runtime_libs
+    swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u)
+    for lib in $swift_runtime_libs; do
+      echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
+      rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
+      code_sign_if_enabled "${destination}/${lib}"
+    done
+  fi
+}
+# Copies and strips a vendored dSYM
+install_dsym() {
+  local source="$1"
+  warn_missing_arch=${2:-true}
+  if [ -r "$source" ]; then
+    # Copy the dSYM into the targets temp dir.
+    echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\""
+    rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}"
+
+    local basename
+    basename="$(basename -s .dSYM "$source")"
+    binary_name="$(ls "$source/Contents/Resources/DWARF")"
+    binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}"
+
+    # Strip invalid architectures from the dSYM.
+    if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then
+      strip_invalid_archs "$binary" "$warn_missing_arch"
+    fi
+    if [[ $STRIP_BINARY_RETVAL == 0 ]]; then
+      # Move the stripped file into its final destination.
+      echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
+      rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
+    else
+      # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing.
+      touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM"
+    fi
+  fi
+}
+
+# Used as a return value for each invocation of `strip_invalid_archs` function.
+STRIP_BINARY_RETVAL=0
+
+# Strip invalid architectures
+strip_invalid_archs() {
+  binary="$1"
+  warn_missing_arch=${2:-true}
+  # Get architectures for current target binary
+  binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
+  # Intersect them with the architectures we are building for
+  intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
+  # If there are no archs supported by this binary then warn the user
+  if [[ -z "$intersected_archs" ]]; then
+    if [[ "$warn_missing_arch" == "true" ]]; then
+      echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
+    fi
+    STRIP_BINARY_RETVAL=1
+    return
+  fi
+  stripped=""
+  for arch in $binary_archs; do
+    if ! [[ "${ARCHS}" == *"$arch"* ]]; then
+      # Strip non-valid architectures in-place
+      lipo -remove "$arch" -output "$binary" "$binary"
+      stripped="$stripped $arch"
+    fi
+  done
+  if [[ "$stripped" ]]; then
+    echo "Stripped $binary of architectures:$stripped"
+  fi
+  STRIP_BINARY_RETVAL=0
+}
+
+# Copies the bcsymbolmap files of a vendored framework
+install_bcsymbolmap() {
+    local bcsymbolmap_path="$1"
+    local destination="${BUILT_PRODUCTS_DIR}"
+    echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}""
+    rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"
+}
+
+# Signs a framework with the provided identity
+code_sign_if_enabled() {
+  if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
+    # Use the current code_sign_identity
+    echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
+    local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'"
+
+    if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
+      code_sign_cmd="$code_sign_cmd &"
+    fi
+    echo "$code_sign_cmd"
+    eval "$code_sign_cmd"
+  fi
+}
+
+if [[ "$CONFIGURATION" == "Debug" ]]; then
+  install_framework "${BUILT_PRODUCTS_DIR}/FBSnapshotTestCase/FBSnapshotTestCase.framework"
+fi
+if [[ "$CONFIGURATION" == "Release" ]]; then
+  install_framework "${BUILT_PRODUCTS_DIR}/FBSnapshotTestCase/FBSnapshotTestCase.framework"
+fi
+if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
+  wait
+fi

+ 16 - 0
Example/Pods/Target Support Files/Pods-WHCServieRouter_Tests/Pods-WHCServieRouter_Tests-umbrella.h

@@ -0,0 +1,16 @@
+#ifdef __OBJC__
+#import <UIKit/UIKit.h>
+#else
+#ifndef FOUNDATION_EXPORT
+#if defined(__cplusplus)
+#define FOUNDATION_EXPORT extern "C"
+#else
+#define FOUNDATION_EXPORT extern
+#endif
+#endif
+#endif
+
+
+FOUNDATION_EXPORT double Pods_WHCServieRouter_TestsVersionNumber;
+FOUNDATION_EXPORT const unsigned char Pods_WHCServieRouter_TestsVersionString[];
+

+ 11 - 0
Example/Pods/Target Support Files/Pods-WHCServieRouter_Tests/Pods-WHCServieRouter_Tests.debug.xcconfig

@@ -0,0 +1,11 @@
+CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
+FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/WHCServieRouter"
+GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
+HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/WHCServieRouter/WHCServieRouter.framework/Headers"
+OTHER_LDFLAGS = $(inherited) -framework "WHCServieRouter"
+PODS_BUILD_DIR = ${BUILD_DIR}
+PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
+PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
+PODS_ROOT = ${SRCROOT}/Pods
+PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
+USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES

+ 6 - 0
Example/Pods/Target Support Files/Pods-WHCServieRouter_Tests/Pods-WHCServieRouter_Tests.modulemap

@@ -0,0 +1,6 @@
+framework module Pods_WHCServieRouter_Tests {
+  umbrella header "Pods-WHCServieRouter_Tests-umbrella.h"
+
+  export *
+  module * { export * }
+}

+ 11 - 0
Example/Pods/Target Support Files/Pods-WHCServieRouter_Tests/Pods-WHCServieRouter_Tests.release.xcconfig

@@ -0,0 +1,11 @@
+CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
+FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/WHCServieRouter"
+GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
+HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/WHCServieRouter/WHCServieRouter.framework/Headers"
+OTHER_LDFLAGS = $(inherited) -framework "WHCServieRouter"
+PODS_BUILD_DIR = ${BUILD_DIR}
+PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
+PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
+PODS_ROOT = ${SRCROOT}/Pods
+PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
+USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES

+ 26 - 0
Example/Pods/Target Support Files/WHCServieRouter/WHCServieRouter-Info.plist

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+  <key>CFBundleDevelopmentRegion</key>
+  <string>en</string>
+  <key>CFBundleExecutable</key>
+  <string>${EXECUTABLE_NAME}</string>
+  <key>CFBundleIdentifier</key>
+  <string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
+  <key>CFBundleInfoDictionaryVersion</key>
+  <string>6.0</string>
+  <key>CFBundleName</key>
+  <string>${PRODUCT_NAME}</string>
+  <key>CFBundlePackageType</key>
+  <string>FMWK</string>
+  <key>CFBundleShortVersionString</key>
+  <string>0.1.0</string>
+  <key>CFBundleSignature</key>
+  <string>????</string>
+  <key>CFBundleVersion</key>
+  <string>${CURRENT_PROJECT_VERSION}</string>
+  <key>NSPrincipalClass</key>
+  <string></string>
+</dict>
+</plist>

+ 5 - 0
Example/Pods/Target Support Files/WHCServieRouter/WHCServieRouter-dummy.m

@@ -0,0 +1,5 @@
+#import <Foundation/Foundation.h>
+@interface PodsDummy_WHCServieRouter : NSObject
+@end
+@implementation PodsDummy_WHCServieRouter
+@end

+ 12 - 0
Example/Pods/Target Support Files/WHCServieRouter/WHCServieRouter-prefix.pch

@@ -0,0 +1,12 @@
+#ifdef __OBJC__
+#import <UIKit/UIKit.h>
+#else
+#ifndef FOUNDATION_EXPORT
+#if defined(__cplusplus)
+#define FOUNDATION_EXPORT extern "C"
+#else
+#define FOUNDATION_EXPORT extern
+#endif
+#endif
+#endif
+

+ 20 - 0
Example/Pods/Target Support Files/WHCServieRouter/WHCServieRouter-umbrella.h

@@ -0,0 +1,20 @@
+#ifdef __OBJC__
+#import <UIKit/UIKit.h>
+#else
+#ifndef FOUNDATION_EXPORT
+#if defined(__cplusplus)
+#define FOUNDATION_EXPORT extern "C"
+#else
+#define FOUNDATION_EXPORT extern
+#endif
+#endif
+#endif
+
+#import "Bifrost+Router.h"
+#import "Bifrost.h"
+#import "BifrostHeader.h"
+#import "BifrostProtocol.h"
+
+FOUNDATION_EXPORT double WHCServieRouterVersionNumber;
+FOUNDATION_EXPORT const unsigned char WHCServieRouterVersionString[];
+

+ 11 - 0
Example/Pods/Target Support Files/WHCServieRouter/WHCServieRouter.debug.xcconfig

@@ -0,0 +1,11 @@
+CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
+CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/WHCServieRouter
+GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
+PODS_BUILD_DIR = ${BUILD_DIR}
+PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
+PODS_ROOT = ${SRCROOT}
+PODS_TARGET_SRCROOT = ${PODS_ROOT}/../..
+PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
+PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
+SKIP_INSTALL = YES
+USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES

+ 6 - 0
Example/Pods/Target Support Files/WHCServieRouter/WHCServieRouter.modulemap

@@ -0,0 +1,6 @@
+framework module WHCServieRouter {
+  umbrella header "WHCServieRouter-umbrella.h"
+
+  export *
+  module * { export * }
+}

+ 11 - 0
Example/Pods/Target Support Files/WHCServieRouter/WHCServieRouter.release.xcconfig

@@ -0,0 +1,11 @@
+CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
+CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/WHCServieRouter
+GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
+PODS_BUILD_DIR = ${BUILD_DIR}
+PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
+PODS_ROOT = ${SRCROOT}
+PODS_TARGET_SRCROOT = ${PODS_ROOT}/../..
+PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
+PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
+SKIP_INSTALL = YES
+USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES

+ 1 - 1
Example/Tests/Tests-Prefix.pch

@@ -2,6 +2,6 @@
 
 #ifdef __OBJC__
 
-  @import FBSnapshotTestCase;
+//  @import FBSnapshotTestCase;
 
 #endif

+ 0 - 19
Example/WHCServieRouter.xcodeproj/project.pbxproj

@@ -227,7 +227,6 @@
 				6003F5AA195388D20070C39A /* Sources */,
 				6003F5AB195388D20070C39A /* Frameworks */,
 				6003F5AC195388D20070C39A /* Resources */,
-				40DD3D9E8FB4FCBEA94648C6 /* [CP] Embed Pods Frameworks */,
 			);
 			buildRules = (
 			);
@@ -296,24 +295,6 @@
 /* End PBXResourcesBuildPhase section */
 
 /* Begin PBXShellScriptBuildPhase section */
-		40DD3D9E8FB4FCBEA94648C6 /* [CP] Embed Pods Frameworks */ = {
-			isa = PBXShellScriptBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			inputPaths = (
-				"${PODS_ROOT}/Target Support Files/Pods-WHCServieRouter_Tests/Pods-WHCServieRouter_Tests-frameworks.sh",
-				"${BUILT_PRODUCTS_DIR}/FBSnapshotTestCase/FBSnapshotTestCase.framework",
-			);
-			name = "[CP] Embed Pods Frameworks";
-			outputPaths = (
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FBSnapshotTestCase.framework",
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-			shellPath = /bin/sh;
-			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-WHCServieRouter_Tests/Pods-WHCServieRouter_Tests-frameworks.sh\"\n";
-			showEnvVarsInLog = 0;
-		};
 		9342470473C66C2AC134D407 /* [CP] Check Pods Manifest.lock */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;

+ 10 - 0
Example/WHCServieRouter.xcworkspace/contents.xcworkspacedata

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

+ 8 - 0
Example/WHCServieRouter.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist

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

+ 5 - 7
WHCServieRouter.podspec

@@ -8,8 +8,8 @@
 
 Pod::Spec.new do |s|
   s.name             = 'WHCServieRouter'
-  s.version          = '0.1.0'
-  s.summary          = 'A short description of WHCServieRouter.'
+  s.version          = '0.0.1'
+  s.summary          = '组件化service+router'
 
 # This description is used to generate tags and improve search results.
 #   * Think: What does it do? Why did you write it? What is the focus?
@@ -17,15 +17,13 @@ Pod::Spec.new do |s|
 #   * Write the description between the DESC delimiters below.
 #   * Finally, don't worry about the indent, CocoaPods strips it!
 
-  s.description      = <<-DESC
-TODO: Add long description of the pod here.
-                       DESC
+  s.description      = '组件化service+router,没个模块都需要引入'
 
-  s.homepage         = 'https://github.com/ghost/WHCServieRouter'
+  s.homepage         = 'http://139.224.213.4:3000/yushangxiang'
   # s.screenshots     = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
   s.license          = { :type => 'MIT', :file => 'LICENSE' }
   s.author           = { 'ghost' => 'fasac' }
-  s.source           = { :git => 'https://github.com/ghost/WHCServieRouter.git', :tag => s.version.to_s }
+  s.source           = { :git => 'http://139.224.213.4:3000/yushangxiang/WHCServieRouter.git', :tag => s.version.to_s }
   # s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>'
 
   s.ios.deployment_target = '9.0'

+ 0 - 0
WHCServieRouter/Classes/ReplaceMe.m


+ 104 - 0
WHCServieRouter/Classes/WHCServiceRouter/WHCServieRouter+Router.h

@@ -0,0 +1,104 @@
+//
+//  WHCServieRouter+Router.h
+//  WHCServieRouter
+//
+//  Created by yangke on 2017/9/15.
+//  Copyright © 2017年 jackie@youzan. All rights reserved.
+//
+
+#import "WHCServieRouter.h"
+
+#define BFComplete(Params, Result) [WHCServieRouter completeWithParameters:Params result:Result]
+
+// default keys in the parameters of WHCServieRouterRouteHandler
+extern NSString * _Nonnull const kWHCServieRouterURL; //the key for the raw url
+extern NSString * _Nonnull const kWHCServieRouterCompletion; //the key for the completion block.
+
+/**
+ The handler for a binded url
+ 
+ @param parameters containers above 2 keys and parameters from the query string and complexParams
+ @return the obj returned by the handler
+ */
+typedef _Nullable id (^WHCServieRouterHandler)( NSDictionary * _Nullable parameters);
+
+/**
+ The completion block to be invoked at the end of the router handler block
+ 
+ @param result completion result. defaultly it is the returned object of the WHCServieRouterRouteHandler.
+ */
+typedef void (^WHCServieRouterCompletion)(_Nullable id result);
+
+@interface WHCServieRouter (Router)
+
+/**
+ The method to bind a URL to handler
+ 
+ @param urlStr The URL string. Only scheme, host and api path will be used here.
+ Its query string will be ignore here.
+ @param handler the handler block.
+ The WHCServieRouterRouteCompletion should be invoked at the end of the block
+ */
++ (void)bindURL:(nonnull NSString *)urlStr toHandler:(nonnull WHCServieRouterHandler)handler;
+
+/**
+ The method to unbind a URL
+ 
+ @param urlStr The URL string. Only scheme, host and api path will be used here.
+ Its query string will be ignore here.
+ */
++ (void)unbindURL:(nonnull NSString *)urlStr;
+
+/**
+ Method to unbind all URLs
+ */
++ (void)unbindAllURLs;
+
+/**
+ The method to check whether a url can be handled
+ 
+ @param urlStr The URL string. Only scheme, host and api path will be used here.
+ Its query string will be ignore here.
+ */
++ (BOOL)canHandleURL:(nonnull NSString *)urlStr;
+
+/**
+ Method to handle the URL
+ 
+ @param urlStr URL string
+ @return the returned object of the url's WHCServieRouterRouteHandler
+ */
++ (nullable id)handleURL:(nonnull NSString *)urlStr;
+
+/**
+ Method to handle the url with completion block
+ 
+ @param urlStr URL string
+ @param completion The completion block
+ @return the returned object of the url's WHCServieRouterRouteHandler
+ */
++ (nullable id)handleURL:(nonnull NSString *)urlStr
+              completion:(nullable WHCServieRouterCompletion)completion;
+
+/**
+ The method to handle URL with complex parameters and completion block
+ 
+ @param urlStr URL string
+ @param complexParams complex parameters that can't be put in the url query strings
+ @param completion The completion block
+ @return the returned object of the url's WHCServieRouterRouteHandler
+ */
++ (nullable id)handleURL:(nonnull NSString *)urlStr
+           complexParams:(nullable NSDictionary*)complexParams
+              completion:(nullable WHCServieRouterCompletion)completion;
+
+/**
+ Invoke the completion block in the parameters of WHCServieRouterRouteHandler.
+ Recommend to use macro BFComplete for convenient.
+ 
+ @param params parameters of WHCServieRouterRouteHandler
+ @param result the result for the WHCServieRouterRouteCompletion
+ */
++ (void)completeWithParameters:(nullable NSDictionary*)params result:(_Nullable id)result;
+
+@end

+ 141 - 0
WHCServieRouter/Classes/WHCServiceRouter/WHCServieRouter+Router.m

@@ -0,0 +1,141 @@
+//
+//  WHCServieRouter+Router.m
+//  WHCServieRouter
+//
+//  Created by yangke on 2017/9/15.
+//  Copyright © 2017年 jackie@youzan. All rights reserved.
+//
+
+#import "WHCServieRouter+Router.h"
+
+#define WSLog(msg) NSLog(@"[WHCServieRouter] %@", (msg))
+#define WSKey(URL) [WHCServieRouter keyForURL:URL]
+
+NSString *const kWHCServieRouterURL = @"KWHCServieRouteURL";
+NSString *const kWHCServieRouterCompletion = @"kWHCServieRouterCompletion";
+
+@implementation WHCServieRouter (Router)
+
++ (nonnull NSString*)keyForURL:(nonnull NSString*)urlStr {
+    NSURL *URL = [NSURL URLWithString:urlStr];
+    NSString *key = [NSString stringWithFormat:@"%@%@", URL.host, URL.path];
+    return key;
+}
+
++ (nullable NSDictionary*)parametersInURL:(nonnull NSString*)urlStr {
+    NSURL *URL = [NSURL URLWithString:urlStr];
+    NSMutableDictionary *params = nil;
+    NSString *query = URL.query;
+    if(query.length > 0) {
+        params = [NSMutableDictionary dictionary];
+        NSArray *list = [query componentsSeparatedByString:@"&"];
+        for (NSString *param in list) {
+            NSArray *elts = [param componentsSeparatedByString:@"="];
+            if([elts count] < 2) continue;
+            NSString *decodedStr = [[elts lastObject] stringByRemovingPercentEncoding];
+            [params setObject:decodedStr forKey:[elts firstObject]];
+        }
+    }
+    return params;
+}
+
++ (NSMutableDictionary*)routes {
+    @synchronized (self) {
+        static NSMutableDictionary *_routes = nil;
+        if (!_routes) {
+            _routes = [NSMutableDictionary dictionary];
+        }
+        return _routes;
+    }
+}
+
++ (void)bindURL:(nonnull NSString *)urlStr toHandler:(nonnull WHCServieRouterHandler)handler {
+    [self.routes setObject:handler forKey:WSKey(urlStr)];
+}
+
++ (void)unbindURL:(nonnull NSString *)urlStr {
+    [self.routes removeObjectForKey:WSKey(urlStr)];
+}
+
++ (void)unbindAllURLs {
+    [self.routes removeAllObjects];
+}
+
++ (nullable WHCServieRouterHandler)handlerForURL:(nonnull NSString *)urlStr {
+    return [self.routes objectForKey:WSKey(urlStr)];
+}
+
++ (BOOL)canHandleURL:(nonnull NSString *)urlStr {
+    if (urlStr.length == 0) {
+        return NO;
+    }
+    if ([self handlerForURL:urlStr]) {
+        return YES;
+    } else {
+        return NO;
+    }
+}
+
++ (nullable id)handleURL:(nonnull NSString *)urlStr {
+    return [self handleURL:urlStr complexParams:nil completion:nil];
+}
+
++ (nullable id)handleURL:(nonnull NSString *)urlStr
+              completion:(nullable WHCServieRouterCompletion)completion {
+    return [self handleURL:urlStr complexParams:nil completion:completion];
+}
+
++ (nullable id)handleURL:(nonnull NSString *)urlStr
+           complexParams:(nullable NSDictionary*)complexParams
+              completion:(nullable WHCServieRouterCompletion)completion {
+    id obj = nil;
+    @try {
+        WHCServieRouterHandler handler = [self handlerForURL:urlStr];
+        NSMutableDictionary *params = [NSMutableDictionary dictionaryWithDictionary:complexParams];
+        [params addEntriesFromDictionary:[self.class parametersInURL:urlStr]];
+        [params setObject:urlStr forKey:kWHCServieRouterURL];
+        if (completion) {
+            [params setObject:completion forKey:kWHCServieRouterCompletion];
+        }
+        if (!handler) {
+            NSString *reason = [NSString stringWithFormat:@"Cannot find handler for route url %@", urlStr];
+            NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
+            [userInfo setValue:@(WSExceptionUrlHandlerNotFound) forKey:kWHCServieRouterExceptionCode];
+            [userInfo setValue:urlStr forKey:kWHCServieRouterExceptionURLStr];
+            [userInfo setValue:params forKey:kWHCServieRouterExceptionURLParams];
+            NSException *exception = [[NSException alloc] initWithName:WHCServieRouterExceptionName                                                                reason:reason
+                                                              userInfo:userInfo];
+            WHCServieRouterExceptionHandler handler = [self getExceptionHandler];
+            if (handler) {
+                obj = handler(exception);
+            }
+            WSLog(reason);
+        } else {
+            obj = handler(params);
+        }
+    } @catch (NSException *exception) {
+        NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithDictionary:exception.userInfo];
+        [userInfo setValue:@(WSExceptionDefaultCode) forKey:kWHCServieRouterExceptionCode];
+        [userInfo setValue:urlStr forKey:kWHCServieRouterExceptionURLStr];
+        [userInfo setValue:complexParams forKey:kWHCServieRouterExceptionURLParams];
+        NSException *ex = [[NSException alloc] initWithName:exception.name
+                                                     reason:exception.reason
+                                                   userInfo:userInfo];
+        WHCServieRouterExceptionHandler handler = [self getExceptionHandler];
+        if (handler) {
+            obj = handler(ex);
+        }
+        WSLog(exception.reason);
+    } @finally {
+        return obj;
+    }
+}
+
++ (void)completeWithParameters:(nullable NSDictionary*)params result:(_Nullable id)result {
+    WHCServieRouterCompletion completion = params[kWHCServieRouterCompletion];
+    if (completion) {
+        completion(result);
+    }
+}
+
+@end

+ 113 - 0
WHCServieRouter/Classes/WHCServiceRouter/WHCServieRouter.h

@@ -0,0 +1,113 @@
+//
+//  Bifrost.h
+//  Bifrost
+//
+//  Created by yangke on 2017/9/15.
+//  Copyright © 2017年 jackie@youzan. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "WHCServieRouterProtocol.h"
+
+#define WSRegister(service_protocol) [WHCServieRouter registerService:@protocol(service_protocol) withModule:self.class];
+#define WSModule(service_protocol) ((id<service_protocol>)[WHCServieRouter moduleByService:@protocol(service_protocol)])
+#define WSStr(fmt, ...) [NSString stringWithFormat:fmt, ##__VA_ARGS__]
+
+typedef NS_ENUM(NSInteger, WHCServieRouterExceptionCode)
+{
+    WSExceptionDefaultCode = -20001,
+    WSExceptionUrlHandlerNotFound = -20002,
+    WSExceptionModuleNotFoundException = -20003,
+    WSExceptionAPINotFoundException = -20004,
+    WSExceptionFailedToRegisterModule = -20005,
+    WSExceptionFailedToSetupModule = -20006,
+    WSExceptionFailedToFindModuleByService = -20007,
+
+};
+// BifrostException exception name
+extern NSExceptionName _Nonnull WHCServieRouterExceptionName;
+// Bifrost Exception userInfo keys
+extern NSString *const _Nonnull kWHCServieRouterExceptionCode;
+extern NSString *const _Nonnull kWHCServieRouterExceptionURLStr;
+extern NSString *const _Nonnull kWHCServieRouterExceptionURLParams;
+extern NSString *const _Nonnull kWHCServieRouterExceptionServiceProtocolStr;
+extern NSString *const _Nonnull kWHCServieRouterExceptionModuleClassStr;
+extern NSString *const _Nonnull kWHCServieRouterExceptionAPIStr;
+extern NSString *const _Nonnull kWHCServieRouterExceptionAPIArguments;
+
+@interface NSException (WHCServieRouter)
+- (WHCServieRouterExceptionCode)bf_exceptionCode;
+@end
+
+/**
+ The handler for exceptions, like url not found, api not support, ...
+
+ @param exception exceptions when handling route URLs or module APIs
+ @return The substitute return object
+ */
+typedef _Nullable id (^WHCServieRouterExceptionHandler)(NSException * _Nonnull exception);
+
+@interface WHCServieRouter : NSObject
+
+/**
+ Method to set exception handler
+
+ @param handler the handler block
+ */
++ (void)setExceptionHandler:(WHCServieRouterExceptionHandler _Nullable )handler;
+
++ (WHCServieRouterExceptionHandler _Nullable )getExceptionHandler;
+
+/**
+ Method to register the module srevice with module class.
+ Each Module do the registeration before app launch event, like in the +load method.
+
+ @param serviceProtocol the protocol for the module's service
+ @param moduleClass The class of the module
+ */
++ (void)registerService:(Protocol*_Nonnull)serviceProtocol
+             withModule:(Class<WHCServieRouterModuleProtocol> _Nonnull)moduleClass;
+
+/**
+ Method to unregister service
+
+ @param serviceProtocol the protocol for the module's service
+ */
++ (void)unregisterService:(Protocol*_Nonnull)serviceProtocol;
+
+/**
+ Method to setup all registered modules.
+ It's recommended to invoke this method in AppDelegate's willFinishLaunchingWithOptions method.
+ */
++ (void)setupAllModules;
+
+/**
+ Get module instance by service protocol. 
+ It's recomended to use macro WSModule for convenient
+
+ @param serviceProtocol the service protocol used to register the module
+ @return module instance
+ */
++ (id<WHCServieRouterModuleProtocol> _Nullable)moduleByService:(Protocol*_Nonnull)serviceProtocol;
+
+//+ (NSArray<Protocol*>*_Nonnull)allRegisteredServices;
+//
+
+/**
+ Method to get all registered module classes, sorted by module priority.
+
+ @return module class array, not module instances
+ */
++ (NSArray<Class<WHCServieRouterModuleProtocol>>*_Nonnull)allRegisteredModules;
+
+/**
+ Method to enumarate all modules for methods in UIApplicationDelegate.
+ 
+ @param selector app delegate selector
+ @param arguments argument array
+ @return the return value of the method implementation in those modules
+ */
++ (BOOL)checkAllModulesWithSelector:(nonnull SEL)selector
+                          arguments:(nullable NSArray*)arguments;
+
+@end

+ 361 - 0
WHCServieRouter/Classes/WHCServiceRouter/WHCServieRouter.m

@@ -0,0 +1,361 @@
+//
+//  WHCServieRouter.m
+//  WHCServieRouter
+//
+//  Created by yangke on 2017/9/15.
+//  Copyright © 2017年 jackie@youzan. All rights reserved.
+//
+
+#import "WHCServieRouter.h"
+#import <objc/message.h>
+#import <objc/runtime.h>
+
+#define WSLog(msg) NSLog(@"[WHCServieRouter] %@", (msg))
+#define WSInstance [WHCServieRouter sharedInstance]
+
+NSExceptionName WHCServieRouterExceptionName = @"WHCServieRouterExceptionName";
+NSString * const kWHCServieRouterExceptionCode = @"kWHCServieRouterExceptionCode";
+NSString * const kWHCServieRouterExceptionURLStr = @"kWHCServieRouterExceptionURLStr";
+NSString * const kWHCServieRouterExceptionURLParams = @"kWHCServieRouterExceptionURLParams";
+NSString * const kWHCServieRouterExceptionServiceProtocolStr = @"kWHCServieRouterExceptionServiceProtocolStr";
+NSString * const kWHCServieRouterExceptionModuleClassStr = @"kWHCServieRouterExceptionModuleClassStr";
+NSString * const kWHCServieRouterExceptionAPIStr = @"kWHCServieRouterExceptionAPIStr";
+NSString * const kWHCServieRouterExceptionAPIArguments = @"kWHCServieRouterExceptionAPIArguments";
+
+@implementation NSException (WHCServieRouter)
+- (WHCServieRouterExceptionCode)bf_exceptionCode {
+    return [self.userInfo[kWHCServieRouterExceptionCode] integerValue];
+}
+@end
+
+@interface NSObject (WHCServieRouter)
+- (void)bf_doesNotRecognizeSelector:(SEL)aSelector;
+@end
+
+@interface WHCServieRouter() {
+    
+}
+@property (nonatomic, copy) WHCServieRouterExceptionHandler _Nullable exceptionHandler;
+@property (nonatomic, strong) NSMutableDictionary *moduleDict; // <moduleName, moduleClass>
+@property (nonatomic, strong) NSMutableDictionary *moduleInvokeDict;
++ (instancetype _Nonnull )sharedInstance;
+@end
+
+@implementation WHCServieRouter
+
++ (instancetype _Nonnull )sharedInstance
+{
+    static WHCServieRouter *instance = nil;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        instance = [[self alloc] init];
+        instance.moduleDict = [NSMutableDictionary dictionary];
+        instance.moduleInvokeDict = [NSMutableDictionary dictionary];
+    });
+    return instance;
+}
+
++ (void)setExceptionHandler:(WHCServieRouterExceptionHandler _Nullable )handler {
+    WSInstance.exceptionHandler = handler;
+}
+
++ (WHCServieRouterExceptionHandler _Nullable )getExceptionHandler {
+    return WSInstance.exceptionHandler;
+}
+
++ (void)registerService:(Protocol*_Nonnull)serviceProtocol
+             withModule:(Class<WHCServieRouterModuleProtocol> _Nonnull)moduleClass {
+    NSString *protocolStr = NSStringFromProtocol(serviceProtocol);
+    NSString *moduleStr = NSStringFromClass(moduleClass);
+    Class class = moduleClass; // to avoid warning
+    NSString *exReason = nil;
+    if (protocolStr.length == 0) {
+        exReason =  WSStr(@"Needs a valid protocol for module %@", moduleStr);
+    } else if (moduleStr.length == 0) {
+        exReason =  WSStr(@"Needs a valid module for protocol %@", protocolStr);
+    } else if (![class conformsToProtocol:serviceProtocol]) {
+        exReason =  WSStr(@"Module %@ should confirm to protocol %@", moduleStr, protocolStr);
+    } else {
+        [self hackUnrecognizedSelecotorExceptionForModule:moduleClass];
+        [WSInstance.moduleDict setObject:moduleClass forKey:protocolStr];
+    }
+    if (exReason.length > 0)  {
+        NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
+        [userInfo setValue:@(WSExceptionFailedToRegisterModule) forKey:kWHCServieRouterExceptionCode];
+        [userInfo setValue:protocolStr forKey:kWHCServieRouterExceptionServiceProtocolStr];
+        NSException *exception = [[NSException alloc] initWithName:WHCServieRouterExceptionName
+                                                            reason:exReason
+                                                          userInfo:userInfo];
+        WHCServieRouterExceptionHandler handler = [self getExceptionHandler];
+        if (handler) {
+            handler(exception);
+        }
+        WSLog(exReason);
+    }
+}
+
++ (void)unregisterService:(Protocol*_Nonnull)serviceProtocol {
+    NSString *str = NSStringFromProtocol(serviceProtocol);
+    if (str.length > 0) {
+        [WSInstance.moduleDict removeObjectForKey:str];
+    } else {
+        WSLog(@"Failed to unregister service, protocol is empty");
+    }
+}
+
++ (NSArray<Class<WHCServieRouterModuleProtocol>>*_Nonnull)allRegisteredModules {
+    NSArray *modules = WSInstance.moduleDict.allValues;
+    NSArray *sortedModules = [modules sortedArrayUsingComparator:^NSComparisonResult(Class class1, Class class2) {
+        NSUInteger priority1 = WHCServieRouterModuleDefaultPriority;
+        NSUInteger priority2 = WHCServieRouterModuleDefaultPriority;
+        if ([class1 respondsToSelector:@selector(priority)]) {
+            priority1 = [class1 priority];
+        }
+        if ([class2 respondsToSelector:@selector(priority)]) {
+            priority2 = [class2 priority];
+        }
+        if(priority1 == priority2) {
+            return NSOrderedSame;
+        } else if(priority1 < priority2) {
+            return NSOrderedDescending;
+        } else {
+            return NSOrderedAscending;
+        }
+    }];
+    return sortedModules;
+}
+
++ (void)setupAllModules {
+    NSArray *modules = [self allRegisteredModules];
+    for (Class<WHCServieRouterModuleProtocol> moduleClass in modules) {
+        @try {
+            BOOL setupSync = NO;
+            if ([moduleClass respondsToSelector:@selector(setupModuleSynchronously)]) {
+                setupSync = [moduleClass setupModuleSynchronously];
+            }
+            if (setupSync) {
+                [[moduleClass sharedInstance] setup];
+            } else {
+                dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+                    [[moduleClass sharedInstance] setup];
+                });
+            }
+        } @catch (NSException *exception) {
+            NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithDictionary:exception.userInfo];
+            [userInfo setValue:@(WSExceptionFailedToSetupModule) forKey:kWHCServieRouterExceptionCode];
+            [userInfo setValue:NSStringFromClass(moduleClass) forKey:kWHCServieRouterExceptionModuleClassStr];
+            NSException *ex = [[NSException alloc] initWithName:exception.name
+                                                         reason:exception.reason
+                                                       userInfo:userInfo];
+            WHCServieRouterExceptionHandler handler = [self getExceptionHandler];
+            if (handler) {
+                 handler(ex);
+            }
+            WSLog(exception.reason);
+        }
+    }
+}
+
++ (id<WHCServieRouterModuleProtocol> _Nullable)moduleByService:(Protocol*_Nonnull)serviceProtocol {
+    NSString *protocolStr = NSStringFromProtocol(serviceProtocol);
+    NSString *exReason = nil;
+    NSException *exception = nil;
+    if (protocolStr.length == 0) {
+        exReason = WSStr(@"Invalid service protocol");
+    } else {
+        Class class = WSInstance.moduleDict[protocolStr];
+        NSString *classStr = NSStringFromClass(class);
+        if (!class) {
+            exReason = WSStr(@"Failed to find module by protocol %@", protocolStr);
+        } else if (![class conformsToProtocol:@protocol(WHCServieRouterModuleProtocol)]) {
+            exReason = WSStr(@"Found %@ by protocol %@, but the module doesn't confirm to protocol WHCServieRouterModuleProtocol",
+                            classStr, protocolStr);
+        } else {
+            @try {
+                id instance = [class sharedInstance];
+                return instance;
+            } @catch (NSException *ex) {
+                exception = ex;
+            }
+        }
+    }
+    if (exReason.length > 0) {
+        NSExceptionName name = WHCServieRouterExceptionName;
+        NSMutableDictionary *userInfo = nil;
+        if (exception != nil) {
+            userInfo = [NSMutableDictionary dictionaryWithDictionary:exception.userInfo];
+            name = exception.name;
+        } else {
+            userInfo = [NSMutableDictionary dictionary];
+        }
+        [userInfo setValue:@(WSExceptionFailedToFindModuleByService) forKey:kWHCServieRouterExceptionCode];
+        [userInfo setValue:NSStringFromProtocol(serviceProtocol) forKey:kWHCServieRouterExceptionServiceProtocolStr];
+        NSException *ex = [[NSException alloc] initWithName:name
+                                                            reason:exReason
+                                                          userInfo:userInfo];
+        WHCServieRouterExceptionHandler handler = [self getExceptionHandler];
+        if (handler) {
+            handler(ex);
+        }
+        WSLog(exReason);
+        return nil;
+    }
+    
+}
+
++ (BOOL)checkAllModulesWithSelector:(SEL)selector arguments:(NSArray*)arguments {
+    BOOL result = NO;
+    NSArray *modules = [self allRegisteredModules];
+    for (Class<WHCServieRouterModuleProtocol> class in modules) {
+        id<WHCServieRouterModuleProtocol> moduleItem = [class sharedInstance];
+        if ([moduleItem respondsToSelector:selector]) {
+            
+            __block BOOL shouldInvoke = YES;
+            if (![WSInstance.moduleInvokeDict objectForKey:NSStringFromClass([moduleItem class])]) {
+                // 如果 modules 里面有 moduleItem 的子类,不 invoke target
+                [modules enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+                    if ([NSStringFromClass([obj superclass]) isEqualToString:NSStringFromClass([moduleItem class])]) {
+                        shouldInvoke = NO;
+                        *stop = YES;
+                    }
+                }];
+            }
+            
+            if (shouldInvoke) {
+                if (![WSInstance.moduleInvokeDict objectForKey:NSStringFromClass([moduleItem class])]) { //cache it
+                    [WSInstance.moduleInvokeDict setObject:moduleItem forKey:NSStringFromClass([moduleItem class])];
+                }
+                
+                BOOL ret = NO;
+                [self invokeTarget:moduleItem action:selector arguments:arguments returnValue:&ret];
+                if (!result) {
+                    result = ret;
+                }
+            }
+        }
+    }
+    return result;
+}
+
+
++ (BOOL)invokeTarget:(id)target
+              action:(_Nonnull SEL)selector
+           arguments:(NSArray* _Nullable )arguments
+         returnValue:(void* _Nullable)result; {
+    if (target && [target respondsToSelector:selector]) {
+        NSMethodSignature *sig = [target methodSignatureForSelector:selector];
+        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig];
+        [invocation setTarget:target];
+        [invocation setSelector:selector];
+        for (NSUInteger i = 0; i<[arguments count]; i++) {
+            NSUInteger argIndex = i+2;
+            id argument = arguments[i];
+            if ([argument isKindOfClass:NSNumber.class]) {
+                //convert number object to basic num type if needs
+                BOOL shouldContinue = NO;
+                NSNumber *num = (NSNumber*)argument;
+                const char *type = [sig getArgumentTypeAtIndex:argIndex];
+                if (strcmp(type, @encode(BOOL)) == 0) {
+                    BOOL rawNum = [num boolValue];
+                    [invocation setArgument:&rawNum atIndex:argIndex];
+                    shouldContinue = YES;
+                } else if (strcmp(type, @encode(int)) == 0
+                           || strcmp(type, @encode(short)) == 0
+                           || strcmp(type, @encode(long)) == 0) {
+                    NSInteger rawNum = [num integerValue];
+                    [invocation setArgument:&rawNum atIndex:argIndex];
+                    shouldContinue = YES;
+                } else if(strcmp(type, @encode(long long)) == 0) {
+                    long long rawNum = [num longLongValue];
+                    [invocation setArgument:&rawNum atIndex:argIndex];
+                    shouldContinue = YES;
+                } else if (strcmp(type, @encode(unsigned int)) == 0
+                           || strcmp(type, @encode(unsigned short)) == 0
+                           || strcmp(type, @encode(unsigned long)) == 0) {
+                    NSUInteger rawNum = [num unsignedIntegerValue];
+                    [invocation setArgument:&rawNum atIndex:argIndex];
+                    shouldContinue = YES;
+                } else if(strcmp(type, @encode(unsigned long long)) == 0) {
+                    unsigned long long rawNum = [num unsignedLongLongValue];
+                    [invocation setArgument:&rawNum atIndex:argIndex];
+                    shouldContinue = YES;
+                } else if (strcmp(type, @encode(float)) == 0) {
+                    float rawNum = [num floatValue];
+                    [invocation setArgument:&rawNum atIndex:argIndex];
+                    shouldContinue = YES;
+                } else if (strcmp(type, @encode(double)) == 0) { // double
+                    double rawNum = [num doubleValue];
+                    [invocation setArgument:&rawNum atIndex:argIndex];
+                    shouldContinue = YES;
+                }
+                if (shouldContinue) {
+                    continue;
+                }
+            }
+            if ([argument isKindOfClass:[NSNull class]]) {
+                argument = nil;
+            }
+            [invocation setArgument:&argument atIndex:argIndex];
+        }
+        [invocation invoke];
+        NSString *methodReturnType = [NSString stringWithUTF8String:sig.methodReturnType];
+        if (result && ![methodReturnType isEqualToString:@"v"]) { //if return type is not void
+            if([methodReturnType isEqualToString:@"@"]) { //if it's kind of NSObject
+                CFTypeRef cfResult = nil;
+                [invocation getReturnValue:&cfResult]; //this operation won't retain the result
+                if (cfResult) {
+                    CFRetain(cfResult); //we need to retain it manually
+                    *(void**)result = (__bridge_retained void *)((__bridge_transfer id)cfResult);
+                }
+            } else {
+                [invocation getReturnValue:result];
+            }
+        }
+        return YES;
+    }
+    return NO;
+}
+
++ (void)hackUnrecognizedSelecotorExceptionForModule:(Class)class {
+    SEL originSEL = @selector(doesNotRecognizeSelector:);
+    SEL newSEL = @selector(bf_doesNotRecognizeSelector:);
+    [self swizzleOrginSEL:originSEL withNewSEL:newSEL inClass:class];
+}
+
++ (void)swizzleOrginSEL:(SEL)originSEL withNewSEL:(SEL)newSEL inClass:(Class)class {
+    Method origMethod = class_getInstanceMethod(class, originSEL);
+    Method overrideMethod = class_getInstanceMethod(class, newSEL);
+    if (class_addMethod(class, originSEL, method_getImplementation(overrideMethod),
+                        method_getTypeEncoding(overrideMethod))) {
+        class_replaceMethod(class, newSEL, method_getImplementation(origMethod),
+                            method_getTypeEncoding(origMethod));
+    } else {
+        method_exchangeImplementations(origMethod, overrideMethod);
+    }
+}
+
+@end
+
+@implementation NSObject (WHCServieRouter)
+
+- (void)bf_doesNotRecognizeSelector:(SEL)aSelector {
+    @try {
+        [self bf_doesNotRecognizeSelector:aSelector];
+    } @catch (NSException *ex) {
+        NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
+        [userInfo setValue:@(WSExceptionAPINotFoundException) forKey:kWHCServieRouterExceptionCode];
+        NSException *exception = [[NSException alloc] initWithName:ex.name
+                                                            reason:ex.reason
+                                                          userInfo:userInfo];
+        if (WSInstance.exceptionHandler) {
+            WSInstance.exceptionHandler(exception);
+        } else {
+#ifdef DEBUG
+            @throw exception;
+#endif
+        }
+    } @finally {
+    }
+}
+
+@end

+ 16 - 0
WHCServieRouter/Classes/WHCServiceRouter/WHCServieRouterHeader.h

@@ -0,0 +1,16 @@
+//
+//  BifrostHeader.h
+//  Bifrost
+//
+//  Created by yangke on 2017/9/15.
+//  Copyright © 2017年 jackie@youzan. All rights reserved.
+//
+
+#ifndef WHCServieRouterHeader_h
+#define WHCServieRouterHeader_h
+
+#import "WHCServieRouter.h"
+#import "WHCServieRouter+Router.h"
+#import "WHCServieRouterProtocol.h"
+
+#endif /* WHCServieRouterHeader_h */

+ 58 - 0
WHCServieRouter/Classes/WHCServiceRouter/WHCServieRouterProtocol.h

@@ -0,0 +1,58 @@
+//
+//  BifrostProtocol.h
+//  Bifrost
+//
+//  Created by yangke on 2017/9/15.
+//  Copyright © 2017年 jackie@youzan. All rights reserved.
+//
+
+#ifndef WHCServieRouterModuleProtocol_h
+#define WHCServieRouterModuleProtocol_h
+
+#import <UIKit/UIKit.h>
+
+#define WHCServieRouterModuleDefaultPriority 100
+
+@protocol WHCServieRouterModuleProtocol <UIApplicationDelegate, NSObject>
+
+@required
+/**
+ Each module should be a singleton class
+
+ @return module instance
+ */
++ (instancetype)sharedInstance;
+
+/**
+ module setup method, will be invoked by module manager when app is launched or module is loaded.
+ It's invoked in main thread synchronourly.
+ It's strong recommended to run its content in background thread asynchronously to save launch time.
+ */
+- (void)setup;
+
+@optional
+
+/**
+ The priority of the module to be setup. 0 is the lowest priority;
+ If not provided, the default priority is BifrostModuleDefaultPriority;
+
+ @return the priority
+ */
++ (NSUInteger)priority;
+
+
+/**
+ Whether to setup the module synchronously in main thread.
+ If it's not implemeted, default value is NO, module will be sutup asyhchronously in backgorud thread.
+
+ @return whether synchronously
+ */
++ (BOOL)setupModuleSynchronously;
+
+@end
+
+//@protocol BifrostServcieProtocol <NSObject>
+//
+//@end
+
+#endif /* BifrostModuleProtocol_h */