@@ -8,27 +8,44 @@ class ExternalDownloadSource
88 public string Version { get ; }
99 public string ArchiveKey { get ; }
1010 public string UrlPrefix { get ; }
11-
12- public ExternalDownloadSource ( string id , string version , string archiveKey , string urlPrefix = DefaultUrlPrefix )
11+ public string ExtractionRootName { get ; }
12+ public string ExpectedSha256 { get ; }
13+
14+ public ExternalDownloadSource (
15+ string id ,
16+ string version ,
17+ string archiveKey ,
18+ string urlPrefix = DefaultUrlPrefix ,
19+ string extractionRootName = null ,
20+ string expectedSha256 = null )
1321 {
1422 Id = id ;
1523 Version = version ;
1624 ArchiveKey = archiveKey ;
1725 UrlPrefix = urlPrefix ;
26+ ExtractionRootName = extractionRootName ?? $ "{ Id } -{ Version } ";
27+ ExpectedSha256 = expectedSha256 ;
1828 }
1929
2030 public string ArchiveFileName => $ "{ Id } -{ Version } .tar.gz";
21- public string ExtractionRootName => $ "{ Id } -{ Version } ";
2231 public string Url => $ "{ UrlPrefix } /{ ArchiveKey } /{ ArchiveFileName } ";
2332}
2433
2534// *.tar.gz URLs can be found in the podspecs (e.g., CocoaPods Specs repo paths), such as:
2635// FirebaseAnalytics: https://github.com/CocoaPods/Specs/tree/master/Specs/e/2/1/FirebaseAnalytics
2736// GoogleAppMeasurement: https://github.com/CocoaPods/Specs/tree/master/Specs/e/3/b/GoogleAppMeasurement
37+ // GoogleMaps: https://github.com/CocoaPods/Specs/tree/master/Specs/1/9/0/GoogleMaps
2838// GooglePlaces: https://github.com/CocoaPods/Specs/tree/master/Specs/c/3/2/GooglePlaces
2939var ExternalDownloads = new Dictionary < string , ExternalDownloadSource > {
3040 { "FirebaseAnalytics" , new ExternalDownloadSource ( "FirebaseAnalytics" , "12.10.0" , "3c185b45848d98d8" ) } ,
3141 { "GoogleAppMeasurement" , new ExternalDownloadSource ( "GoogleAppMeasurement" , "12.10.0" , "5f5e4d8cb469941e" ) } ,
42+ { "GoogleMaps" , new ExternalDownloadSource (
43+ "GoogleMaps" ,
44+ "9.2.0" ,
45+ "33a7ac549361ab23" ,
46+ "https://dl.google.com/dl/cpdc" ,
47+ extractionRootName : "Maps" ,
48+ expectedSha256 : "81bbd92c2d627087ae222ae955e5f746590812d7389b9d800add15e4004b6431" ) } ,
3249 { "GooglePlaces" , new ExternalDownloadSource ( "GooglePlaces" , "7.4.0" , "3e8dc2602895d53405d075ff4eb569bff93ff1af97e69915d1e657c07ef28dd8" , "https://dl.google.com/dl/geosdk" ) } ,
3350} ;
3451
@@ -60,6 +77,7 @@ void DownloadAndExtract (ExternalDownloadSource source, Func<bool> artifactsAlre
6077 DeleteFile ( archivePath ) ;
6178
6279 DownloadArchive ( source , archivePath ) ;
80+ VerifyArchiveHash ( source , archivePath ) ;
6381
6482 var exitCode = ExtractArchive ( source , externalsPath , archivePath ) ;
6583
@@ -84,6 +102,22 @@ void DownloadArchive (ExternalDownloadSource source, FilePath archivePath)
84102 DownloadFile ( source . Url , archivePath ) ;
85103}
86104
105+ void VerifyArchiveHash ( ExternalDownloadSource source , FilePath archivePath )
106+ {
107+ if ( string . IsNullOrWhiteSpace ( source . ExpectedSha256 ) )
108+ return ;
109+
110+ string actualSha256 ;
111+ using ( var stream = System . IO . File . OpenRead ( archivePath . FullPath ) )
112+ using ( var sha256 = System . Security . Cryptography . SHA256 . Create ( ) )
113+ actualSha256 = BitConverter . ToString ( sha256 . ComputeHash ( stream ) ) . Replace ( "-" , "" ) . ToLowerInvariant ( ) ;
114+
115+ if ( ! string . Equals ( actualSha256 , source . ExpectedSha256 , StringComparison . OrdinalIgnoreCase ) )
116+ throw new Exception ( $ "SHA-256 mismatch for { source . ArchiveFileName } : expected { source . ExpectedSha256 } , got { actualSha256 } .") ;
117+
118+ Information ( $ "Verified SHA-256 for { source . ArchiveFileName } .") ;
119+ }
120+
87121void FirebaseAnalyticsDownload ( )
88122{
89123 var source = ExternalDownloads [ "FirebaseAnalytics" ] ;
@@ -126,6 +160,37 @@ void GooglePlacesDownload ()
126160 } ) ;
127161}
128162
163+ void GoogleMapsDownload ( )
164+ {
165+ var source = ExternalDownloads [ "GoogleMaps" ] ;
166+
167+ DownloadAndExtract (
168+ source ,
169+ ( ) => DirectoryExists ( new DirectoryPath ( "./externals/GoogleMaps.xcframework" ) ) &&
170+ DirectoryExists ( new DirectoryPath ( "./externals/GoogleMaps.bundle" ) ) ,
171+ ( extractionRoot , externalsPath , deleteSettings ) => {
172+ var frameworkSource = extractionRoot . Combine ( "Frameworks" ) . Combine ( "GoogleMaps.xcframework" ) ;
173+ var resourceSource = extractionRoot . Combine ( "Resources" ) . Combine ( "GoogleMapsResources" ) . Combine ( "GoogleMaps.bundle" ) ;
174+ var frameworkDestination = externalsPath . Combine ( "GoogleMaps.xcframework" ) ;
175+ var resourceDestination = externalsPath . Combine ( "GoogleMaps.bundle" ) ;
176+
177+ if ( ! DirectoryExists ( frameworkSource ) )
178+ throw new Exception ( $ "Expected GoogleMaps.xcframework at { frameworkSource } after extraction.") ;
179+
180+ if ( ! DirectoryExists ( resourceSource ) )
181+ throw new Exception ( $ "Expected GoogleMaps.bundle at { resourceSource } after extraction.") ;
182+
183+ if ( DirectoryExists ( frameworkDestination ) )
184+ DeleteDirectory ( frameworkDestination , deleteSettings ) ;
185+
186+ if ( DirectoryExists ( resourceDestination ) )
187+ DeleteDirectory ( resourceDestination , deleteSettings ) ;
188+
189+ CopyDirectory ( frameworkSource , frameworkDestination ) ;
190+ CopyDirectory ( resourceSource , resourceDestination ) ;
191+ } ) ;
192+ }
193+
129194void GoogleAppMeasurementDownload ( )
130195{
131196 var source = ExternalDownloads [ "GoogleAppMeasurement" ] ;
0 commit comments