Răsfoiți Sursa

Add dictionary support to iOS Psiphon config calback

- This solves the issues where the delegate implementation
  had to serialize Psiphon config as JSON if it had already parsed it
  and stored its values in a NSDictionary.
  This lowers memory used by removing redundant JSON serialization operation.
Amir Khan 8 ani în urmă
părinte
comite
a89bd2d20f

+ 5 - 3
MobileLibrary/iOS/PsiphonTunnel/PsiphonTunnel/PsiphonTunnel.h

@@ -111,11 +111,13 @@ typedef NS_ENUM(NSInteger, PsiphonConnectionState)
  See the tunnel-core config code for details about the fields.
  See the tunnel-core config code for details about the fields.
  https://github.com/Psiphon-Labs/psiphon-tunnel-core/blob/master/psiphon/config.go
  https://github.com/Psiphon-Labs/psiphon-tunnel-core/blob/master/psiphon/config.go
 
 
- @return  JSON string with config that should used to run the Psiphon tunnel, or NULL on error.
+ @return Either JSON NSString with config that should be used to run the Psiphon tunnel,
+         or return already parsed JSON as NSDictionary,
+         or nil on error.
 
 
- Swift: @code func getPsiphonConfig() -> String? @endcode
+ Swift: @code func getPsiphonConfig() -> Any? @endcode
  */
  */
-- (NSString * _Nullable)getPsiphonConfig;
+- (id _Nullable)getPsiphonConfig;
 
 
 /*!
 /*!
  Called when the tunnel is starting to get the initial server entries (typically embedded in the app) that will be used to bootstrap the Psiphon tunnel connection. This value is in a particular format and will be supplied by Psiphon Inc.
  Called when the tunnel is starting to get the initial server entries (typically embedded in the app) that will be used to bootstrap the Psiphon tunnel connection. This value is in a particular format and will be supplied by Psiphon Inc.

+ 28 - 16
MobileLibrary/iOS/PsiphonTunnel/PsiphonTunnel/PsiphonTunnel.m

@@ -392,30 +392,42 @@
         return nil;
         return nil;
     }
     }
 
 
-    __block NSString *configStr = nil;
+    __block id configObject = nil;
     dispatch_sync(self->callbackQueue, ^{
     dispatch_sync(self->callbackQueue, ^{
-        configStr = [self.tunneledAppDelegate getPsiphonConfig];
+        configObject = [self.tunneledAppDelegate getPsiphonConfig];
     });
     });
-    if (configStr == nil) {
+    
+    if (configObject == nil) {
         [self logMessage:@"Error getting config from delegate"];
         [self logMessage:@"Error getting config from delegate"];
         return nil;
         return nil;
     }
     }
     
     
     __block NSDictionary *initialConfig = nil;
     __block NSDictionary *initialConfig = nil;
-    id block = ^(id obj, BOOL *ignored) {
-        if (ignored == nil || *ignored == YES) {
-            return;
-        }
-        initialConfig = (NSDictionary *)obj;
-    };
     
     
-    id eh = ^(NSError *err) {
-        initialConfig = nil;
-        [self logMessage:[NSString stringWithFormat: @"Config JSON parse failed: %@", err.description]];
-    };
-    
-    id parser = [SBJson4Parser parserWithBlock:block allowMultiRoot:NO unwrapRootArray:NO errorHandler:eh];
-    [parser parse:[configStr dataUsingEncoding:NSUTF8StringEncoding]];
+    if ([configObject isKindOfClass:[NSString class]]) {
+        
+        id block = ^(id obj, BOOL *ignored) {
+            if (ignored == nil || *ignored == YES) {
+                return;
+            }
+            initialConfig = (NSDictionary *)obj;
+        };
+        
+        id eh = ^(NSError *err) {
+            initialConfig = nil;
+            [self logMessage:[NSString stringWithFormat: @"Config JSON parse failed: %@", err.description]];
+        };
+        
+        id parser = [SBJson4Parser parserWithBlock:block allowMultiRoot:NO unwrapRootArray:NO errorHandler:eh];
+        [parser parse:[(NSString *)configObject dataUsingEncoding:NSUTF8StringEncoding]];
+        
+    } else if ([configObject isKindOfClass:[NSDictionary class]]) {
+        
+        initialConfig = (NSDictionary *) configObject;
+        
+    } else {
+        [self logMessage:@"getPsiphonConfig should either return an NSDictionary object or an NSString object"];
+    }
     
     
     if (initialConfig == nil) {
     if (initialConfig == nil) {
         return nil;
         return nil;