diff --git a/.DS_Store b/.DS_Store index fecbc67..ddaef51 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/FacebookAdapter.podspec b/FacebookAdapter.podspec new file mode 100644 index 0000000..8d07d77 --- /dev/null +++ b/FacebookAdapter.podspec @@ -0,0 +1,97 @@ + + +Pod::Spec.new do |spec| + + + + spec.name = "FacebookAdapter" + spec.version = "0.0.67" + spec.summary = "an adapter for Meta SDK" + spec.description = "an adapter for Meta SDK for MSP S2S" + + spec.homepage = "https://github.com/aimsp/msp-ios-sdk/MetaAdapter" + + spec.license = "Copyright" + + # + + spec.author = { "huanzhiNB" => "huanzhi.zhang@newsbreak.com" } + # Or just: spec.author = "huanzhiNB" + # spec.authors = { "huanzhiNB" => "huanzhi.zhang@newsbreak.com" } + # spec.social_media_url = "https://twitter.com/huanzhiNB" + + # spec.platform = :ios + # spec.platform = :ios, "5.0" + + # When using multiple platforms + # spec.ios.deployment_target = "5.0" + # spec.osx.deployment_target = "10.7" + # spec.watchos.deployment_target = "2.0" + # spec.tvos.deployment_target = "9.0" + # spec.visionos.deployment_target = "1.0" + + + # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # + # + # Specify the location from where the source should be retrieved. + # Supports git, hg, bzr, svn and HTTP. + # + + spec.source = { :git => "https://github.com/huanzhiNB/msp-ios-sdk-public.git", :tag => "#{spec.version}" } + + spec.ios.deployment_target = '13.0' + + + spec.source_files = "FacebookAdapter/FacebookAdapter/**/*.{h,m,swift}" + spec.exclude_files = "Classes/Exclude" + + spec.dependency 'FBAudienceNetwork', '6.15.0' + spec.dependency 'MSPSharedLibraries', '0.0.64' + #spec.module_map = 'GoogleAdapter/GoogleAdapter.modulemap' + + #spec.public_header_files = "GoogleAdapter//**/*.h" + #spec.vendored_frameworks= "GoogleAdapter/shared.xcframework" + + spec.pod_target_xcconfig = { 'VALID_ARCHS' => 'x86_64 armv7 arm64' } + spec.user_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' } + + spec.static_framework = true + # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # + # + # A list of resources included with the Pod. These are copied into the + # target bundle with a build phase script. Anything else will be cleaned. + # You can preserve files from being cleaned, please don't preserve + # non-essential files like tests, examples and documentation. + # + + # spec.resource = "icon.png" + # spec.resources = "Resources/*.png" + + # spec.preserve_paths = "FilesToSave", "MoreFilesToSave" + + + # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # + # + # Link your library with frameworks, or libraries. Libraries do not include + # the lib prefix of their name. + # + + # spec.framework = "SomeFramework" + # spec.frameworks = "SomeFramework", "AnotherFramework" + + # spec.library = "iconv" + # spec.libraries = "iconv", "xml2" + + + # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # + # + # If your library depends on compiler flags you can set them in the xcconfig hash + # where they will only apply to your library. If you depend on other Podspecs + # you can include multiple dependencies to ensure it works. + + # spec.requires_arc = true + + # spec.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } + # spec.dependency "JSONKit", "~> 1.4" + +end diff --git a/FacebookAdapter/.DS_Store b/FacebookAdapter/.DS_Store new file mode 100644 index 0000000..508b6f5 Binary files /dev/null and b/FacebookAdapter/.DS_Store differ diff --git a/FacebookAdapter/FacebookAdapter.xcodeproj/project.pbxproj b/FacebookAdapter/FacebookAdapter.xcodeproj/project.pbxproj new file mode 100644 index 0000000..ae95650 --- /dev/null +++ b/FacebookAdapter/FacebookAdapter.xcodeproj/project.pbxproj @@ -0,0 +1,577 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 56; + objects = { + +/* Begin PBXBuildFile section */ + 038135564898D05ECF9F4DE2 /* libPods-FacebookAdapter.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E08585DBE79311974847A20E /* libPods-FacebookAdapter.a */; }; + 668ACA632CC9B83C00F45803 /* FacebookInterstitialAd.swift in Sources */ = {isa = PBXBuildFile; fileRef = 668ACA622CC9B83C00F45803 /* FacebookInterstitialAd.swift */; }; + 66B730142C2CCB250042E4FF /* FacebookAdapter.docc in Sources */ = {isa = PBXBuildFile; fileRef = 66B730132C2CCB250042E4FF /* FacebookAdapter.docc */; }; + 66B7301A2C2CCB260042E4FF /* FacebookAdapter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66B7300F2C2CCB250042E4FF /* FacebookAdapter.framework */; }; + 66B7301F2C2CCB260042E4FF /* MetaAdapterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66B7301E2C2CCB260042E4FF /* MetaAdapterTests.swift */; }; + 66B730202C2CCB260042E4FF /* FacebookAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 66B730122C2CCB250042E4FF /* FacebookAdapter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 66B7302B2C2CCD390042E4FF /* FacebookAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66B7302A2C2CCD390042E4FF /* FacebookAdapter.swift */; }; + 66B7302F2C2CD10F0042E4FF /* FacebookManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66B7302E2C2CD10F0042E4FF /* FacebookManager.swift */; }; + 66B730322C2CD22F0042E4FF /* FacebookNativeAd.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66B730312C2CD22F0042E4FF /* FacebookNativeAd.swift */; }; + 66B730352C2CDD490042E4FF /* FacebookBidTokenProviderHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66B730342C2CDD490042E4FF /* FacebookBidTokenProviderHelper.swift */; }; + 66B7303B2C2E21D80042E4FF /* FacebookNativeAdView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66B7303A2C2E21D70042E4FF /* FacebookNativeAdView.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 66B7301B2C2CCB260042E4FF /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 66B730062C2CCB250042E4FF /* Project object */; + proxyType = 1; + remoteGlobalIDString = 66B7300E2C2CCB250042E4FF; + remoteInfo = MetaAdapter; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 3D26F55FD54E848B3F19F5D2 /* Pods-FacebookAdapter.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FacebookAdapter.debug.xcconfig"; path = "Target Support Files/Pods-FacebookAdapter/Pods-FacebookAdapter.debug.xcconfig"; sourceTree = ""; }; + 668ACA622CC9B83C00F45803 /* FacebookInterstitialAd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FacebookInterstitialAd.swift; sourceTree = ""; }; + 66B7300F2C2CCB250042E4FF /* FacebookAdapter.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FacebookAdapter.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 66B730122C2CCB250042E4FF /* FacebookAdapter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FacebookAdapter.h; sourceTree = ""; }; + 66B730132C2CCB250042E4FF /* FacebookAdapter.docc */ = {isa = PBXFileReference; lastKnownFileType = folder.documentationcatalog; path = FacebookAdapter.docc; sourceTree = ""; }; + 66B730192C2CCB260042E4FF /* FacebookAdapterTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FacebookAdapterTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 66B7301E2C2CCB260042E4FF /* MetaAdapterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MetaAdapterTests.swift; sourceTree = ""; }; + 66B7302A2C2CCD390042E4FF /* FacebookAdapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FacebookAdapter.swift; sourceTree = ""; }; + 66B7302E2C2CD10F0042E4FF /* FacebookManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FacebookManager.swift; sourceTree = ""; }; + 66B730312C2CD22F0042E4FF /* FacebookNativeAd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FacebookNativeAd.swift; sourceTree = ""; }; + 66B730342C2CDD490042E4FF /* FacebookBidTokenProviderHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FacebookBidTokenProviderHelper.swift; sourceTree = ""; }; + 66B7303A2C2E21D70042E4FF /* FacebookNativeAdView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FacebookNativeAdView.swift; sourceTree = ""; }; + 9A4DFD67DB156BF779DB0500 /* Pods-FacebookAdapter.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FacebookAdapter.release.xcconfig"; path = "Target Support Files/Pods-FacebookAdapter/Pods-FacebookAdapter.release.xcconfig"; sourceTree = ""; }; + C302EF7DCE62B63A460496D8 /* Pods-MetaAdapter.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MetaAdapter.release.xcconfig"; path = "Target Support Files/Pods-MetaAdapter/Pods-MetaAdapter.release.xcconfig"; sourceTree = ""; }; + DBA52CF482851172B9D71194 /* Pods-MetaAdapter.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MetaAdapter.debug.xcconfig"; path = "Target Support Files/Pods-MetaAdapter/Pods-MetaAdapter.debug.xcconfig"; sourceTree = ""; }; + E08585DBE79311974847A20E /* libPods-FacebookAdapter.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-FacebookAdapter.a"; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 66B7300C2C2CCB250042E4FF /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 038135564898D05ECF9F4DE2 /* libPods-FacebookAdapter.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 66B730162C2CCB260042E4FF /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 66B7301A2C2CCB260042E4FF /* FacebookAdapter.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 133385217AEDB45C8CC05C8D /* Pods */ = { + isa = PBXGroup; + children = ( + DBA52CF482851172B9D71194 /* Pods-MetaAdapter.debug.xcconfig */, + C302EF7DCE62B63A460496D8 /* Pods-MetaAdapter.release.xcconfig */, + 3D26F55FD54E848B3F19F5D2 /* Pods-FacebookAdapter.debug.xcconfig */, + 9A4DFD67DB156BF779DB0500 /* Pods-FacebookAdapter.release.xcconfig */, + ); + name = Pods; + path = ../Pods; + sourceTree = ""; + }; + 668ACA612CC9B81800F45803 /* Interstitial */ = { + isa = PBXGroup; + children = ( + 668ACA622CC9B83C00F45803 /* FacebookInterstitialAd.swift */, + ); + path = Interstitial; + sourceTree = ""; + }; + 66B730052C2CCB250042E4FF = { + isa = PBXGroup; + children = ( + 66B730112C2CCB250042E4FF /* FacebookAdapter */, + 66B7301D2C2CCB260042E4FF /* MetaAdapterTests */, + 66B730102C2CCB250042E4FF /* Products */, + 133385217AEDB45C8CC05C8D /* Pods */, + B45356B399B594381AF7DF2C /* Frameworks */, + ); + sourceTree = ""; + }; + 66B730102C2CCB250042E4FF /* Products */ = { + isa = PBXGroup; + children = ( + 66B7300F2C2CCB250042E4FF /* FacebookAdapter.framework */, + 66B730192C2CCB260042E4FF /* FacebookAdapterTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 66B730112C2CCB250042E4FF /* FacebookAdapter */ = { + isa = PBXGroup; + children = ( + 668ACA612CC9B81800F45803 /* Interstitial */, + 66B730302C2CD21B0042E4FF /* Native */, + 66B730122C2CCB250042E4FF /* FacebookAdapter.h */, + 66B730132C2CCB250042E4FF /* FacebookAdapter.docc */, + 66B7302A2C2CCD390042E4FF /* FacebookAdapter.swift */, + 66B7302E2C2CD10F0042E4FF /* FacebookManager.swift */, + 66B730342C2CDD490042E4FF /* FacebookBidTokenProviderHelper.swift */, + ); + path = FacebookAdapter; + sourceTree = ""; + }; + 66B7301D2C2CCB260042E4FF /* MetaAdapterTests */ = { + isa = PBXGroup; + children = ( + 66B7301E2C2CCB260042E4FF /* MetaAdapterTests.swift */, + ); + path = MetaAdapterTests; + sourceTree = ""; + }; + 66B730302C2CD21B0042E4FF /* Native */ = { + isa = PBXGroup; + children = ( + 66B730312C2CD22F0042E4FF /* FacebookNativeAd.swift */, + 66B7303A2C2E21D70042E4FF /* FacebookNativeAdView.swift */, + ); + path = Native; + sourceTree = ""; + }; + B45356B399B594381AF7DF2C /* Frameworks */ = { + isa = PBXGroup; + children = ( + E08585DBE79311974847A20E /* libPods-FacebookAdapter.a */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 66B7300A2C2CCB250042E4FF /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 66B730202C2CCB260042E4FF /* FacebookAdapter.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 66B7300E2C2CCB250042E4FF /* FacebookAdapter */ = { + isa = PBXNativeTarget; + buildConfigurationList = 66B730232C2CCB260042E4FF /* Build configuration list for PBXNativeTarget "FacebookAdapter" */; + buildPhases = ( + 3AF18660FD9BFB492D9077E9 /* [CP] Check Pods Manifest.lock */, + 66B7300A2C2CCB250042E4FF /* Headers */, + 66B7300B2C2CCB250042E4FF /* Sources */, + 66B7300C2C2CCB250042E4FF /* Frameworks */, + 66B7300D2C2CCB250042E4FF /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = FacebookAdapter; + productName = MetaAdapter; + productReference = 66B7300F2C2CCB250042E4FF /* FacebookAdapter.framework */; + productType = "com.apple.product-type.framework"; + }; + 66B730182C2CCB260042E4FF /* FacebookAdapterTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 66B730262C2CCB260042E4FF /* Build configuration list for PBXNativeTarget "FacebookAdapterTests" */; + buildPhases = ( + 66B730152C2CCB260042E4FF /* Sources */, + 66B730162C2CCB260042E4FF /* Frameworks */, + 66B730172C2CCB260042E4FF /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 66B7301C2C2CCB260042E4FF /* PBXTargetDependency */, + ); + name = FacebookAdapterTests; + productName = MetaAdapterTests; + productReference = 66B730192C2CCB260042E4FF /* FacebookAdapterTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 66B730062C2CCB250042E4FF /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1540; + LastUpgradeCheck = 1540; + TargetAttributes = { + 66B7300E2C2CCB250042E4FF = { + CreatedOnToolsVersion = 15.4; + }; + 66B730182C2CCB260042E4FF = { + CreatedOnToolsVersion = 15.4; + }; + }; + }; + buildConfigurationList = 66B730092C2CCB250042E4FF /* Build configuration list for PBXProject "FacebookAdapter" */; + compatibilityVersion = "Xcode 14.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 66B730052C2CCB250042E4FF; + productRefGroup = 66B730102C2CCB250042E4FF /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 66B7300E2C2CCB250042E4FF /* FacebookAdapter */, + 66B730182C2CCB260042E4FF /* FacebookAdapterTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 66B7300D2C2CCB250042E4FF /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 66B730172C2CCB260042E4FF /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3AF18660FD9BFB492D9077E9 /* [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-FacebookAdapter-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; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 66B7300B2C2CCB250042E4FF /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 66B730322C2CD22F0042E4FF /* FacebookNativeAd.swift in Sources */, + 66B7302F2C2CD10F0042E4FF /* FacebookManager.swift in Sources */, + 66B7302B2C2CCD390042E4FF /* FacebookAdapter.swift in Sources */, + 66B730352C2CDD490042E4FF /* FacebookBidTokenProviderHelper.swift in Sources */, + 668ACA632CC9B83C00F45803 /* FacebookInterstitialAd.swift in Sources */, + 66B730142C2CCB250042E4FF /* FacebookAdapter.docc in Sources */, + 66B7303B2C2E21D80042E4FF /* FacebookNativeAdView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 66B730152C2CCB260042E4FF /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 66B7301F2C2CCB260042E4FF /* MetaAdapterTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 66B7301C2C2CCB260042E4FF /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 66B7300E2C2CCB250042E4FF /* FacebookAdapter */; + targetProxy = 66B7301B2C2CCB260042E4FF /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 66B730212C2CCB260042E4FF /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + 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.5; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 66B730222C2CCB260042E4FF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + 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.5; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 66B730242C2CCB260042E4FF /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 3D26F55FD54E848B3F19F5D2 /* Pods-FacebookAdapter.debug.xcconfig */; + buildSettings = { + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = 4PEHUZX8QH; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; + PRODUCT_BUNDLE_IDENTIFIER = msp.FacebookAdapter; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_INSTALL_OBJC_HEADER = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 66B730252C2CCB260042E4FF /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9A4DFD67DB156BF779DB0500 /* Pods-FacebookAdapter.release.xcconfig */; + buildSettings = { + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = 4PEHUZX8QH; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; + PRODUCT_BUNDLE_IDENTIFIER = msp.FacebookAdapter; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_INSTALL_OBJC_HEADER = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 66B730272C2CCB260042E4FF /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 4PEHUZX8QH; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = msp.MetaAdapterTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 66B730282C2CCB260042E4FF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 4PEHUZX8QH; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = msp.MetaAdapterTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 66B730092C2CCB250042E4FF /* Build configuration list for PBXProject "FacebookAdapter" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 66B730212C2CCB260042E4FF /* Debug */, + 66B730222C2CCB260042E4FF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 66B730232C2CCB260042E4FF /* Build configuration list for PBXNativeTarget "FacebookAdapter" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 66B730242C2CCB260042E4FF /* Debug */, + 66B730252C2CCB260042E4FF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 66B730262C2CCB260042E4FF /* Build configuration list for PBXNativeTarget "FacebookAdapterTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 66B730272C2CCB260042E4FF /* Debug */, + 66B730282C2CCB260042E4FF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 66B730062C2CCB250042E4FF /* Project object */; +} diff --git a/FacebookAdapter/FacebookAdapter.xcodeproj/xcuserdata/huanzhizhang.xcuserdatad/xcschemes/xcschememanagement.plist b/FacebookAdapter/FacebookAdapter.xcodeproj/xcuserdata/huanzhizhang.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..edfe7e8 --- /dev/null +++ b/FacebookAdapter/FacebookAdapter.xcodeproj/xcuserdata/huanzhizhang.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,19 @@ + + + + + SchemeUserState + + FacebookAdapter.xcscheme_^#shared#^_ + + orderHint + 33 + + MetaAdapter.xcscheme_^#shared#^_ + + orderHint + 33 + + + + diff --git a/FacebookAdapter/FacebookAdapter/.DS_Store b/FacebookAdapter/FacebookAdapter/.DS_Store new file mode 100644 index 0000000..304f64c Binary files /dev/null and b/FacebookAdapter/FacebookAdapter/.DS_Store differ diff --git a/FacebookAdapter/FacebookAdapter/FacebookAdapter.docc/.DS_Store b/FacebookAdapter/FacebookAdapter/FacebookAdapter.docc/.DS_Store new file mode 100644 index 0000000..2669ebf Binary files /dev/null and b/FacebookAdapter/FacebookAdapter/FacebookAdapter.docc/.DS_Store differ diff --git a/FacebookAdapter/FacebookAdapter/FacebookAdapter.docc/FacebookAdapter.md b/FacebookAdapter/FacebookAdapter/FacebookAdapter.docc/FacebookAdapter.md new file mode 100755 index 0000000..9bc1765 --- /dev/null +++ b/FacebookAdapter/FacebookAdapter/FacebookAdapter.docc/FacebookAdapter.md @@ -0,0 +1,13 @@ +# ``FacebookAdapter`` + +Summary + +## Overview + +Text + +## Topics + +### Group + +- ``Symbol`` diff --git a/FacebookAdapter/FacebookAdapter/FacebookAdapter.h b/FacebookAdapter/FacebookAdapter/FacebookAdapter.h new file mode 100644 index 0000000..8d20c5b --- /dev/null +++ b/FacebookAdapter/FacebookAdapter/FacebookAdapter.h @@ -0,0 +1,13 @@ + + +#import + +//! Project version number for FacebookAdapter. +FOUNDATION_EXPORT double FacebookAdapterVersionNumber; + +//! Project version string for FacebookAdapter. +FOUNDATION_EXPORT const unsigned char FacebookAdapterVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/FacebookAdapter/FacebookAdapter/FacebookAdapter.swift b/FacebookAdapter/FacebookAdapter/FacebookAdapter.swift new file mode 100644 index 0000000..28f525c --- /dev/null +++ b/FacebookAdapter/FacebookAdapter/FacebookAdapter.swift @@ -0,0 +1,250 @@ + +//import shared +import MSPiOSCore +import FBAudienceNetwork +import AppTrackingTransparency +import PrebidMobile + +import Foundation + +@objc public class FacebookAdapter : NSObject, AdNetworkAdapter { + public func setAdMetricReporter(adMetricReporter: any MSPiOSCore.AdMetricReporter) { + self.adMetricReporter = adMetricReporter + } + + public func prepareViewForInteraction(nativeAd: MSPiOSCore.NativeAd, nativeAdView: Any) { + guard let nativeAdView = nativeAdView as? NativeAdView, + let mediaView = nativeAdView.mediaView as? FBMediaView, + let fbNativeAdItem = self.nativeAdItem else {return} + //let fbNativeAdView = UIView() + nativeAdView.translatesAutoresizingMaskIntoConstraints = false + let fbSubViews = [nativeAdView.titleLabel, nativeAdView.bodyLabel, nativeAdView.advertiserLabel, nativeAdView.callToActionButton, mediaView] + for view in fbSubViews { + if let view = view { + nativeAdView.addSubview(view) + } + } + nativeAdView.nativeAdViewBinder.setUpViews(parentView: nativeAdView) + + let fbAdOptionsView = FBAdOptionsView(frame: .zero) + fbAdOptionsView.backgroundColor = .clear + fbAdOptionsView.translatesAutoresizingMaskIntoConstraints = false + + nativeAdView.addSubview(fbAdOptionsView) + NSLayoutConstraint.activate([ + fbAdOptionsView.topAnchor.constraint(equalTo: nativeAdView.topAnchor), + fbAdOptionsView.trailingAnchor.constraint(equalTo: nativeAdView.trailingAnchor), + fbAdOptionsView.widthAnchor.constraint(equalToConstant: FBAdOptionsViewWidth), + fbAdOptionsView.heightAnchor.constraint(equalToConstant: FBAdOptionsViewHeight) + ]) + + fbNativeAdItem.registerView(forInteraction: nativeAdView, + mediaView: mediaView, + iconImageView: nil, + viewController: nil, + clickableViews: fbSubViews.compactMap{ $0 }) + fbAdOptionsView.nativeAd = fbNativeAdItem + } + + public var adListener: AdListener? + public var priceInDollar: Double? + + private var nativeAdItem: FBNativeAd? + private var facebookNativeAd: FacebookNativeAd? + private var adRequest: AdRequest? + + private var facebookInterstitialAd: FacebookInterstitialAd? + private var interstitialAdItem: FBInterstitialAd? + + private var adMetricReporter: AdMetricReporter? + + public func destroyAd() { + + } + + public func initialize(initParams: any InitializationParameters, adapterInitListener: any AdapterInitListener, context: Any?) { + FBAdSettings.setAdvertiserTrackingEnabled(isIDFAAuthorized()) + FBAudienceNetworkAds.initialize(with: nil, completionHandler: {_ in + adapterInitListener.onComplete(adNetwork: .facebook, adapterInitStatus: .SUCCESS, message: "") + }) + } + + public func loadAdCreative(bidResponse: Any, adListener: any AdListener, context: Any, adRequest: AdRequest) { + self.adListener = adListener + self.adRequest = adRequest + + guard bidResponse is BidResponse, + let mBidResponse = bidResponse as? BidResponse else { + self.adListener?.onError(msg: "no valid response") + return + } + + guard let adString = mBidResponse.winningBid?.bid.adm, + let rawBidDict = SafeAs(mBidResponse.winningBid?.bid.rawJsonDictionary, [String: Any].self), + let bidExtDict = SafeAs(rawBidDict["ext"], [String: Any].self), + let prebidExtDict = SafeAs(bidExtDict["prebid"], [String: Any].self), + let adType = SafeAs(prebidExtDict["type"], String.self) + else { + self.adListener?.onError(msg: "no valid response") + return + } + self.priceInDollar = Double(mBidResponse.winningBid?.price ?? 0) + + switch adType { + case "native": + guard let placementId = self.getFBPlacementId(from: adString) else { + self.adListener?.onError(msg: "Missing FB payload or placementId") + return + } + nativeAdItem = FBNativeAd(placementID: placementId) + nativeAdItem?.delegate = self + + DispatchQueue.main.async { + self.nativeAdItem?.loadAd(withBidPayload: adString) + } + case "banner": + if adRequest.adFormat == .interstitial { + guard let placementId = self.getFBPlacementId(from: adString) else { + self.adListener?.onError(msg: "Missing FB payload or placementId") + return + } + let facebookInterstitialAdItem = FBInterstitialAd(placementID: placementId) + self.interstitialAdItem = facebookInterstitialAdItem + facebookInterstitialAdItem.delegate = self + DispatchQueue.main.async { + facebookInterstitialAdItem.load(withBidPayload: adString) + } + + } + default: + self.adListener?.onError(msg: "unknown adType") + } + } + + public func loadTestAdCreative() { + nativeAdItem = FBNativeAd(placementID: "placementId#IMG_16_9_LINK") + nativeAdItem?.delegate = self + + self.nativeAdItem?.loadAd(withBidPayload: "placementId#IMG_16_9_LINK") + + } + + public func isIDFAAuthorized() -> Bool { + if #available(iOS 14, *), case .authorized = ATTrackingManager.trackingAuthorizationStatus { + return true + } else { + return false + } + } + + private func SafeAs(_ object: T?, _ objectType: U.Type) -> U? { + if let object = object { + if let temp = object as? U { + return temp + } else { + return nil + } + } else { + // It's always OK to cast nil to nil + return nil + } + } + + private func getFBPlacementId(from payload: String) -> String? { + guard let data = payload.data(using: .utf8) else { + self.adListener?.onError(msg: "Failed to get data from FB payload") + return nil + } + + do { + guard let dict = SafeAs(try JSONSerialization.jsonObject(with: data), [String: Any].self) else { + self.adListener?.onError(msg: "Failed to convert FB payload to json dict") + return nil + } + return SafeAs(dict["resolved_placement_id"], String.self) + } catch { + self.adListener?.onError(msg: "Failed to json serialize FB payload, error = \(error.localizedDescription)") + return nil + } + } +} + + +extension FacebookAdapter: FBNativeAdDelegate { + public func nativeAdDidLoad(_ nativeAd: FBNativeAd) { + let mediaView = FBMediaView(frame: .zero) + mediaView.translatesAutoresizingMaskIntoConstraints = false + + let facebookNativeAd = FacebookNativeAd(adNetworkAdapter: self, + title: nativeAd.headline ?? "", + body: nativeAd.bodyText ?? "", + advertiser: nativeAd.advertiserName ?? "", + callToAction:nativeAd.callToAction ?? "") + self.facebookNativeAd = facebookNativeAd + facebookNativeAd.priceInDollar = self.priceInDollar + facebookNativeAd.nativeAdItem = nativeAd + facebookNativeAd.mediaView = mediaView + facebookNativeAd.adInfo["priceInDollar"] = self.priceInDollar + self.nativeAdItem = nativeAd + if let adListener = adListener, + let adRequest = adRequest { + handleAdLoaded(ad: facebookNativeAd, listener: adListener, adRequest: adRequest) + } + } + + public func nativeAd(_ nativeAd: FBNativeAd, didFailWithError error: Error) { + self.adListener?.onError(msg: error.localizedDescription) + } + + public func nativeAdWillLogImpression(_ nativeAd: FBNativeAd) { + if let facebookNativeAd = self.facebookNativeAd { + self.adListener?.onAdImpression(ad: facebookNativeAd) + } + } + + public func nativeAdDidClick(_ nativeAd: FBNativeAd) { + if let facebookNativeAd = self.facebookNativeAd { + self.adListener?.onAdClick(ad: facebookNativeAd) + } + } +} + +extension FacebookAdapter: FBInterstitialAdDelegate { + public func interstitialAdDidLoad(_ interstitialAd: FBInterstitialAd) { + var facebookInterstitialAd = FacebookInterstitialAd(adNetworkAdapter: self) + facebookInterstitialAd.interstitialAdItem = interstitialAd + interstitialAd.delegate = self + self.interstitialAdItem = interstitialAd + self.facebookInterstitialAd = facebookInterstitialAd + + + if let adListener = self.adListener, + let adRequest = self.adRequest { + handleAdLoaded(ad: facebookInterstitialAd, listener: adListener, adRequest: adRequest) + self.adMetricReporter?.logAdResult(placementId: adRequest.placementId, ad: facebookInterstitialAd, fill: true, isFromCache: false) + } + } + + public func interstitialAd(_ interstitialAd: FBInterstitialAd, didFailWithError error: Error) { + self.adListener?.onError(msg: error.localizedDescription) + self.adMetricReporter?.logAdResult(placementId: adRequest?.placementId ?? "", ad: nil, fill: false, isFromCache: false) + } + + public func interstitialAdDidClick(_ interstitialAd: FBInterstitialAd) { + if let facebookInterstitialAd = self.facebookInterstitialAd { + self.adListener?.onAdClick(ad: facebookInterstitialAd) + } + } + + public func interstitialAdDidClose(_ interstitialAd: FBInterstitialAd) { + if let facebookInterstitialAd = self.facebookInterstitialAd { + self.adListener?.onAdDismissed(ad: facebookInterstitialAd) + } + } + + public func interstitialAdWillLogImpression(_ interstitialAd: FBInterstitialAd) { + if let facebookInterstitialAd = self.facebookInterstitialAd { + self.adListener?.onAdImpression(ad: facebookInterstitialAd) + } + } +} diff --git a/FacebookAdapter/FacebookAdapter/FacebookBidTokenProviderHelper.swift b/FacebookAdapter/FacebookAdapter/FacebookBidTokenProviderHelper.swift new file mode 100644 index 0000000..1409fc4 --- /dev/null +++ b/FacebookAdapter/FacebookAdapter/FacebookBidTokenProviderHelper.swift @@ -0,0 +1,16 @@ +//import shared +import MSPiOSCore +import FBAudienceNetwork + +import Foundation + +public class FacebookBidTokenProviderHelper: FacebookBidTokenProvider { + public init() { + + } + + public func fetch(completeListener: any FacebookBidTokenListener, context: Any) { + let bidToken = FBAdSettings.bidderToken + completeListener.onComplete(bidToken: bidToken) + } +} diff --git a/FacebookAdapter/FacebookAdapter/FacebookManager.swift b/FacebookAdapter/FacebookAdapter/FacebookManager.swift new file mode 100644 index 0000000..f1d1a19 --- /dev/null +++ b/FacebookAdapter/FacebookAdapter/FacebookManager.swift @@ -0,0 +1,11 @@ +import Foundation +import MSPiOSCore +//import shared + +public class FacebookManager: AdNetworkManager { + + public override func getAdNetworkAdapter() -> AdNetworkAdapter? { + return FacebookAdapter() + } + +} diff --git a/FacebookAdapter/FacebookAdapter/Interstitial/FacebookInterstitialAd.swift b/FacebookAdapter/FacebookAdapter/Interstitial/FacebookInterstitialAd.swift new file mode 100644 index 0000000..21c73dd --- /dev/null +++ b/FacebookAdapter/FacebookAdapter/Interstitial/FacebookInterstitialAd.swift @@ -0,0 +1,24 @@ +// +// FacebookInterstitialAd.swift +// FacebookAdapter +// +// Created by Huanzhi Zhang on 10/23/24. +// + +import Foundation +import MSPiOSCore +import FBAudienceNetwork + + +public class FacebookInterstitialAd: MSPiOSCore.InterstitialAd { + public var rootViewController: UIViewController? + public var interstitialAdItem: FBInterstitialAd? + + public override func show() { + interstitialAdItem?.show(fromRootViewController: nil) + } + + public override func show(rootViewController: UIViewController?) { + interstitialAdItem?.show(fromRootViewController: rootViewController) + } +} diff --git a/FacebookAdapter/FacebookAdapter/Native/FacebookNativeAd.swift b/FacebookAdapter/FacebookAdapter/Native/FacebookNativeAd.swift new file mode 100644 index 0000000..7a9546b --- /dev/null +++ b/FacebookAdapter/FacebookAdapter/Native/FacebookNativeAd.swift @@ -0,0 +1,10 @@ + +import Foundation +//import shared +import MSPiOSCore +import FBAudienceNetwork + +public class FacebookNativeAd: NativeAd { + public var nativeAdItem: FBNativeAd? + public var priceInDollar: Double? +} diff --git a/FacebookAdapter/FacebookAdapter/Native/FacebookNativeAdView.swift b/FacebookAdapter/FacebookAdapter/Native/FacebookNativeAdView.swift new file mode 100644 index 0000000..5ac8788 --- /dev/null +++ b/FacebookAdapter/FacebookAdapter/Native/FacebookNativeAdView.swift @@ -0,0 +1,55 @@ + + +import Foundation +import FBAudienceNetwork + +open class FacebookNativeAdView: UIView { + + public var titleLabel: UILabel? + public var bodyLabel: UILabel? + public var advertiserLabel: UILabel? + public var callToActionButton: UIButton? + + public let fbMediaView: FBMediaView = { + let view = FBMediaView(frame: .zero) + view.translatesAutoresizingMaskIntoConstraints = false + return view + }() + + public let fbAdOptionsView: FBAdOptionsView = { + let view = FBAdOptionsView(frame: .zero) + view.backgroundColor = .clear + view.translatesAutoresizingMaskIntoConstraints = false + return view + }() + + open func bindView(nativeAd: FBNativeAd) { + titleLabel = UILabel() + bodyLabel = UILabel() + advertiserLabel = UILabel() + callToActionButton = UIButton(type: .custom) + } + + open func setUpView(nativeAd: FBNativeAd) { + titleLabel?.text = nativeAd.headline + bodyLabel?.text = nativeAd.bodyText + advertiserLabel?.text = nativeAd.advertiserName + callToActionButton?.setTitle(nativeAd.callToAction, for: .normal) + + nativeAd.unregisterView() + + let clickableViews = [ + self.fbMediaView, + self.advertiserLabel, + self.bodyLabel, + self.callToActionButton, + self.titleLabel, + ] + nativeAd.registerView(forInteraction: self, + mediaView: self.fbMediaView, + iconImageView: nil, + viewController: nil, + clickableViews: clickableViews.compactMap { $0 }) + self.fbAdOptionsView.nativeAd = nativeAd + } +} diff --git a/FacebookAdapter/FacebookAdapterTests/MetaAdapterTests.swift b/FacebookAdapter/FacebookAdapterTests/MetaAdapterTests.swift new file mode 100644 index 0000000..c68dbaf --- /dev/null +++ b/FacebookAdapter/FacebookAdapterTests/MetaAdapterTests.swift @@ -0,0 +1,31 @@ + + +import XCTest +@testable import FacebookAdapter + +final class FacebookAdapterTests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() throws { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + // Any test you write for XCTest can be annotated as throws and async. + // Mark your test throws to produce an unexpected failure when your test encounters an uncaught error. + // Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards. + } + + func testPerformanceExample() throws { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + +}