From 74e43d316eaccb429c93a508bfad8a807260a8ea Mon Sep 17 00:00:00 2001 From: Rake Yang Date: Tue, 31 Dec 2019 23:34:41 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B7=AF=E7=94=B1=E8=A1=A8=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E7=94=9F=E6=88=90=E5=A4=B4=E6=96=87=E4=BB=B6=EF=BC=8C=E6=96=B9?= =?UTF-8?q?=E4=BE=BF=E4=BB=A3=E7=A0=81=E4=B8=AD=E5=BC=95=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Example/Peregrine.xcodeproj/project.pbxproj | 26 ++++++-- Example/Peregrine/FPFileBox.swift | 15 +++++ Example/Peregrine/PeregrineActionTest3.h | 2 +- .../Peregrine_Example-Bridging-Header.h | 4 ++ Example/Tests/Tests.m | 4 +- Example/Tests/routers.json | 47 -------------- Peregrine.podspec | 2 +- Peregrine/PGGenerator.rb | 63 ++++++++++++++----- Peregrine/PGRouter-generate.h | 14 +++++ Peregrine/PGRouterManager.h | 1 + 10 files changed, 106 insertions(+), 72 deletions(-) create mode 100644 Example/Peregrine/FPFileBox.swift create mode 100644 Example/Peregrine/Peregrine_Example-Bridging-Header.h delete mode 100644 Example/Tests/routers.json create mode 100644 Peregrine/PGRouter-generate.h diff --git a/Example/Peregrine.xcodeproj/project.pbxproj b/Example/Peregrine.xcodeproj/project.pbxproj index 374140f..125954d 100644 --- a/Example/Peregrine.xcodeproj/project.pbxproj +++ b/Example/Peregrine.xcodeproj/project.pbxproj @@ -10,6 +10,7 @@ 18B0C51432699A6EAA0AA8D5 /* Pods_Peregrine_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 235C20B6298A280A37EEFAE1 /* Pods_Peregrine_Tests.framework */; }; 19FD2F3C18A45BD4E25E58FD /* Pods_Peregrine_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25B17BE52729276AC7C2099D /* Pods_Peregrine_Example.framework */; }; 240E7B4C228327C800B5579E /* Peregrine-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 240E7B4B228327C800B5579E /* Peregrine-Info.plist */; }; + 2432139323BB8A4500DF8407 /* FPFileBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2432139223BB8A4500DF8407 /* FPFileBox.swift */; }; 243B492423A3CCA7004D3E71 /* FPInsertEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 243B492323A3CCA7004D3E71 /* FPInsertEvent.m */; }; 2440D8402389304E0031BC26 /* FPModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 2440D83F2389304E0031BC26 /* FPModel.m */; }; 24F05A4C22DB42A700B25CB8 /* PeregrineActionTest1.m in Sources */ = {isa = PBXBuildFile; fileRef = 24F05A4822DB42A700B25CB8 /* PeregrineActionTest1.m */; }; @@ -30,7 +31,6 @@ 71719F9F1E33DC2100824A3D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 71719F9D1E33DC2100824A3D /* LaunchScreen.storyboard */; }; 873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */; }; C91B8E7723B1B6E000875343 /* PeregrineActionTest3.m in Sources */ = {isa = PBXBuildFile; fileRef = C91B8E7523B1B6E000875343 /* PeregrineActionTest3.m */; }; - CE17E91E236FC59800F259C1 /* routers.json in Resources */ = {isa = PBXBuildFile; fileRef = CE17E91C236FC59300F259C1 /* routers.json */; }; CE3FD9DE23668E5400F8803D /* FPWebViewViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CE3FD9DC23668E5400F8803D /* FPWebViewViewController.m */; }; CE3FD9E12366957700F8803D /* webview.html in Resources */ = {isa = PBXBuildFile; fileRef = CE3FD9E02366957700F8803D /* webview.html */; }; /* End PBXBuildFile section */ @@ -48,6 +48,8 @@ /* Begin PBXFileReference section */ 235C20B6298A280A37EEFAE1 /* Pods_Peregrine_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Peregrine_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 240E7B4B228327C800B5579E /* Peregrine-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Peregrine-Info.plist"; sourceTree = ""; }; + 2432139123BB8A4400DF8407 /* Peregrine_Example-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Peregrine_Example-Bridging-Header.h"; sourceTree = ""; }; + 2432139223BB8A4500DF8407 /* FPFileBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FPFileBox.swift; sourceTree = ""; }; 243B492223A3CCA7004D3E71 /* FPInsertEvent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FPInsertEvent.h; sourceTree = ""; }; 243B492323A3CCA7004D3E71 /* FPInsertEvent.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FPInsertEvent.m; sourceTree = ""; }; 2440D83E2389304E0031BC26 /* FPModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FPModel.h; sourceTree = ""; }; @@ -86,7 +88,6 @@ C91B8E7523B1B6E000875343 /* PeregrineActionTest3.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PeregrineActionTest3.m; sourceTree = ""; }; C91B8E7623B1B6E000875343 /* PeregrineActionTest3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PeregrineActionTest3.h; sourceTree = ""; }; CB6CE61360BBC12792B872B7 /* Pods-Peregrine_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Peregrine_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Peregrine_Tests/Pods-Peregrine_Tests.debug.xcconfig"; sourceTree = ""; }; - CE17E91C236FC59300F259C1 /* routers.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = routers.json; sourceTree = ""; }; CE3FD9DB23668E5400F8803D /* FPWebViewViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FPWebViewViewController.h; sourceTree = ""; }; CE3FD9DC23668E5400F8803D /* FPWebViewViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FPWebViewViewController.m; sourceTree = ""; }; CE3FD9E02366957700F8803D /* webview.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = webview.html; sourceTree = ""; }; @@ -177,6 +178,8 @@ C91B8E7623B1B6E000875343 /* PeregrineActionTest3.h */, C91B8E7523B1B6E000875343 /* PeregrineActionTest3.m */, 6003F594195388D20070C39A /* Supporting Files */, + 2432139223BB8A4500DF8407 /* FPFileBox.swift */, + 2432139123BB8A4400DF8407 /* Peregrine_Example-Bridging-Header.h */, ); name = "Example for Peregrine"; path = Peregrine; @@ -197,7 +200,6 @@ 6003F5B5195388D20070C39A /* Tests */ = { isa = PBXGroup; children = ( - CE17E91C236FC59300F259C1 /* routers.json */, 6003F5BB195388D20070C39A /* Tests.m */, 6003F5B6195388D20070C39A /* Supporting Files */, ); @@ -290,6 +292,9 @@ LastUpgradeCheck = 0720; ORGANIZATIONNAME = BinaryParadise; TargetAttributes = { + 6003F589195388D20070C39A = { + LastSwiftMigration = 1010; + }; 6003F5AD195388D20070C39A = { TestTargetID = 6003F589195388D20070C39A; }; @@ -333,7 +338,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - CE17E91E236FC59800F259C1 /* routers.json in Resources */, 6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -395,7 +399,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "export LANG=en_US.UTF-8\nexport LANGUAGE=en_US.UTF-8\nexport LC_ALL=en_US.UTF-8\nruby /Users/rakeyang/Github/Peregrine/Peregrine/PGGenerator.rb 1\n"; + shellScript = "export LANG=en_US.UTF-8 export LANGUAGE=en_US.UTF-8 export LC_ALL=en_US.UTF-8 export PG_VERSION=0.6.0 \nruby /Users/bonana/Github/Peregrine/Peregrine/PGGenerator.rb\n"; }; 842D5995DC0ECC9C1951B7AE /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; @@ -453,6 +457,7 @@ 6003F59E195388D20070C39A /* FPAppDelegate.m in Sources */, 24F05A4C22DB42A700B25CB8 /* PeregrineActionTest1.m in Sources */, 6003F5A7195388D20070C39A /* FPViewController.m in Sources */, + 2432139323BB8A4500DF8407 /* FPFileBox.swift in Sources */, 2440D8402389304E0031BC26 /* FPModel.m in Sources */, CE3FD9DE23668E5400F8803D /* FPWebViewViewController.m in Sources */, 6003F59A195388D20070C39A /* main.m in Sources */, @@ -584,12 +589,17 @@ baseConfigurationReference = 4AE5344D6E912B110E4D13C3 /* Pods-Peregrine_Example.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = Peregrine/PrefixHeader.pch; INFOPLIST_FILE = "Peregrine/Peregrine-Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MODULE_NAME = ExampleApp; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Peregrine/Peregrine_Example-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; WRAPPER_EXTENSION = app; }; name = Debug; @@ -599,12 +609,16 @@ baseConfigurationReference = 7DF05A23FD0C93C0A260AD29 /* Pods-Peregrine_Example.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = Peregrine/PrefixHeader.pch; INFOPLIST_FILE = "Peregrine/Peregrine-Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MODULE_NAME = ExampleApp; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Peregrine/Peregrine_Example-Bridging-Header.h"; + SWIFT_VERSION = 4.2; WRAPPER_EXTENSION = app; }; name = Release; @@ -613,6 +627,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = CB6CE61360BBC12792B872B7 /* Pods-Peregrine_Tests.debug.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; FRAMEWORK_SEARCH_PATHS = ( "$(SDKROOT)/Developer/Library/Frameworks", @@ -637,6 +652,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 91F1F1D12A795DC44A4FC7D1 /* Pods-Peregrine_Tests.release.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; FRAMEWORK_SEARCH_PATHS = ( "$(SDKROOT)/Developer/Library/Frameworks", diff --git a/Example/Peregrine/FPFileBox.swift b/Example/Peregrine/FPFileBox.swift new file mode 100644 index 0000000..ad072f4 --- /dev/null +++ b/Example/Peregrine/FPFileBox.swift @@ -0,0 +1,15 @@ +// +// FPFileBox.swift +// Peregrine_Example +// +// Created by Rake Yang on 2019/12/31. +// Copyright © 2019年 BinaryParadise. All rights reserved. +// + +import Foundation + +@objc public class FPFileBox: NSObject { + @objc public func initWithString() { + + } +} diff --git a/Example/Peregrine/PeregrineActionTest3.h b/Example/Peregrine/PeregrineActionTest3.h index 1ad9603..b887e8c 100644 --- a/Example/Peregrine/PeregrineActionTest3.h +++ b/Example/Peregrine/PeregrineActionTest3.h @@ -10,6 +10,6 @@ @interface PeregrineActionTest3 : NSObject -PGMethod(verification1, "ap://tlbb/xlv?c=小龙女"); +PGMethod(verification1, "ap://tlbb/xxlv?c=小龙女"); @end diff --git a/Example/Peregrine/Peregrine_Example-Bridging-Header.h b/Example/Peregrine/Peregrine_Example-Bridging-Header.h new file mode 100644 index 0000000..1b2cb5d --- /dev/null +++ b/Example/Peregrine/Peregrine_Example-Bridging-Header.h @@ -0,0 +1,4 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + diff --git a/Example/Tests/Tests.m b/Example/Tests/Tests.m index 1d61e38..011d0ea 100644 --- a/Example/Tests/Tests.m +++ b/Example/Tests/Tests.m @@ -27,8 +27,8 @@ }); it(@"OpenURL", ^{ - if ([PGRouterManager dryRun:@"ap://tlbb/wyy?result=1"]) { - [PGRouterManager openURL:@"ap://tlbb/wyy?result=1" completion:^(BOOL ret, NSNumber * _Nonnull object) { + if ([PGRouterManager dryRun:ap_tlbb_wyy]) { + [PGRouterManager openURL:[ap_tlbb_wyy stringByAppendingString:@"?result=1"] completion:^(BOOL ret, NSNumber * _Nonnull object) { expect(object.boolValue).equal(YES); }]; } diff --git a/Example/Tests/routers.json b/Example/Tests/routers.json deleted file mode 100644 index 7060467..0000000 --- a/Example/Tests/routers.json +++ /dev/null @@ -1,47 +0,0 @@ -[ - { - "class" : "PeregrineActionTest2xxxx", - "selector" : "verification1:", - "url" : "ap://tlbb/xlv?c=小龙女" - }, - { - "class" : "PeregrineActionTest2", - "selector" : "multiComponent:", - "url" : "ap://tlbb/most/like/wangyuyan?t=multi" - }, - { - "class" : "PeregrineActionTest2", - "selector" : "multiComponent1:", - "url" : "ap://tlbb/most/like/wangzuxian?c=nice" - }, - { - "class" : "PeregrineActionTest2", - "selector" : "invalid:", - "url" : "invalidurl/haha" - }, - { - "class" : "PeregrineActionTest1", - "selector" : "verification1:", - "url" : "ap://tlbb/wyy?c=王语嫣1" - }, - { - "class" : "PeregrineActionTest1", - "selector" : "verification2:", - "url" : "ap://tlbb/ym?c=杨幂22" - }, - { - "class" : "PeregrineActionTest1", - "selector" : "webview:", - "url" : "ap://webview/UIWebView" - }, - { - "class" : "PeregrineActionTest1", - "selector" : "wkwebview:", - "url" : "ap://webview/WKWebView" - }, - { - "class" : "PeregrineActionTest1", - "selector" : "jscalloc:", - "url" : "ap://webview/calloc" - } -] diff --git a/Peregrine.podspec b/Peregrine.podspec index 3e75611..e5c3dbb 100644 --- a/Peregrine.podspec +++ b/Peregrine.podspec @@ -7,7 +7,7 @@ # Pod::Spec.new do |s| s.name = 'Peregrine' - s.version = '0.6.0' + s.version = '0.6.1' s.summary = 'A short description of Peregrine.' # This description is used to generate tags and improve search results. diff --git a/Peregrine/PGGenerator.rb b/Peregrine/PGGenerator.rb index 56b7b6b..2760681 100755 --- a/Peregrine/PGGenerator.rb +++ b/Peregrine/PGGenerator.rb @@ -1,21 +1,26 @@ +#!/usr/bin/ruby -W0 + require 'xcodeproj' require 'yaml' require 'json' +require 'uri' BUILD_PHASE_NAME_FETCH_ENV = '[Peregrine] Generator Routing Table' CLANG_TOOL_PATH = '/usr/local/bin/clang-peregrine' +CLANG_MODE = 'Clang' class PGGenerator attr_accessor:routers + attr_accessor:version def initialize(args) if args[0].eql?('install') return end - if args[0].eql?('1') + if ENV["GENERATE_MODE"].eql?(CLANG_MODE) + buildWithClang(args) + else @routers = Array.new buildWithRegularExpression(args) - else - buildWithClang(args) end end @@ -72,9 +77,10 @@ def buildWithClang(args) # 通过正则表达式匹配生成路由表 def buildWithRegularExpression(args) srcroot = ENV['SRCROOT'] - # srcroot = "/Users/rakeyang/Github/Peregrine/" collectPath(srcroot) + + # 生成路由表到目标App中 destination_file = ENV["BUILT_PRODUCTS_DIR"] if !ENV["PODS_CONFIGURATION_BUILD_DIR"].nil? destination_file = ENV["PODS_CONFIGURATION_BUILD_DIR"] @@ -92,6 +98,32 @@ def buildWithRegularExpression(args) router_json_file = File.new("#{destination_file}/routers.json", 'w+') router_json_file.write(JSON.pretty_generate(@routers)) router_json_file.close + + # 更新路由的定义头文件 + # `rm PGRouter-generate.h` + generate_file = File.new("#{File.dirname(__FILE__)}/PGRouter-generate.h", 'w+') + generate_file.write("// +// PGRouter-generate.h +// Peregrine +// +// Created by Rake Yang on 2019/12/31. +// Copyright © 2019 BinaryParadise. All rights reserved. + +/** + Generated automatic by Peregrine version 0.6.0 (#{Time.now}) + Don't modify manual ⚠️ +*/ + +typedef NSString * PGRouterURLKey; + +") + @routers.each {|item| ( + uri = URI(URI::encode(item['url'])) + + generate_file.write("static PGRouterURLKey const #{uri.scheme}_#{uri.host}#{uri.path.split('/').join('_')} = @\"#{uri.scheme}://#{uri.host}#{uri.path}\";\n") + )} + generate_file.close + end # 收集所有.h中声明的路由 @@ -122,7 +154,6 @@ def mapRouter(file_path) file_content.scan(/@interface\s+(\w+)\s*[\s\S]+?\n([\s\S]+?)@end/) do |match| class_name = match[0] class_content = match[1] - # puts match class_content.scan(/PGMethod\((\b\w+\b),\s*\"([\s\S]+?)\"\);/) do |match1| @routers.push({ 'class' => class_name, 'selector' => match1[0] + ':', 'url' => match1[1] }) end @@ -132,7 +163,11 @@ def mapRouter(file_path) # expression=true表示使用正则匹配模式 def self.configure_project(installer, expression=true, condition=nil) path = installer.sandbox.development_pods['Peregrine'] - @dev_path = path ? path.dirname.to_s : nil + file_content = File.read(installer.sandbox.manifest.defined_in_file) + file_content.scan(/(Peregrine\s\()(\d.+)(\))/) do |match| + @version = match[1] + end + @ruby_path = path ? path.dirname.to_s : "${PODS_ROOT}/Peregrine" installer.analysis_result.targets.each do |target| if target.user_project_path.exist? && target.user_target_uuids.any? @@ -147,7 +182,7 @@ def self.configure_project(installer, expression=true, condition=nil) installer.pod_targets.each do |target| if !condition.nil? && condition.call(target.pod_name) project = Xcodeproj::Project.open(installer.sandbox.root.to_s+"/"+target.pod_name+".xcodeproj") - self.add_shell_script(project.targets, project) + self.add_shell_script(project.targets, project, expression) end end @@ -156,8 +191,6 @@ def self.configure_project(installer, expression=true, condition=nil) def self.add_shell_script(project_targets, project, expression=true) install_targets = project_targets.select { |target| ['com.apple.product-type.application','com.apple.product-type.framework'].include?(target.product_type) } install_targets.each do |project_target| - rubypath = (@dev_path == nil ? "${PODS_ROOT}/Peregrine" : @dev_path) + "/Peregrine/PGGenerator.rb" - phase = self.fetch_exist_phase(BUILD_PHASE_NAME_FETCH_ENV, project_target) if phase.nil? phase = project_target.new_shell_script_build_phase(BUILD_PHASE_NAME_FETCH_ENV) @@ -167,16 +200,14 @@ def self.add_shell_script(project_targets, project, expression=true) end end - expr = 0 - if expression - expr = 1 + mode = nil + if !expression + mode = "export GENERATE_MODE=#{CLANG_MODE}" end phase.run_only_for_deployment_postprocessing = "0" - phase.shell_script = "export LANG=en_US.UTF-8 -export LANGUAGE=en_US.UTF-8 -export LC_ALL=en_US.UTF-8 -ruby #{rubypath} #{expr}" + phase.shell_script = "export LANG=en_US.UTF-8 export LANGUAGE=en_US.UTF-8 export LC_ALL=en_US.UTF-8 export PG_VERSION=#{@version} #{mode} +ruby #{@ruby_path}/Peregrine/PGGenerator.rb" project.save() end diff --git a/Peregrine/PGRouter-generate.h b/Peregrine/PGRouter-generate.h new file mode 100644 index 0000000..328fc2e --- /dev/null +++ b/Peregrine/PGRouter-generate.h @@ -0,0 +1,14 @@ +// +// PGRouter-generate.h +// Peregrine +// +// Created by Rake Yang on 2019/12/31. +// Copyright © 2019 BinaryParadise. All rights reserved. + +/** + Generated automatic by Peregrine version 0.6.0 (2019-12-31 23:33:30 +0800) + Don't modify manual ⚠️ +*/ + +typedef NSString * PGRouterURLKey; + diff --git a/Peregrine/PGRouterManager.h b/Peregrine/PGRouterManager.h index 225e4ec..06c54cb 100644 --- a/Peregrine/PGRouterManager.h +++ b/Peregrine/PGRouterManager.h @@ -8,6 +8,7 @@ #import #import "PGRouterNode.h" +#import "PGRouter-generate.h" #define PGTarget(_router) __attribute__((pe_routed(_router))) #define PGMethod(_name, _url) \