diff --git a/CordovaLib/Classes/Private/Plugins/CDVIntentAndNavigationFilter/CDVIntentAndNavigationFilter.m b/CordovaLib/Classes/Private/Plugins/CDVIntentAndNavigationFilter/CDVIntentAndNavigationFilter.m index 04a7444f7..bf8479e73 100644 --- a/CordovaLib/Classes/Private/Plugins/CDVIntentAndNavigationFilter/CDVIntentAndNavigationFilter.m +++ b/CordovaLib/Classes/Private/Plugins/CDVIntentAndNavigationFilter/CDVIntentAndNavigationFilter.m @@ -18,6 +18,7 @@ Licensed to the Apache Software Foundation (ASF) under one */ #import "CDVIntentAndNavigationFilter.h" +#import @interface CDVIntentAndNavigationFilter () @@ -73,9 +74,7 @@ - (void)parser:(NSXMLParser*)parser parseErrorOccurred:(NSError*)parseError - (void)pluginInitialize { - if ([self.viewController isKindOfClass:[CDVViewController class]]) { - [(CDVViewController*)self.viewController parseSettingsWithParser:self]; - } + [CDVConfigParser parseConfigFile:self.viewController.configFilePath withDelegate:self]; } + (CDVIntentAndNavigationFilterValue) filterUrl:(NSURL*)url allowIntentsList:(CDVAllowList*)allowIntentsList navigationsAllowList:(CDVAllowList*)navigationsAllowList diff --git a/CordovaLib/Classes/Public/CDVConfigParser.m b/CordovaLib/Classes/Public/CDVConfigParser.m index a5663e590..6f8da6a92 100644 --- a/CordovaLib/Classes/Public/CDVConfigParser.m +++ b/CordovaLib/Classes/Public/CDVConfigParser.m @@ -20,19 +20,47 @@ Licensed to the Apache Software Foundation (ASF) under one #import @interface CDVConfigParser () +{ + NSString *featureName; +} -@property (nonatomic, readwrite, strong) NSMutableDictionary* pluginsDict; -@property (nonatomic, readwrite, strong) NSMutableDictionary* settings; -@property (nonatomic, readwrite, strong) NSMutableArray* startupPluginNames; -@property (nonatomic, readwrite, strong) NSString* startPage; +@property (nonatomic, readwrite, strong) NSMutableDictionary *pluginsDict; +@property (nonatomic, readwrite, strong) NSMutableDictionary *settings; +@property (nonatomic, readwrite, strong) NSMutableArray *startupPluginNames; +@property (nonatomic, readwrite, strong) NSString *startPage; @end @implementation CDVConfigParser -@synthesize pluginsDict, settings, startPage, startupPluginNames; +@synthesize pluginsDict; +@synthesize settings; +@synthesize startPage; +@synthesize startupPluginNames; + ++ (instancetype)parseConfigFile:(NSURL *)filePath +{ + CDVConfigParser* delegate = [[CDVConfigParser alloc] init]; + [CDVConfigParser parseConfigFile:filePath withDelegate:delegate]; + return delegate; +} + ++ (BOOL)parseConfigFile:(NSURL *)filePath withDelegate:(id )delegate +{ + NSXMLParser *configParser = [[NSXMLParser alloc] initWithContentsOfURL:filePath]; + + if (configParser == nil) { + NSLog(@"Failed to initialize XML parser."); + return NO; + } + + [configParser setDelegate:delegate]; + [configParser parse]; + + return YES; +} -- (id)init +- (instancetype)init { self = [super init]; if (self != nil) { @@ -44,14 +72,14 @@ - (id)init return self; } -- (void)parser:(NSXMLParser*)parser didStartElement:(NSString*)elementName namespaceURI:(NSString*)namespaceURI qualifiedName:(NSString*)qualifiedName attributes:(NSDictionary*)attributeDict +- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict { if ([elementName isEqualToString:@"preference"]) { settings[[attributeDict[@"name"] lowercaseString]] = attributeDict[@"value"]; } else if ([elementName isEqualToString:@"feature"]) { // store feature name to use with correct parameter set featureName = [attributeDict[@"name"] lowercaseString]; } else if ((featureName != nil) && [elementName isEqualToString:@"param"]) { - NSString* paramName = [attributeDict[@"name"] lowercaseString]; + NSString *paramName = [attributeDict[@"name"] lowercaseString]; id value = attributeDict[@"value"]; if ([paramName isEqualToString:@"ios-package"]) { pluginsDict[featureName] = value; @@ -66,14 +94,14 @@ - (void)parser:(NSXMLParser*)parser didStartElement:(NSString*)elementName names } } -- (void)parser:(NSXMLParser*)parser didEndElement:(NSString*)elementName namespaceURI:(NSString*)namespaceURI qualifiedName:(NSString*)qualifiedName +- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName { if ([elementName isEqualToString:@"feature"]) { // no longer handling a feature so release featureName = nil; } } -- (void)parser:(NSXMLParser*)parser parseErrorOccurred:(NSError*)parseError +- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError { NSAssert(NO, @"config.xml parse error line %ld col %ld", (long)[parser lineNumber], (long)[parser columnNumber]); } diff --git a/CordovaLib/Classes/Public/CDVViewController.m b/CordovaLib/Classes/Public/CDVViewController.m index f86bffdb0..475d85e5b 100644 --- a/CordovaLib/Classes/Public/CDVViewController.m +++ b/CordovaLib/Classes/Public/CDVViewController.m @@ -161,11 +161,12 @@ - (void)setSplashBackgroundColor:(UIColor *)color _splashBackgroundColor = color ?: self.backgroundColor; } --(NSString*)configFilePath{ - NSString* path = self.configFile ?: @"config.xml"; +- (nullable NSURL *)configFilePath +{ + NSString* path = self.configFile; // if path is relative, resolve it against the main bundle - if(![path isAbsolutePath]){ + if (![path isAbsolutePath]) { NSString* absolutePath = [[NSBundle mainBundle] pathForResource:path ofType:nil]; if(!absolutePath){ NSAssert(NO, @"ERROR: %@ not found in the main bundle!", path); @@ -179,42 +180,24 @@ -(NSString*)configFilePath{ return nil; } - return path; -} - -- (void)parseSettingsWithParser:(NSObject *)delegate -{ - // read from config.xml in the app bundle - NSString* path = [self configFilePath]; - - NSURL* url = [NSURL fileURLWithPath:path]; - - self.configParser = [[NSXMLParser alloc] initWithContentsOfURL:url]; - if (self.configParser == nil) { - NSLog(@"Failed to initialize XML parser."); - return; - } - [self.configParser setDelegate:((id < NSXMLParserDelegate >)delegate)]; - [self.configParser parse]; + return [NSURL fileURLWithPath:path]; } - (void)loadSettings { - CDVConfigParser* delegate = [[CDVConfigParser alloc] init]; - - [self parseSettingsWithParser:delegate]; + CDVConfigParser *parser = [CDVConfigParser parseConfigFile:self.configFilePath]; // Get the plugin dictionary, allowList and settings from the delegate. - self.pluginsMap = delegate.pluginsDict; - self.startupPluginNames = delegate.startupPluginNames; - self.settings = [[CDVSettingsDictionary alloc] initWithDictionary:delegate.settings]; + self.pluginsMap = parser.pluginsDict; + self.startupPluginNames = parser.startupPluginNames; + self.settings = [[CDVSettingsDictionary alloc] initWithDictionary:parser.settings]; // And the start folder/page. if(self.wwwFolderName == nil){ self.wwwFolderName = @"www"; } - if(delegate.startPage && self.startPage == nil){ - self.startPage = delegate.startPage; + if(parser.startPage && self.startPage == nil){ + self.startPage = parser.startPage; } if (self.startPage == nil) { self.startPage = @"index.html"; @@ -747,4 +730,9 @@ - (void)showLaunchScreen:(BOOL)visible }]; } +- (void)parseSettingsWithParser:(id )delegate +{ + [CDVConfigParser parseConfigFile:self.configFilePath withDelegate:delegate]; +} + @end diff --git a/CordovaLib/include/Cordova/CDVConfigParser.h b/CordovaLib/include/Cordova/CDVConfigParser.h index 0a937031e..f25febf95 100644 --- a/CordovaLib/include/Cordova/CDVConfigParser.h +++ b/CordovaLib/include/Cordova/CDVConfigParser.h @@ -15,18 +15,70 @@ KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - */ +*/ #import +NS_ASSUME_NONNULL_BEGIN + +/** + An object that handles parsing Cordova XML configuration files. + + ## Overview + The `CDVConfigParser` class provides methods to parse a Cordova XML + configuration file and then access the resulting configuration data. + + Use ``parseConfigFile:`` to load data from a file path. + + Use ``parseConfigFile:withDelegate:`` if you need to intercept the XML parsing + and handle the data yourself with an ``NSXMLParserDelegate``. + */ @interface CDVConfigParser : NSObject -{ - NSString* featureName; -} -@property (nonatomic, readonly, strong) NSMutableDictionary* pluginsDict; -@property (nonatomic, readonly, strong) NSMutableDictionary* settings; -@property (nonatomic, readonly, strong) NSMutableArray* startupPluginNames; -@property (nonatomic, readonly, strong) NSString* startPage; +/** + A dictionary mapping Cordova plugin name keys to the plugin classes that implement them. + */ +@property (nonatomic, readonly, strong) NSMutableDictionary *pluginsDict; + +/** + A dictionary of Cordova preference keys and their values. + This should not be used directly, you should only use it to initialize a + ``CDVSettingsDictionary`` object. + */ +@property (nonatomic, readonly, strong) NSMutableDictionary *settings; + +/** + An array of plugin names to load immediately when Cordova initializes. + */ +@property (nonatomic, readonly, strong) NSMutableArray *startupPluginNames; + +/** + The path to the HTML page to display when the web view loads. + */ +@property (nonatomic, nullable, readonly, strong) NSString *startPage; + +/** + Parses the given path as a Cordova XML configuration file. + + If the file could not be loaded or parsed, the resulting ``CDVConfigParser`` + object will have empty values. + + - Parameters: + - filePath: The file path URL to the configuration file. + - Returns: A ``CDVConfigParser`` with the parsed result. + */ ++ (instancetype)parseConfigFile:(NSURL *)filePath; + +/** + Parses the given path as a Cordova XML configuration file using the given delegate. + + - Parameters: + - filePath: The file path URL to the configuration file. + - delegate: The delegate to handle the parsed XML data. + - Returns: Whether the given file was successfully parsed. + */ ++ (BOOL)parseConfigFile:(NSURL *)filePath withDelegate:(id )delegate; @end + +NS_ASSUME_NONNULL_END diff --git a/CordovaLib/include/Cordova/CDVViewController.h b/CordovaLib/include/Cordova/CDVViewController.h index fc0b94a95..2be684424 100644 --- a/CordovaLib/include/Cordova/CDVViewController.h +++ b/CordovaLib/include/Cordova/CDVViewController.h @@ -30,9 +30,11 @@ @class CDVPlugin; +NS_ASSUME_NONNULL_BEGIN + @interface CDVViewController : UIViewController -NS_ASSUME_NONNULL_BEGIN +@property (nonatomic, nullable, readonly, strong) NSXMLParser *configParser CDV_DEPRECATED(8, "Unused"); @property (nonatomic, readonly, nullable, weak) IBOutlet UIView* webView; @@ -47,8 +49,6 @@ NS_ASSUME_NONNULL_BEGIN */ @property (nonatomic, readonly, strong) CDVSettingsDictionary* settings; -@property (nonatomic, readonly, strong) NSXMLParser* configParser; - @property (nonatomic, readwrite, copy) NSString* appScheme; @property (nonatomic, readwrite, copy) NSString* configFile; @property (nonatomic, readwrite, copy) NSString* wwwFolderName; @@ -57,6 +57,10 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, readonly, strong) id webViewEngine; @property (nonatomic, readonly, strong) id commandDelegate; +/** + The filepath to the Cordova XML configuration file. + */ +@property (nonatomic, nullable, readonly, copy) NSURL *configFilePath; /** A boolean value indicating whether to show the splash screen while the webview @@ -109,6 +113,6 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)showLaunchScreen:(BOOL)visible; -NS_ASSUME_NONNULL_END - @end + +NS_ASSUME_NONNULL_END