From 8c2c55e7b86c6667af1f6852d5024f90a6ed33e1 Mon Sep 17 00:00:00 2001 From: "pengfei.zhou" Date: Wed, 14 Aug 2019 16:03:37 +0800 Subject: [PATCH] iOS implement local server --- iOS/Doric.podspec | 1 + iOS/Example/Example/ViewController.m | 5 ++ iOS/Example/Podfile.lock | 8 +- iOS/Pod/Classes/Dev/DoricLocalServer.h | 16 ++++ iOS/Pod/Classes/Dev/DoricLocalServer.m | 115 +++++++++++++++++++++++++ 5 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 iOS/Pod/Classes/Dev/DoricLocalServer.h create mode 100644 iOS/Pod/Classes/Dev/DoricLocalServer.m diff --git a/iOS/Doric.podspec b/iOS/Doric.podspec index f682107e..80347944 100644 --- a/iOS/Doric.podspec +++ b/iOS/Doric.podspec @@ -41,4 +41,5 @@ TODO: Add long description of the pod here. # s.dependency 'AFNetworking', '~> 2.3' s.dependency 'SDWebImage', '~> 5.0' s.dependency 'SocketRocket', '~> 0.5.1' + s.dependency 'GCDWebServer', '~> 3.0' end diff --git a/iOS/Example/Example/ViewController.m b/iOS/Example/Example/ViewController.m index 18788615..dabf77b3 100644 --- a/iOS/Example/Example/ViewController.m +++ b/iOS/Example/Example/ViewController.m @@ -12,9 +12,11 @@ #import "DoricContext.h" #import "DoricNativePlugin.h" #import "DoricRootNode.h" +#import "DoricLocalServer.h" @interface ViewController () @property (nonatomic,strong) DoricContext *doricContext; +@property (nonatomic,strong) DoricLocalServer *localServer; @end @implementation ViewController @@ -28,6 +30,9 @@ - (void)viewDidLoad { self.doricContext.rootNode.view = self.view; [self.doricContext initContextWithWidth:self.view.width height:self.view.height]; [self.doricContext.driver connectDevKit:@"ws://192.168.11.38:7777"]; + self.localServer = [[DoricLocalServer alloc] init]; + [self.localServer startWithPort:8910]; + NSLog(@"00112233"); } diff --git a/iOS/Example/Podfile.lock b/iOS/Example/Podfile.lock index ff01a6f7..9c0eaa93 100644 --- a/iOS/Example/Podfile.lock +++ b/iOS/Example/Podfile.lock @@ -1,7 +1,11 @@ PODS: - Doric (0.1.0): + - GCDWebServer (~> 3.0) - SDWebImage (~> 5.0) - SocketRocket (~> 0.5.1) + - GCDWebServer (3.5.2): + - GCDWebServer/Core (= 3.5.2) + - GCDWebServer/Core (3.5.2) - SDWebImage (5.0.6): - SDWebImage/Core (= 5.0.6) - SDWebImage/Core (5.0.6) @@ -12,6 +16,7 @@ DEPENDENCIES: SPEC REPOS: https://github.com/cocoapods/specs.git: + - GCDWebServer - SDWebImage - SocketRocket @@ -20,7 +25,8 @@ EXTERNAL SOURCES: :path: "../" SPEC CHECKSUMS: - Doric: fffcb912bda6820db1165fc7919dce47f9aa0463 + Doric: 1dae6e8a19a32a27af975f787509cc0658dde095 + GCDWebServer: ead88cd14596dd4eae4f5830b8877c87c8728990 SDWebImage: 920f1a2ff1ca8296ad34f6e0510a1ef1d70ac965 SocketRocket: d57c7159b83c3c6655745cd15302aa24b6bae531 diff --git a/iOS/Pod/Classes/Dev/DoricLocalServer.h b/iOS/Pod/Classes/Dev/DoricLocalServer.h new file mode 100644 index 00000000..0fb4b5d3 --- /dev/null +++ b/iOS/Pod/Classes/Dev/DoricLocalServer.h @@ -0,0 +1,16 @@ +// +// DoricLocalServer.h +// Doric +// +// Created by pengfei.zhou on 2019/8/14. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface DoricLocalServer : NSObject +- (void)startWithPort:(NSUInteger)port; +@end + +NS_ASSUME_NONNULL_END diff --git a/iOS/Pod/Classes/Dev/DoricLocalServer.m b/iOS/Pod/Classes/Dev/DoricLocalServer.m new file mode 100644 index 00000000..7694ae5e --- /dev/null +++ b/iOS/Pod/Classes/Dev/DoricLocalServer.m @@ -0,0 +1,115 @@ +// +// DoricLocalServer.m +// Doric +// +// Created by pengfei.zhou on 2019/8/14. +// + +#import "DoricLocalServer.h" +#import "GCDWebServer.h" +#import "GCDWebServerDataResponse.h" +#import "DoricUtil.h" +#import "DoricContextManager.h" + +#include +#include +#include + +typedef id (^ServerHandler)(GCDWebServerRequest * request); + +@interface DoricLocalServer() +@property (nonatomic, strong) GCDWebServer *server; +@property (nonatomic, strong) NSMutableDictionary *handlers; +@end + +@implementation DoricLocalServer + +- (instancetype)init { + if (self = [super init]) { + _server = [[GCDWebServer alloc] init]; + _handlers = [[NSMutableDictionary alloc] init]; + [self configurate]; + } + return self; +} + +- (NSString *)localIPAddress { + NSString *localIP = nil; + struct ifaddrs *addrs; + if (getifaddrs(&addrs)==0) { + const struct ifaddrs *cursor = addrs; + while (cursor != NULL) { + if (cursor->ifa_addr->sa_family == AF_INET && (cursor->ifa_flags & IFF_LOOPBACK) == 0) { + //NSString *name = [NSString stringWithUTF8String:cursor->ifa_name]; + //if ([name isEqualToString:@"en0"]) // Wi-Fi adapter + { + localIP = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)cursor->ifa_addr)->sin_addr)]; + break; + } + } + cursor = cursor->ifa_next; + } + freeifaddrs(addrs); + } + return localIP; +} + +- (GCDWebServerResponse *)handleRequest:(GCDWebServerRequest *)request { + if ([request.path hasPrefix:@"/api/"]) { + NSString *command = [request.path substringFromIndex:@"/api/".length]; + ServerHandler handler = [self.handlers objectForKey:command]; + if (handler) { + id dic = handler(request); + return [GCDWebServerDataResponse responseWithJSONObject:dic]; + } + return [GCDWebServerDataResponse responseWithHTML:@"

