diff --git a/Objective-C/PodServingExample/PodServingExample.xcodeproj/project.pbxproj b/Objective-C/PodServingExample/PodServingExample.xcodeproj/project.pbxproj new file mode 100644 index 0000000..4d41c02 --- /dev/null +++ b/Objective-C/PodServingExample/PodServingExample.xcodeproj/project.pbxproj @@ -0,0 +1,406 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 15C30C501AE6D50500374786 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15C30C4F1AE6D50500374786 /* WebKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 6448425361EA48E76174AD20 /* libPods-PodServingExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 67A5CB9267FA318797AF2829 /* libPods-PodServingExample.a */; }; + A093EE5525D362960020CE6C /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A093EE4C25D362950020CE6C /* AppDelegate.m */; }; + A093EE5625D362960020CE6C /* iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A093EE4D25D362950020CE6C /* iPhone.storyboard */; }; + A093EE5725D362960020CE6C /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A093EE4F25D362950020CE6C /* Images.xcassets */; }; + A093EE5925D362960020CE6C /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A093EE5225D362950020CE6C /* ViewController.m */; }; + A093EE5A25D362960020CE6C /* iPad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A093EE5325D362950020CE6C /* iPad.storyboard */; }; + A093EE5B25D362960020CE6C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = A093EE5425D362960020CE6C /* main.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 1569505F1D5BC117006BEC0A /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 1; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1589E157199126CA00E5DF1A /* PodServingExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PodServingExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 15C30C4F1AE6D50500374786 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; + 5A535E923F1837B20E6528B0 /* Pods-PodServingExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PodServingExample.debug.xcconfig"; path = "Target Support Files/Pods-PodServingExample/Pods-PodServingExample.debug.xcconfig"; sourceTree = ""; }; + 67A5CB9267FA318797AF2829 /* libPods-PodServingExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-PodServingExample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 9D11373354A647400A7EC539 /* Pods-PodServingExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PodServingExample.release.xcconfig"; path = "Target Support Files/Pods-PodServingExample/Pods-PodServingExample.release.xcconfig"; sourceTree = ""; }; + A093EE4B25D362950020CE6C /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + A093EE4C25D362950020CE6C /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + A093EE4E25D362950020CE6C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/iPhone.storyboard; sourceTree = ""; }; + A093EE4F25D362950020CE6C /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + A093EE5025D362950020CE6C /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + A093EE5125D362950020CE6C /* ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; + A093EE5225D362950020CE6C /* ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; + A093EE5325D362950020CE6C /* iPad.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = iPad.storyboard; sourceTree = ""; }; + A093EE5425D362960020CE6C /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1589E154199126CA00E5DF1A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 15C30C501AE6D50500374786 /* WebKit.framework in Frameworks */, + 6448425361EA48E76174AD20 /* libPods-PodServingExample.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 02733AA8386749E688D4F7A2 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 15C30C4F1AE6D50500374786 /* WebKit.framework */, + 67A5CB9267FA318797AF2829 /* libPods-PodServingExample.a */, + ); + name = Frameworks; + sourceTree = ""; + }; + 152D49DE19B10DA0003400E4 /* Resources */ = { + isa = PBXGroup; + children = ( + ); + name = Resources; + sourceTree = ""; + }; + 1589E14E199126CA00E5DF1A = { + isa = PBXGroup; + children = ( + A093EE4A25D362950020CE6C /* app */, + 152D49DE19B10DA0003400E4 /* Resources */, + 1589E158199126CA00E5DF1A /* Products */, + 02733AA8386749E688D4F7A2 /* Frameworks */, + EB97DD51877C44BF44746331 /* Pods */, + ); + sourceTree = ""; + }; + 1589E158199126CA00E5DF1A /* Products */ = { + isa = PBXGroup; + children = ( + 1589E157199126CA00E5DF1A /* PodServingExample.app */, + ); + name = Products; + sourceTree = ""; + }; + A093EE4A25D362950020CE6C /* app */ = { + isa = PBXGroup; + children = ( + A093EE4B25D362950020CE6C /* AppDelegate.h */, + A093EE4C25D362950020CE6C /* AppDelegate.m */, + A093EE4D25D362950020CE6C /* iPhone.storyboard */, + A093EE4F25D362950020CE6C /* Images.xcassets */, + A093EE5025D362950020CE6C /* Info.plist */, + A093EE5125D362950020CE6C /* ViewController.h */, + A093EE5225D362950020CE6C /* ViewController.m */, + A093EE5325D362950020CE6C /* iPad.storyboard */, + A093EE5425D362960020CE6C /* main.m */, + ); + path = app; + sourceTree = ""; + }; + EB97DD51877C44BF44746331 /* Pods */ = { + isa = PBXGroup; + children = ( + 5A535E923F1837B20E6528B0 /* Pods-PodServingExample.debug.xcconfig */, + 9D11373354A647400A7EC539 /* Pods-PodServingExample.release.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1589E156199126CA00E5DF1A /* PodServingExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1589E177199126CA00E5DF1A /* Build configuration list for PBXNativeTarget "PodServingExample" */; + buildPhases = ( + 8A940E7DA69DF3FC0A545EEB /* [CP] Check Pods Manifest.lock */, + 1589E153199126CA00E5DF1A /* Sources */, + 1589E154199126CA00E5DF1A /* Frameworks */, + 1589E155199126CA00E5DF1A /* Resources */, + 1569505F1D5BC117006BEC0A /* Embed Frameworks */, + A5531F6D4D7927280D7F52CF /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = PodServingExample; + productName = PodServingExample; + productReference = 1589E157199126CA00E5DF1A /* PodServingExample.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 1589E14F199126CA00E5DF1A /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0600; + ORGANIZATIONNAME = "Google, Inc."; + TargetAttributes = { + 1589E156199126CA00E5DF1A = { + CreatedOnToolsVersion = 6.0; + }; + }; + }; + buildConfigurationList = 1589E152199126CA00E5DF1A /* Build configuration list for PBXProject "PodServingExample" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + English, + en, + Base, + ); + mainGroup = 1589E14E199126CA00E5DF1A; + productRefGroup = 1589E158199126CA00E5DF1A /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1589E156199126CA00E5DF1A /* PodServingExample */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1589E155199126CA00E5DF1A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A093EE5A25D362960020CE6C /* iPad.storyboard in Resources */, + A093EE5625D362960020CE6C /* iPhone.storyboard in Resources */, + A093EE5725D362960020CE6C /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 8A940E7DA69DF3FC0A545EEB /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-PodServingExample-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + A5531F6D4D7927280D7F52CF /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-PodServingExample/Pods-PodServingExample-frameworks.sh", + "${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleAds-IMA-iOS-SDK/GoogleInteractiveMediaAds.framework/GoogleInteractiveMediaAds", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleInteractiveMediaAds.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-PodServingExample/Pods-PodServingExample-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1589E153199126CA00E5DF1A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A093EE5925D362960020CE6C /* ViewController.m in Sources */, + A093EE5B25D362960020CE6C /* main.m in Sources */, + A093EE5525D362960020CE6C /* AppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + A093EE4D25D362950020CE6C /* iPhone.storyboard */ = { + isa = PBXVariantGroup; + children = ( + A093EE4E25D362950020CE6C /* Base */, + ); + name = iPhone.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1589E175199126CA00E5DF1A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.4; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 1589E176199126CA00E5DF1A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.4; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 1589E178199126CA00E5DF1A /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 5A535E923F1837B20E6528B0 /* Pods-PodServingExample.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + INFOPLIST_FILE = "$(SRCROOT)/app/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + OTHER_LDFLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.ima.PodServingExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 1589E179199126CA00E5DF1A /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9D11373354A647400A7EC539 /* Pods-PodServingExample.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + INFOPLIST_FILE = "$(SRCROOT)/app/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + OTHER_LDFLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.ima.PodServingExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1589E152199126CA00E5DF1A /* Build configuration list for PBXProject "PodServingExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1589E175199126CA00E5DF1A /* Debug */, + 1589E176199126CA00E5DF1A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1589E177199126CA00E5DF1A /* Build configuration list for PBXNativeTarget "PodServingExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1589E178199126CA00E5DF1A /* Debug */, + 1589E179199126CA00E5DF1A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 1589E14F199126CA00E5DF1A /* Project object */; +} diff --git a/Objective-C/PodServingExample/Podfile b/Objective-C/PodServingExample/Podfile new file mode 100644 index 0000000..34c5edb --- /dev/null +++ b/Objective-C/PodServingExample/Podfile @@ -0,0 +1,7 @@ +source 'https://github.com/CocoaPods/Specs.git' + +platform :ios, '14' + +target 'PodServingExample' do + pod 'GoogleAds-IMA-iOS-SDK' +end diff --git a/Objective-C/PodServingExample/app/AppDelegate.h b/Objective-C/PodServingExample/app/AppDelegate.h new file mode 100644 index 0000000..bc09789 --- /dev/null +++ b/Objective-C/PodServingExample/app/AppDelegate.h @@ -0,0 +1,20 @@ +// Copyright 2024 Google LLC. All rights reserved. +// +// +// 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 + +@interface AppDelegate : UIResponder + +@property(nonatomic, strong) UIWindow *window; + +@end diff --git a/Objective-C/PodServingExample/app/AppDelegate.m b/Objective-C/PodServingExample/app/AppDelegate.m new file mode 100644 index 0000000..aeb0f4b --- /dev/null +++ b/Objective-C/PodServingExample/app/AppDelegate.m @@ -0,0 +1,28 @@ +// Copyright 2024 Google LLC. All rights reserved. +// +// +// 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 "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +@end diff --git a/Objective-C/PodServingExample/app/Base.lproj/iPhone.storyboard b/Objective-C/PodServingExample/app/Base.lproj/iPhone.storyboard new file mode 100644 index 0000000..b610c1a --- /dev/null +++ b/Objective-C/PodServingExample/app/Base.lproj/iPhone.storyboard @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Objective-C/PodServingExample/app/Images.xcassets/AppIcon.appiconset/Contents.json b/Objective-C/PodServingExample/app/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..99174b9 --- /dev/null +++ b/Objective-C/PodServingExample/app/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,93 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Objective-C/PodServingExample/app/Images.xcassets/LaunchImage.launchimage/Contents.json b/Objective-C/PodServingExample/app/Images.xcassets/LaunchImage.launchimage/Contents.json new file mode 100644 index 0000000..6f870a4 --- /dev/null +++ b/Objective-C/PodServingExample/app/Images.xcassets/LaunchImage.launchimage/Contents.json @@ -0,0 +1,51 @@ +{ + "images" : [ + { + "orientation" : "portrait", + "idiom" : "iphone", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "scale" : "2x" + }, + { + "orientation" : "portrait", + "idiom" : "iphone", + "subtype" : "retina4", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "scale" : "2x" + }, + { + "orientation" : "portrait", + "idiom" : "ipad", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "scale" : "1x" + }, + { + "orientation" : "landscape", + "idiom" : "ipad", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "scale" : "1x" + }, + { + "orientation" : "portrait", + "idiom" : "ipad", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "scale" : "2x" + }, + { + "orientation" : "landscape", + "idiom" : "ipad", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Objective-C/PodServingExample/app/Info.plist b/Objective-C/PodServingExample/app/Info.plist new file mode 100644 index 0000000..c73a059 --- /dev/null +++ b/Objective-C/PodServingExample/app/Info.plist @@ -0,0 +1,47 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + UIMainStoryboardFile + iPhone + UIMainStoryboardFile~ipad + iPad + UIRequiredDeviceCapabilities + + arm64 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Objective-C/PodServingExample/app/ViewController.h b/Objective-C/PodServingExample/app/ViewController.h new file mode 100644 index 0000000..53ac23f --- /dev/null +++ b/Objective-C/PodServingExample/app/ViewController.h @@ -0,0 +1,18 @@ +// Copyright 2024 Google LLC. All rights reserved. +// +// +// 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 + +@interface ViewController : UIViewController + +@end diff --git a/Objective-C/PodServingExample/app/ViewController.m b/Objective-C/PodServingExample/app/ViewController.m new file mode 100644 index 0000000..c529032 --- /dev/null +++ b/Objective-C/PodServingExample/app/ViewController.m @@ -0,0 +1,205 @@ +// Copyright 2024 Google LLC. All rights reserved. +// +// +// 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 "ViewController.h" + +#import + +@import GoogleInteractiveMediaAds; + +typedef enum {liveStream, vodStream} streamType; +/// Specifies the ad pod stream type; either `liveStream` or `vodStream`. +static streamType const kRequestType = liveStream; +/// Google Ad Manager network code. +static NSString *const kNetworkCode = @""; +/// Livestream custom asset key. +static NSString *const kCustomAssetKey = @""; +/// Returns the stream manifest URL from the video technical partner or manifest manipulator. +static NSString *(^gCustomVTPParser)(NSString *) = ^(NSString *streamID) { + // Insert synchronous code here to retrieve a stream manifest URL from your video tech partner + // or manifest manipulation server. + NSString *manifestUrl = @""; + return manifestUrl; +}; + +/// Fallback URL in case something goes wrong in loading the stream. If all goes well, this will not +/// be used. +static NSString *const kBackupStreamURLString = @""; + +@interface ViewController () + +/// Content video player. +@property(nonatomic, strong) AVPlayer *contentPlayer; + +// UI +/// Play button. +@property(nonatomic, weak) IBOutlet UIButton *playButton; +/// UIView in which we will render our AVPlayer for content. +@property(nonatomic, weak) IBOutlet UIView *videoView; + +// SDK +/// Entry point for the SDK. Used to make ad requests. +@property(nonatomic, strong) IMAAdsLoader *adsLoader; +/// Main point of interaction with the SDK. Created by the SDK as the result of an ad request. +@property(nonatomic, strong) IMAStreamManager *streamManager; +/// Video display used by the SDK to play ads. +@property(nonatomic, strong) id videoDisplay; + +@end + +@implementation ViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + self.playButton.layer.zPosition = MAXFLOAT; + + [self setupAdsLoader]; + [self setUpContentPlayer]; +} + +- (IBAction)onPlayButtonTouch:(id)sender { + [self requestStream]; + self.playButton.hidden = YES; +} + +#pragma mark Content Player Setup + +- (void)setUpContentPlayer { + // Load AVPlayer with path to our content. + NSURL *contentURL = [NSURL URLWithString:kBackupStreamURLString]; + self.contentPlayer = [AVPlayer playerWithURL:contentURL]; + + // Create a player layer for the player. + AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.contentPlayer]; + + // Size, position, and display the AVPlayer. + playerLayer.frame = self.videoView.layer.bounds; + [self.videoView.layer addSublayer:playerLayer]; +} + +#pragma mark SDK Setup + +- (void)setupAdsLoader { + self.adsLoader = [[IMAAdsLoader alloc] initWithSettings:nil]; + self.adsLoader.delegate = self; +} + +- (void)requestStream { + // Create an ad display container for ad rendering. + IMAAdDisplayContainer *adDisplayContainer = + [[IMAAdDisplayContainer alloc] initWithAdContainer:self.videoView + viewController:self + companionSlots:nil]; + // Create an IMAAVPlayerVideoDisplay to give the SDK access to your video player. + self.videoDisplay = + [[IMAAVPlayerVideoDisplay alloc] initWithAVPlayer:self.contentPlayer]; + IMAStreamRequest *request; + if (kRequestType == liveStream) { + // Create a pod serving request for a livestream. + request = [[IMAPodStreamRequest alloc] initWithNetworkCode:kNetworkCode + customAssetKey:kCustomAssetKey + adDisplayContainer:adDisplayContainer + videoDisplay:self.videoDisplay + pictureInPictureProxy:nil + userContext:nil]; + } else { + // Create a pod serving request for a VOD stream. + request = [[IMAPodVODStreamRequest alloc] initWithNetworkCode:kNetworkCode + adDisplayContainer:adDisplayContainer + videoDisplay:self.videoDisplay + pictureInPictureProxy:nil + userContext:nil]; + } + [self.adsLoader requestStreamWithRequest:request]; +} + +#pragma mark AdsLoader Delegates + +- (void)adsLoader:(IMAAdsLoader *)loader adsLoadedWithData:(IMAAdsLoadedData *)adsLoadedData { + // Initialize and listen to stream manager's events. + self.streamManager = adsLoadedData.streamManager; + // The stream manager must be initialized before playback for adsRenderingSettings to be + // respected. + [self.streamManager initializeWithAdsRenderingSettings:nil]; + self.streamManager.delegate = self; + + // Build the Pod serving Stream URL and load into AVPlayer + NSString *streamId = adsLoadedData.streamManager.streamId; + NSString *urlString = gCustomVTPParser(streamId); + NSURL *streamUrl = [NSURL URLWithString:urlString]; + if (kRequestType == liveStream) { + [self.videoDisplay loadStream:streamUrl withSubtitles:@[]]; + [self.videoDisplay play]; + } else { + [self.streamManager loadThirdPartyStream:streamUrl streamSubtitles:@[]]; + // There is no need to trigger playback here. + // streamManager.loadThirdPartyStream will load the stream, request metadata, and play + } + NSLog(@"Stream created with: %@.", self.streamManager.streamId); +} + +- (void)adsLoader:(IMAAdsLoader *)loader failedWithErrorData:(IMAAdLoadingErrorData *)adErrorData { + // Something went wrong loading ads. Log the error and play the content. + NSLog(@"AdsLoader error, code:%ld, message: %@", adErrorData.adError.code, + adErrorData.adError.message); + [self.contentPlayer play]; +} + +#pragma mark StreamManager Delegates + +- (void)streamManager:(IMAStreamManager *)streamManager didReceiveAdEvent:(IMAAdEvent *)event { + NSLog(@"StreamManager event (%@).", event.typeString); + switch (event.type) { + case kIMAAdEvent_STARTED: { + // Log extended data. + NSString *extendedAdPodInfo = [[NSString alloc] + initWithFormat:@"Showing ad %ld/%ld, bumper: %@, title: %@, description: %@, contentType:" + @"%@, pod index: %ld, time offset: %lf, max duration: %lf.", + (long)event.ad.adPodInfo.adPosition, (long)event.ad.adPodInfo.totalAds, + event.ad.adPodInfo.isBumper ? @"YES" : @"NO", event.ad.adTitle, + event.ad.adDescription, event.ad.contentType, + (long)event.ad.adPodInfo.podIndex, event.ad.adPodInfo.timeOffset, + event.ad.adPodInfo.maxDuration]; + + NSLog(@"%@", extendedAdPodInfo); + break; + } + case kIMAAdEvent_AD_BREAK_STARTED: { + NSLog(@"Ad break started"); + break; + } + case kIMAAdEvent_AD_BREAK_ENDED: { + NSLog(@"Ad break ended"); + break; + } + case kIMAAdEvent_AD_PERIOD_STARTED: { + NSLog(@"Ad period started"); + break; + } + case kIMAAdEvent_AD_PERIOD_ENDED: { + NSLog(@"Ad period ended"); + break; + } + default: + break; + } +} + +- (void)streamManager:(IMAStreamManager *)streamManager didReceiveAdError:(IMAAdError *)error { + NSLog(@"StreamManager error with type: %ld\ncode: %ld\nmessage: %@", error.type, error.code, + error.message); + [self.contentPlayer play]; +} + +@end diff --git a/Objective-C/PodServingExample/app/iPad.storyboard b/Objective-C/PodServingExample/app/iPad.storyboard new file mode 100644 index 0000000..9b97708 --- /dev/null +++ b/Objective-C/PodServingExample/app/iPad.storyboard @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Objective-C/PodServingExample/app/main.m b/Objective-C/PodServingExample/app/main.m new file mode 100644 index 0000000..effb88a --- /dev/null +++ b/Objective-C/PodServingExample/app/main.m @@ -0,0 +1,22 @@ +// Copyright 2024 Google LLC. All rights reserved. +// +// +// 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 + +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +}