diff --git a/PrebidMobile.xcodeproj/project.pbxproj b/PrebidMobile.xcodeproj/project.pbxproj index dc8ac5ae8..c859a4954 100644 --- a/PrebidMobile.xcodeproj/project.pbxproj +++ b/PrebidMobile.xcodeproj/project.pbxproj @@ -115,6 +115,9 @@ 53CE09012AD673020018CB75 /* sample_ortb_native_with_win_event.json in Resources */ = {isa = PBXBuildFile; fileRef = 53CE09002AD673020018CB75 /* sample_ortb_native_with_win_event.json */; }; 53CE09032AD67ECE0018CB75 /* MockPBMBidRequester.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53CE09022AD67ECE0018CB75 /* MockPBMBidRequester.swift */; }; 53CF5B3729DC690600613E84 /* VideoAdUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53CF5B3629DC690600613E84 /* VideoAdUnit.swift */; }; + 53D3C3882C2BEE1E0074D99B /* URL+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53D3C3872C2BEE1E0074D99B /* URL+Extensions.swift */; }; + 53D3C38D2C2BEF9B0074D99B /* NSURL+PBMExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 53D3C38C2C2BEF9B0074D99B /* NSURL+PBMExtensions.m */; }; + 53D3C38E2C2BEF9B0074D99B /* NSURL+PBMExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 53D3C38B2C2BEF9B0074D99B /* NSURL+PBMExtensions.h */; }; 53D934FF282CE62E0092E243 /* AgeUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53D934FE282CE62E0092E243 /* AgeUtils.swift */; }; 53D93505282CEA900092E243 /* DateFormatService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53D93504282CEA900092E243 /* DateFormatService.swift */; }; 53E3910E27FCD60800DBA2F7 /* VideoParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53E3910D27FCD60800DBA2F7 /* VideoParameters.swift */; }; @@ -963,6 +966,9 @@ 53CE09002AD673020018CB75 /* sample_ortb_native_with_win_event.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = sample_ortb_native_with_win_event.json; sourceTree = ""; }; 53CE09022AD67ECE0018CB75 /* MockPBMBidRequester.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockPBMBidRequester.swift; sourceTree = ""; }; 53CF5B3629DC690600613E84 /* VideoAdUnit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoAdUnit.swift; sourceTree = ""; }; + 53D3C3872C2BEE1E0074D99B /* URL+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+Extensions.swift"; sourceTree = ""; }; + 53D3C38B2C2BEF9B0074D99B /* NSURL+PBMExtensions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSURL+PBMExtensions.h"; sourceTree = ""; }; + 53D3C38C2C2BEF9B0074D99B /* NSURL+PBMExtensions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSURL+PBMExtensions.m"; sourceTree = ""; }; 53D934FE282CE62E0092E243 /* AgeUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AgeUtils.swift; sourceTree = ""; }; 53D93504282CEA900092E243 /* DateFormatService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateFormatService.swift; sourceTree = ""; }; 53E3910D27FCD60800DBA2F7 /* VideoParameters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoParameters.swift; sourceTree = ""; }; @@ -1861,6 +1867,7 @@ 34C9CD5E2850CE6300FB5451 /* OMSDKVersionProvider.m */, 53F35F6E292BAE9B001C1183 /* UserDefaults+Extensions.swift */, 53842BBB29E565030069A4B7 /* NSString+Extensions.swift */, + 53D3C3872C2BEE1E0074D99B /* URL+Extensions.swift */, ); path = Utils; sourceTree = ""; @@ -1955,6 +1962,8 @@ 5BC3765E271F1CFD00444D5E /* UIWindow+PBMExtensions.h */, 5BC3766F271F1CFD00444D5E /* UIWindow+PBMExtensions.m */, 53C925012990FB30009E6F94 /* String+Extensions.swift */, + 53D3C38B2C2BEF9B0074D99B /* NSURL+PBMExtensions.h */, + 53D3C38C2C2BEF9B0074D99B /* NSURL+PBMExtensions.m */, ); path = ExtensionsAndWrappers; sourceTree = ""; @@ -3360,6 +3369,7 @@ 5BC37A66271F1D0000444D5E /* PBMORTBBidExtSkadn.h in Headers */, 5BC37AD7271F1D0100444D5E /* PBMUserConsentParameterBuilder.h in Headers */, 5BC37964271F1D0000444D5E /* PBMVastResponse.h in Headers */, + 53D3C38E2C2BEF9B0074D99B /* NSURL+PBMExtensions.h in Headers */, 5BC379CC271F1D0000444D5E /* PBMAdLoadManagerVAST.h in Headers */, 5BC37985271F1D0000444D5E /* PBMMRAIDController.h in Headers */, 5BC3790F271F1CFF00444D5E /* PBMDeviceAccessManager.h in Headers */, @@ -3963,6 +3973,7 @@ 9236A650272FEC5A00ABBEF4 /* ImpressionTask.swift in Sources */, 5BC37A97271F1D0000444D5E /* InterstitialEventHandlerProtocol.swift in Sources */, 5BC379F3271F1D0000444D5E /* PBMExternalLinkHandler.m in Sources */, + 53D3C38D2C2BEF9B0074D99B /* NSURL+PBMExtensions.m in Sources */, 5BC379AD271F1D0000444D5E /* PBMTransaction.m in Sources */, 53269D55282E6D0F0098550D /* ServerEvent.swift in Sources */, 5BC37A5E271F1D0000444D5E /* PBMORTBBidResponseExt.m in Sources */, @@ -4190,6 +4201,7 @@ 5BC37961271F1D0000444D5E /* PBMVastAdsBuilder.m in Sources */, 5BC37A91271F1D0000444D5E /* InterstitialEventLoadingDelegate.swift in Sources */, 530382F2283197E100B2B111 /* PrebidServerResponse.swift in Sources */, + 53D3C3882C2BEE1E0074D99B /* URL+Extensions.swift in Sources */, 5BC3792F271F1D0000444D5E /* PBMDeviceAccessManager.m in Sources */, 5BC37A6E271F1D0000444D5E /* PBMORTBBidResponse.m in Sources */, 5BC37ACE271F1D0100444D5E /* PBMGeoLocationParameterBuilder.m in Sources */, diff --git a/PrebidMobile/Host.swift b/PrebidMobile/Host.swift index ca0dc8223..06fb571bc 100644 --- a/PrebidMobile/Host.swift +++ b/PrebidMobile/Host.swift @@ -57,7 +57,7 @@ public class Host: NSObject { */ @objc public func setCustomHostURL(_ urlString: String?) throws { - guard let url = URL(string: urlString!) else { + guard let url = URL.urlWithoutEncoding(from: urlString) else { throw ErrorCode.prebidServerURLInvalid(urlString ?? "") } customHostURL = url diff --git a/PrebidMobile/PrebidMobileRendering/AdTypes/AdView/PBMMRAIDController.m b/PrebidMobile/PrebidMobileRendering/AdTypes/AdView/PBMMRAIDController.m index e941e5c64..32f827d3b 100644 --- a/PrebidMobile/PrebidMobileRendering/AdTypes/AdView/PBMMRAIDController.m +++ b/PrebidMobile/PrebidMobileRendering/AdTypes/AdView/PBMMRAIDController.m @@ -20,6 +20,7 @@ #import "NSException+PBMExtensions.h" #import "NSString+PBMExtensions.h" #import "UIView+PBMExtensions.h" +#import "NSURL+PBMExtensions.h" #import "PBMAbstractCreative.h" #import "PBMCreativeModel.h" @@ -277,7 +278,7 @@ - (void)handleMRAIDCommandOpen:(PBMMRAIDCommand *)command { @throw [NSException pbmException:@"No arguments to MRAID.open()"]; } - NSURL *url = [NSURL URLWithString:strURL]; + NSURL *url = [NSURL PBMURLWithoutEncodingFromString:strURL]; if (!url) { @throw [NSException pbmException:[NSString stringWithFormat:@"Could not create URL from string: %@", strURL]]; } @@ -323,7 +324,7 @@ - (void)handleMRAIDCommandExpand:(PBMMRAIDCommand *)command originURL:(NSURL *)u NSString *strExpandURL = [[command.arguments firstObject] stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet]; if (strExpandURL && ![strExpandURL isEqualToString:@""]) { //Epanding to a URL - NSURL *expandURL = [NSURL URLWithString:strExpandURL]; + NSURL *expandURL = [NSURL PBMURLWithoutEncodingFromString:strExpandURL]; if (!expandURL) { PBMLogError(@"Could not create expand url to: %@", strExpandURL); return; @@ -532,7 +533,7 @@ - (void)handleMRAIDCommandPlayVideo:(PBMMRAIDCommand *)command { @throw [NSException pbmException:@"Insufficient arguments for MRAIDAction.playVideo"]; } - NSURL *url = [NSURL URLWithString:strURL]; + NSURL *url = [NSURL PBMURLWithoutEncodingFromString:strURL]; if (!url) { NSString *message = [NSString stringWithFormat:@"MRAID attempted to load an invalid URL: %@", strURL]; @throw [NSException pbmException:message]; diff --git a/PrebidMobile/PrebidMobileRendering/ExtensionsAndWrappers/NSURL+PBMExtensions.h b/PrebidMobile/PrebidMobileRendering/ExtensionsAndWrappers/NSURL+PBMExtensions.h new file mode 100644 index 000000000..ace33cb9c --- /dev/null +++ b/PrebidMobile/PrebidMobileRendering/ExtensionsAndWrappers/NSURL+PBMExtensions.h @@ -0,0 +1,26 @@ +/*   Copyright 2018-2024 Prebid.org, Inc. + +  Licensed under the Apache License, Version 2.0 (the "License"); +  you may not use this file except in compliance with the License. +  You may obtain a copy of the License at + +  http://www.apache.org/licenses/LICENSE-2.0 + +  Unless required by applicable law or agreed to in writing, software +  distributed under the License is distributed on an "AS IS" BASIS, +  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +  See the License for the specific language governing permissions and +  limitations under the License. +  */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NSURL (PBMExtensions) + ++ (NSURL *)PBMURLWithoutEncodingFromString:(NSString *)str; + +@end + +NS_ASSUME_NONNULL_END diff --git a/PrebidMobile/PrebidMobileRendering/ExtensionsAndWrappers/NSURL+PBMExtensions.m b/PrebidMobile/PrebidMobileRendering/ExtensionsAndWrappers/NSURL+PBMExtensions.m new file mode 100644 index 000000000..ad2f97ae2 --- /dev/null +++ b/PrebidMobile/PrebidMobileRendering/ExtensionsAndWrappers/NSURL+PBMExtensions.m @@ -0,0 +1,32 @@ +/*   Copyright 2018-2024 Prebid.org, Inc. + +  Licensed under the Apache License, Version 2.0 (the "License"); +  you may not use this file except in compliance with the License. +  You may obtain a copy of the License at + +  http://www.apache.org/licenses/LICENSE-2.0 + +  Unless required by applicable law or agreed to in writing, software +  distributed under the License is distributed on an "AS IS" BASIS, +  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +  See the License for the specific language governing permissions and +  limitations under the License. +  */ + +#import "NSURL+PBMExtensions.h" + +@implementation NSURL (PBMExtensions) + ++ (NSURL *)PBMURLWithoutEncodingFromString:(NSString *)str { + if (!str) { + return nil; + } + + if (@available(iOS 17.0, *)) { + return [NSURL URLWithString:str encodingInvalidCharacters:NO]; + } else { + return [NSURL URLWithString:str]; + } +} + +@end diff --git a/PrebidMobile/PrebidMobileRendering/Networking/PrebidServerConnection.swift b/PrebidMobile/PrebidMobileRendering/Networking/PrebidServerConnection.swift index e2f1278fb..1507f6c83 100644 --- a/PrebidMobile/PrebidMobileRendering/Networking/PrebidServerConnection.swift +++ b/PrebidMobile/PrebidMobileRendering/Networking/PrebidServerConnection.swift @@ -232,7 +232,7 @@ public class PrebidServerConnection: NSObject, PrebidServerConnectionProtocol, U return nil } - guard let url = URL(string: strUrl) else { + guard let url = URL.urlWithoutEncoding(from: strUrl) else { Log.error("URL creation failed for string: \(strUrl)") return nil } diff --git a/PrebidMobile/PrebidMobileRendering/Utilities/PBMDeepLinkPlus.m b/PrebidMobile/PrebidMobileRendering/Utilities/PBMDeepLinkPlus.m index 2912252fe..a9a291ad5 100644 --- a/PrebidMobile/PrebidMobileRendering/Utilities/PBMDeepLinkPlus.m +++ b/PrebidMobile/PrebidMobileRendering/Utilities/PBMDeepLinkPlus.m @@ -14,6 +14,7 @@  */ #import "PBMDeepLinkPlus.h" +#import "NSURL+PBMExtensions.h" @interface PBMDeepLinkPlus() @@ -48,7 +49,7 @@ - (BOOL)parseURL:(NSURL * _Nonnull)url { for (NSURLQueryItem *queryItem in queryItems) { NSString *key = queryItem.name; - NSURL *valueURL = [NSURL URLWithString:queryItem.value]; + NSURL *valueURL = [NSURL PBMURLWithoutEncodingFromString:queryItem.value]; if (valueURL != nil) { if ([key isEqualToString:@"primaryUrl"]) { if (self.primaryURL == nil) { diff --git a/PrebidMobile/PrebidMobileRendering/Utilities/PBMDeviceAccessManager.m b/PrebidMobile/PrebidMobileRendering/Utilities/PBMDeviceAccessManager.m index 345a06280..ae22c778a 100644 --- a/PrebidMobile/PrebidMobileRendering/Utilities/PBMDeviceAccessManager.m +++ b/PrebidMobile/PrebidMobileRendering/Utilities/PBMDeviceAccessManager.m @@ -92,7 +92,11 @@ - (nullable NSString *)platformString { } - (nullable NSString *)userLangaugeCode { - return [self.locale objectForKey:NSLocaleLanguageCode]; + NSString * languageCode = [self.locale objectForKey:NSLocaleLanguageCode]; + if (languageCode.length == 0) { + return nil; + } + return languageCode; } #pragma mark - IDFA diff --git a/PrebidMobile/Utils/URL+Extensions.swift b/PrebidMobile/Utils/URL+Extensions.swift new file mode 100644 index 000000000..1914c67a3 --- /dev/null +++ b/PrebidMobile/Utils/URL+Extensions.swift @@ -0,0 +1,31 @@ +/*   Copyright 2018-2024 Prebid.org, Inc. + +  Licensed under the Apache License, Version 2.0 (the "License"); +  you may not use this file except in compliance with the License. +  You may obtain a copy of the License at + +  http://www.apache.org/licenses/LICENSE-2.0 + +  Unless required by applicable law or agreed to in writing, software +  distributed under the License is distributed on an "AS IS" BASIS, +  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +  See the License for the specific language governing permissions and +  limitations under the License. +  */ + +import Foundation + +extension URL { + + static func urlWithoutEncoding(from str: String?) -> URL? { + guard let str = str else { + return nil + } + + if #available(iOS 17.0, *) { + return URL(string: str, encodingInvalidCharacters: false) + } + + return URL(string: str) + } +}