It's a API request.

"]; + } + NSBundle *bundle = DoricBundle(); + NSString *filePath = [NSString stringWithFormat:@"%@/dist%@",bundle.bundlePath,request.path]; + NSData *data = [NSData dataWithContentsOfFile:filePath]; + NSURL *url = [NSURL fileURLWithPath:filePath]; + NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url]; + NSHTTPURLResponse *response; + [NSURLConnection sendSynchronousRequest:req returningResponse:&response error:nil]; + return [GCDWebServerDataResponse responseWithData:data contentType:response.MIMEType]; +} + +- (void)configurate { + __weak typeof(self) _self = self; + [self.server addDefaultHandlerForMethod:@"GET" + requestClass:[GCDWebServerRequest class] + processBlock:^GCDWebServerResponse * (GCDWebServerRequest * request) { + __strong typeof(_self) self = _self; + return [self handleRequest:request]; + }]; + [self.handlers setObject:^id(GCDWebServerRequest *request) { + NSMutableArray *array = [[NSMutableArray alloc] init]; + + for(NSValue *value in [[DoricContextManager instance] aliveContexts]) { + DoricContext *context = value.nonretainedObjectValue; + [array addObject:@{ + @"source":context.source, + @"id":context.contextId, + }]; + } + return array; + } + forKey:@"allContexts"]; + + [self.handlers setObject:^id(GCDWebServerRequest *request) { + NSString *contextId = [request.query objectForKey:@"id"]; + DoricContext *context = [[DoricContextManager instance] getContext:contextId]; + return @{ + @"id":context.contextId, + @"source":context.source, + @"script":context.script + }; + } + forKey:@"context"]; +} + +- (void)startWithPort:(NSUInteger)port { + [self.server startWithPort:port bonjourName:nil]; + DoricLog(@"Start Server At %@:%d",[self localIPAddress],port); +} +@end