diff --git a/ios/RNMBX/RNMBXAtmosphereComponentView.mm b/ios/RNMBX/RNMBXAtmosphereComponentView.mm index 7eea4dcf48..d32d6eb15a 100644 --- a/ios/RNMBX/RNMBXAtmosphereComponentView.mm +++ b/ios/RNMBX/RNMBXAtmosphereComponentView.mm @@ -3,6 +3,7 @@ #import "RNMBXFabricHelpers.h" #import +#import "RNMBXBridgeManager.h" #import #import @@ -40,7 +41,7 @@ - (instancetype)initWithFrame:(CGRect)frame - (void)prepareView { _view = [[RNMBXAtmosphere alloc] init]; - _view.bridge = [RCTBridge currentBridge]; + _view.bridge = [RNMBXBridgeManager currentBridge]; self.contentView = _view; } diff --git a/ios/RNMBX/RNMBXBackgroundLayerComponentView.mm b/ios/RNMBX/RNMBXBackgroundLayerComponentView.mm index f3fc7f14b0..f331d60edf 100644 --- a/ios/RNMBX/RNMBXBackgroundLayerComponentView.mm +++ b/ios/RNMBX/RNMBXBackgroundLayerComponentView.mm @@ -3,6 +3,7 @@ #import "RNMBXFabricHelpers.h" #import +#import "RNMBXBridgeManager.h" #import #import @@ -40,7 +41,7 @@ - (instancetype)initWithFrame:(CGRect)frame - (void)prepareView { _view = [[RNMBXBackgroundLayer alloc] init]; - _view.bridge = [RCTBridge currentBridge]; + _view.bridge = [RNMBXBridgeManager currentBridge]; self.contentView = _view; } diff --git a/ios/RNMBX/RNMBXBridgeManager.h b/ios/RNMBX/RNMBXBridgeManager.h new file mode 100644 index 0000000000..f5568b589c --- /dev/null +++ b/ios/RNMBX/RNMBXBridgeManager.h @@ -0,0 +1,8 @@ +#import + +@interface RNMBXBridgeManager : NSObject + ++ (void)setBridge:(RCTBridge *)bridge; ++ (RCTBridge *)currentBridge; + +@end diff --git a/ios/RNMBX/RNMBXBridgeManager.m b/ios/RNMBX/RNMBXBridgeManager.m new file mode 100644 index 0000000000..4398e45907 --- /dev/null +++ b/ios/RNMBX/RNMBXBridgeManager.m @@ -0,0 +1,16 @@ +#import "RNMBXBridgeManager.h" +#import + +static __weak RCTBridge *_rnmbxBridge = nil; + +@implementation RNMBXBridgeManager + ++ (void)setBridge:(RCTBridge *)bridge { + _rnmbxBridge = bridge; +} + ++ (RCTBridge *)currentBridge { + return [RCTBridge currentBridge] ?: _rnmbxBridge; +} + +@end diff --git a/ios/RNMBX/RNMBXCircleLayerComponentView.mm b/ios/RNMBX/RNMBXCircleLayerComponentView.mm index 909a831139..8e666593f5 100644 --- a/ios/RNMBX/RNMBXCircleLayerComponentView.mm +++ b/ios/RNMBX/RNMBXCircleLayerComponentView.mm @@ -5,6 +5,7 @@ #import #import #import +#import "RNMBXBridgeManager.h" #import #import @@ -40,7 +41,7 @@ - (instancetype)initWithFrame:(CGRect)frame - (void)prepareView { _view = [[RNMBXCircleLayer alloc] init]; - _view.bridge = [RCTBridge currentBridge]; + _view.bridge = [RNMBXBridgeManager currentBridge]; self.contentView = _view; } diff --git a/ios/RNMBX/RNMBXFillExtrusionLayerComponentView.mm b/ios/RNMBX/RNMBXFillExtrusionLayerComponentView.mm index 176699039e..7c1f9456be 100644 --- a/ios/RNMBX/RNMBXFillExtrusionLayerComponentView.mm +++ b/ios/RNMBX/RNMBXFillExtrusionLayerComponentView.mm @@ -5,6 +5,7 @@ #import #import #import +#import "RNMBXBridgeManager.h" #import #import @@ -40,7 +41,7 @@ - (instancetype)initWithFrame:(CGRect)frame - (void)prepareView { _view = [[RNMBXFillExtrusionLayer alloc] init]; - _view.bridge = [RCTBridge currentBridge]; + _view.bridge = [RNMBXBridgeManager currentBridge]; self.contentView = _view; } diff --git a/ios/RNMBX/RNMBXFillLayerComponentView.mm b/ios/RNMBX/RNMBXFillLayerComponentView.mm index e081e226a2..f606dbbf86 100644 --- a/ios/RNMBX/RNMBXFillLayerComponentView.mm +++ b/ios/RNMBX/RNMBXFillLayerComponentView.mm @@ -5,6 +5,7 @@ #import #import #import +#import "RNMBXBridgeManager.h" #import #import @@ -40,7 +41,7 @@ - (instancetype)initWithFrame:(CGRect)frame - (void)prepareView { _view = [[RNMBXFillLayer alloc] init]; - _view.bridge = [RCTBridge currentBridge]; + _view.bridge = [RNMBXBridgeManager currentBridge]; self.contentView = _view; } diff --git a/ios/RNMBX/RNMBXHeatmapLayerComponentView.mm b/ios/RNMBX/RNMBXHeatmapLayerComponentView.mm index 25c2dd73c4..7951732a55 100644 --- a/ios/RNMBX/RNMBXHeatmapLayerComponentView.mm +++ b/ios/RNMBX/RNMBXHeatmapLayerComponentView.mm @@ -5,6 +5,7 @@ #import #import #import +#import "RNMBXBridgeManager.h" #import #import @@ -40,7 +41,7 @@ - (instancetype)initWithFrame:(CGRect)frame - (void)prepareView { _view = [[RNMBXHeatmapLayer alloc] init]; - _view.bridge = [RCTBridge currentBridge]; + _view.bridge = [RNMBXBridgeManager currentBridge]; self.contentView = _view; } #pragma mark - RCTComponentViewProtocol diff --git a/ios/RNMBX/RNMBXHillshadeLayerComponentView.mm b/ios/RNMBX/RNMBXHillshadeLayerComponentView.mm index 8c3792cf96..91524115b8 100644 --- a/ios/RNMBX/RNMBXHillshadeLayerComponentView.mm +++ b/ios/RNMBX/RNMBXHillshadeLayerComponentView.mm @@ -5,6 +5,7 @@ #import #import #import +#import "RNMBXBridgeManager.h" #import #import @@ -40,7 +41,7 @@ - (instancetype)initWithFrame:(CGRect)frame - (void)prepareView { _view = [[RNMBXHillshadeLayer alloc] init]; - _view.bridge = [RCTBridge currentBridge]; + _view.bridge = [RNMBXBridgeManager currentBridge]; self.contentView = _view; } diff --git a/ios/RNMBX/RNMBXImageModule.h b/ios/RNMBX/RNMBXImageModule.h index 9c89de3d3c..19e13b09f9 100644 --- a/ios/RNMBX/RNMBXImageModule.h +++ b/ios/RNMBX/RNMBXImageModule.h @@ -14,3 +14,4 @@ @end #endif + diff --git a/ios/RNMBX/RNMBXImageModule.mm b/ios/RNMBX/RNMBXImageModule.mm index e21b4ff216..0bb9417e51 100644 --- a/ios/RNMBX/RNMBXImageModule.mm +++ b/ios/RNMBX/RNMBXImageModule.mm @@ -4,15 +4,28 @@ #import "RNMBXImageModule.h" #import "RNMBXImageComponentView.h" +#import "RNMBXBridgeManager.h" #import "rnmapbox_maps-Swift.pre.h" -@implementation RNMBXImageModule +@implementation RNMBXImageModule { + id _bridgeBacking; +} RCT_EXPORT_MODULE(); @synthesize viewRegistry_DEPRECATED = _viewRegistry_DEPRECATED; -@synthesize bridge = _bridge; + +- (void)setBridge:(RCTBridge *)bridge { + _bridgeBacking = bridge; + if (bridge != nil) { + [RNMBXBridgeManager setBridge:bridge]; + } +} + +- (RCTBridge *)bridge { + return _bridgeBacking; +} - (dispatch_queue_t)methodQueue { diff --git a/ios/RNMBX/RNMBXImageQueue.swift b/ios/RNMBX/RNMBXImageQueue.swift index 0560de2979..778e932cbf 100644 --- a/ios/RNMBX/RNMBXImageQueue.swift +++ b/ios/RNMBX/RNMBXImageQueue.swift @@ -67,7 +67,15 @@ class RNMBXImageQueueOperation : Operation { DispatchQueue.global(qos: .default).async { if let weakSelf = weakSelf { - let loader : RCTImageLoaderProtocol = weakSelf.bridge!.module(forName: "ImageLoader", lazilyLoadIfNecessary: true) as! RCTImageLoaderProtocol + guard let bridge = weakSelf.bridge else { + Logger.log(level: .error, message: "RNMBXImageQueue: bridge is nil, cannot load image") + if let completionHandler = weakSelf.completionHandler { + completionHandler(NSError(domain: "RNMBXImageQueue", code: 1, userInfo: [NSLocalizedDescriptionKey: "bridge is nil"]), nil) + } + _ = weakSelf.setState(state:.Finished, except:.Finished) + return + } + let loader : RCTImageLoaderProtocol = bridge.module(forName: "ImageLoader", lazilyLoadIfNecessary: true) as! RCTImageLoaderProtocol let cancellationBlock = loader.loadImage(with: weakSelf.urlRequest, size: .zero, scale: CGFloat(weakSelf.scale), clipped: true, resizeMode: .stretch, progressBlock: { _,_ in }, partialLoad: { _ in }) { error, image in if let completionHandler = weakSelf.completionHandler { diff --git a/ios/RNMBX/RNMBXImages.swift b/ios/RNMBX/RNMBXImages.swift index b89393de28..797cf3e373 100644 --- a/ios/RNMBX/RNMBXImages.swift +++ b/ios/RNMBX/RNMBXImages.swift @@ -130,6 +130,10 @@ open class RNMBXImages : UIView, RNMBXMapComponent { } if missingImages.count > 0 { + guard let bridge = bridge else { + Logger.log(level: .error, message: "RNMBXImages: bridge is nil, cannot fetch images. Use nativeAssetImages instead.") + return + } RNMBXUtils.fetchImages(bridge, style: style, objects: missingImages, forceUpdate: true) { name, image in self.loadedImages.insert(name) self.imageManager?.resolve(name: name, image: image) diff --git a/ios/RNMBX/RNMBXImagesComponentView.mm b/ios/RNMBX/RNMBXImagesComponentView.mm index 52203aa52a..6ce7d6b397 100644 --- a/ios/RNMBX/RNMBXImagesComponentView.mm +++ b/ios/RNMBX/RNMBXImagesComponentView.mm @@ -5,6 +5,7 @@ #include "RNMBXImageComponentView.h" #import +#import "RNMBXBridgeManager.h" #import #import @@ -42,7 +43,7 @@ - (instancetype)initWithFrame:(CGRect)frame - (void)prepareView { _view = [[RNMBXImages alloc] init]; - _view.bridge = [RCTBridge currentBridge]; + _view.bridge = [RNMBXBridgeManager currentBridge]; // capture weak self reference to prevent retain cycle __weak __typeof__(self) weakSelf = self; diff --git a/ios/RNMBX/RNMBXLightComponentView.mm b/ios/RNMBX/RNMBXLightComponentView.mm index f0dc33b605..234c7f60af 100644 --- a/ios/RNMBX/RNMBXLightComponentView.mm +++ b/ios/RNMBX/RNMBXLightComponentView.mm @@ -3,6 +3,7 @@ #import "RNMBXFabricHelpers.h" #import +#import "RNMBXBridgeManager.h" #import #import @@ -40,7 +41,7 @@ - (instancetype)initWithFrame:(CGRect)frame - (void)prepareView { _view = [[RNMBXLight alloc] init]; - _view.bridge = [RCTBridge currentBridge]; + _view.bridge = [RNMBXBridgeManager currentBridge]; self.contentView = _view; } diff --git a/ios/RNMBX/RNMBXLineLayerComponentView.mm b/ios/RNMBX/RNMBXLineLayerComponentView.mm index d85a9fc3e5..819ec55db1 100644 --- a/ios/RNMBX/RNMBXLineLayerComponentView.mm +++ b/ios/RNMBX/RNMBXLineLayerComponentView.mm @@ -5,6 +5,7 @@ #import #import #import +#import "RNMBXBridgeManager.h" #import #import @@ -40,7 +41,7 @@ - (instancetype)initWithFrame:(CGRect)frame - (void)prepareView { _view = [[RNMBXLineLayer alloc] init]; - _view.bridge = [RCTBridge currentBridge]; + _view.bridge = [RNMBXBridgeManager currentBridge]; self.contentView = _view; } diff --git a/ios/RNMBX/RNMBXModelLayerComponentView.mm b/ios/RNMBX/RNMBXModelLayerComponentView.mm index 25c72bfd7d..c714e9c915 100644 --- a/ios/RNMBX/RNMBXModelLayerComponentView.mm +++ b/ios/RNMBX/RNMBXModelLayerComponentView.mm @@ -5,6 +5,7 @@ #import #import #import +#import "RNMBXBridgeManager.h" #import #import @@ -40,7 +41,7 @@ - (instancetype)initWithFrame:(CGRect)frame - (void)prepareView { _view = [[RNMBXModelLayer alloc] init]; - _view.bridge = [RCTBridge currentBridge]; + _view.bridge = [RNMBXBridgeManager currentBridge]; self.contentView = _view; } diff --git a/ios/RNMBX/RNMBXRainComponentView.mm b/ios/RNMBX/RNMBXRainComponentView.mm index f96c14cbfb..fdb9800e04 100644 --- a/ios/RNMBX/RNMBXRainComponentView.mm +++ b/ios/RNMBX/RNMBXRainComponentView.mm @@ -3,6 +3,7 @@ #import "RNMBXFabricHelpers.h" #import +#import "RNMBXBridgeManager.h" #import #import @@ -40,7 +41,7 @@ - (instancetype)initWithFrame:(CGRect)frame - (void)prepareView { _view = [[RNMBXRain alloc] init]; - _view.bridge = [RCTBridge currentBridge]; + _view.bridge = [RNMBXBridgeManager currentBridge]; self.contentView = _view; } diff --git a/ios/RNMBX/RNMBXRasterLayerComponentView.mm b/ios/RNMBX/RNMBXRasterLayerComponentView.mm index a63025161e..583eb764a1 100644 --- a/ios/RNMBX/RNMBXRasterLayerComponentView.mm +++ b/ios/RNMBX/RNMBXRasterLayerComponentView.mm @@ -5,6 +5,7 @@ #import #import #import +#import "RNMBXBridgeManager.h" #import #import @@ -40,7 +41,7 @@ - (instancetype)initWithFrame:(CGRect)frame - (void)prepareView { _view = [[RNMBXRasterLayer alloc] init]; - _view.bridge = [RCTBridge currentBridge]; + _view.bridge = [RNMBXBridgeManager currentBridge]; self.contentView = _view; } diff --git a/ios/RNMBX/RNMBXRasterParticleLayerComponentView.mm b/ios/RNMBX/RNMBXRasterParticleLayerComponentView.mm index 0b10b22227..54bf454f4f 100644 --- a/ios/RNMBX/RNMBXRasterParticleLayerComponentView.mm +++ b/ios/RNMBX/RNMBXRasterParticleLayerComponentView.mm @@ -5,6 +5,7 @@ #import #import #import +#import "RNMBXBridgeManager.h" #import #import @@ -40,7 +41,7 @@ - (instancetype)initWithFrame:(CGRect)frame - (void)prepareView { _view = [[RNMBXRasterParticleLayer alloc] init]; - _view.bridge = [RCTBridge currentBridge]; + _view.bridge = [RNMBXBridgeManager currentBridge]; self.contentView = _view; } diff --git a/ios/RNMBX/RNMBXSkyLayerComponentView.mm b/ios/RNMBX/RNMBXSkyLayerComponentView.mm index 8adb75f9d4..9d2bfd0c53 100644 --- a/ios/RNMBX/RNMBXSkyLayerComponentView.mm +++ b/ios/RNMBX/RNMBXSkyLayerComponentView.mm @@ -5,6 +5,7 @@ #import #import #import +#import "RNMBXBridgeManager.h" #import #import @@ -40,7 +41,7 @@ - (instancetype)initWithFrame:(CGRect)frame - (void)prepareView { _view = [[RNMBXSkyLayer alloc] init]; - _view.bridge = [RCTBridge currentBridge]; + _view.bridge = [RNMBXBridgeManager currentBridge]; self.contentView = _view; } diff --git a/ios/RNMBX/RNMBXSnowComponentView.mm b/ios/RNMBX/RNMBXSnowComponentView.mm index cbeff83a26..3faa9ff4bb 100644 --- a/ios/RNMBX/RNMBXSnowComponentView.mm +++ b/ios/RNMBX/RNMBXSnowComponentView.mm @@ -3,6 +3,7 @@ #import "RNMBXFabricHelpers.h" #import +#import "RNMBXBridgeManager.h" #import #import @@ -40,7 +41,7 @@ - (instancetype)initWithFrame:(CGRect)frame - (void)prepareView { _view = [[RNMBXSnow alloc] init]; - _view.bridge = [RCTBridge currentBridge]; + _view.bridge = [RNMBXBridgeManager currentBridge]; self.contentView = _view; } diff --git a/ios/RNMBX/RNMBXStyle.swift b/ios/RNMBX/RNMBXStyle.swift index a1f9db2a7e..5aaa350991 100644 --- a/ios/RNMBX/RNMBXStyle.swift +++ b/ios/RNMBX/RNMBXStyle.swift @@ -53,7 +53,7 @@ func fillLayer(layer: inout FillLayer, reactStyle:Dictionary, oldRe self.setFillTranslateAnchor(&layer, styleValue:styleValue); } else if (prop == "fillPattern") { styleValue.setImage( - bridge: bridge!, + bridge: bridge, style: style, oldValue: oldReactStyle?[prop], setImageOnLayer: { (_) in self.setFillPattern(&layer, styleValue:styleValue) }, @@ -63,7 +63,7 @@ func fillLayer(layer: inout FillLayer, reactStyle:Dictionary, oldRe ) } else if (prop == "fillPatternCrossFade") { styleValue.setImage( - bridge: bridge!, + bridge: bridge, style: style, oldValue: oldReactStyle?[prop], setImageOnLayer: { (_) in self.setFillPatternCrossFade(&layer, styleValue:styleValue) }, @@ -142,7 +142,7 @@ func lineLayer(layer: inout LineLayer, reactStyle:Dictionary, oldRe self.setLineDasharray(&layer, styleValue:styleValue); } else if (prop == "linePattern") { styleValue.setImage( - bridge: bridge!, + bridge: bridge, style: style, oldValue: oldReactStyle?[prop], setImageOnLayer: { (_) in self.setLinePattern(&layer, styleValue:styleValue) }, @@ -174,7 +174,7 @@ func lineLayer(layer: inout LineLayer, reactStyle:Dictionary, oldRe self.setLineElevationGroundScaleTransition(&layer, styleValue:styleValue); } else if (prop == "linePatternCrossFade") { styleValue.setImage( - bridge: bridge!, + bridge: bridge, style: style, oldValue: oldReactStyle?[prop], setImageOnLayer: { (_) in self.setLinePatternCrossFade(&layer, styleValue:styleValue) }, @@ -243,7 +243,7 @@ func symbolLayer(layer: inout SymbolLayer, reactStyle:Dictionary, o self.setIconTextFitPadding(&layer, styleValue:styleValue); } else if (prop == "iconImage") { styleValue.setImage( - bridge: bridge!, + bridge: bridge, style: style, oldValue: oldReactStyle?[prop], setImageOnLayer: { (_) in self.setIconImage(&layer, styleValue:styleValue) }, @@ -379,7 +379,7 @@ func symbolLayer(layer: inout SymbolLayer, reactStyle:Dictionary, o self.setTextEmissiveStrengthTransition(&layer, styleValue:styleValue); } else if (prop == "iconImageCrossFade") { styleValue.setImage( - bridge: bridge!, + bridge: bridge, style: style, oldValue: oldReactStyle?[prop], setImageOnLayer: { (_) in self.setIconImageCrossFade(&layer, styleValue:styleValue) }, @@ -546,7 +546,7 @@ func fillExtrusionLayer(layer: inout FillExtrusionLayer, reactStyle:Dictionary Void, @@ -474,6 +474,12 @@ class RNMBXStyleValue { } } + guard let bridge = bridge else { + Logger.log(level: .error, message: "\(name): bridge is nil, cannot fetch image \(optional: imageURI). Use nativeAssetImages instead.") + setImageOnLayer(self) + return + } + RNMBXUtils.fetchImage(bridge, url:imageURI, scale:getImageScale(), callback:{ (error, image) in if let image = image { DispatchQueue.main.sync { diff --git a/ios/RNMBX/RNMBXSymbolLayerComponentView.mm b/ios/RNMBX/RNMBXSymbolLayerComponentView.mm index 3aa4a59f4c..7a97fa94c0 100644 --- a/ios/RNMBX/RNMBXSymbolLayerComponentView.mm +++ b/ios/RNMBX/RNMBXSymbolLayerComponentView.mm @@ -5,6 +5,7 @@ #import #import #import +#import "RNMBXBridgeManager.h" #import #import @@ -40,7 +41,7 @@ - (instancetype)initWithFrame:(CGRect)frame - (void)prepareView { _view = [[RNMBXSymbolLayer alloc] init]; - _view.bridge = [RCTBridge currentBridge]; + _view.bridge = [RNMBXBridgeManager currentBridge]; self.contentView = _view; } diff --git a/ios/RNMBX/RNMBXTerrainComponentView.mm b/ios/RNMBX/RNMBXTerrainComponentView.mm index 2b84d500df..31a0cb9602 100644 --- a/ios/RNMBX/RNMBXTerrainComponentView.mm +++ b/ios/RNMBX/RNMBXTerrainComponentView.mm @@ -3,6 +3,7 @@ #import "RNMBXFabricHelpers.h" #import +#import "RNMBXBridgeManager.h" #import #import @@ -40,7 +41,7 @@ - (instancetype)initWithFrame:(CGRect)frame - (void)prepareView { _view = [[RNMBXTerrain alloc] init]; - _view.bridge = [RCTBridge currentBridge]; + _view.bridge = [RNMBXBridgeManager currentBridge]; self.contentView = _view; } diff --git a/scripts/templates/RNMBXStyle.swift.ejs b/scripts/templates/RNMBXStyle.swift.ejs index fff61c2372..5645e0826d 100644 --- a/scripts/templates/RNMBXStyle.swift.ejs +++ b/scripts/templates/RNMBXStyle.swift.ejs @@ -35,7 +35,7 @@ func <%- setLayerMethodName(layer, 'ios') -%>(layer: inout <%- getLayerType(laye <%- ifOrElseIf(i) -%> (prop == "<%= layer.properties[i].name %>") { <%_ if (layer.properties[i].image) { _%> styleValue.setImage( - bridge: bridge!, + bridge: bridge, style: style, oldValue: oldReactStyle?[prop], setImageOnLayer: { (_) in self.set<%- iosPropMethodName(layer, pascelCase(layer.properties[i].name)) -%>(&layer, styleValue:styleValue) },