Skip to content

Commit

Permalink
[facebook] Improve sample and add README.md (#15)
Browse files Browse the repository at this point in the history
The facebook sample has been updated to use the bound API, and a README
has been added to explain the sample and how to configure it.

The Android Gradle build scripts have been updated to use Kotlin DSL.

The iOS project has been updated to use Swift Package Manager to manage
the Facebook SDK dependency.

A few MSBuild changes have been made to improve single platform builds.
Android native projects will no longer be built when building for iOS,
and vice-versa.
  • Loading branch information
pjcollins authored May 1, 2024
1 parent 03f352a commit d40ccc7
Show file tree
Hide file tree
Showing 23 changed files with 297 additions and 169 deletions.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,25 @@ There are several ways you can use these samples in your own project.
1. Submodule or otherwise clone this repo into your project, and reference the projects directly as outlined above in the [Get Started section](#get-started)
2. Build the binding projects and consume the .dll assembly artifacts

When packaging a native Android library (.aar) file, gradle/maven dependencies are _not_ automatically bundled into your library. This is important to note, as the application project will often need to explicitly reference these dependencies in order to run successfully. While this approach can work on an individual application basis, it is *not* recommended for library projects. Including specific versions of dependencies in a library can lead to version conflicts when the library is consumed by an application that also uses the same dependencies.

The `facebook/android/native/mauifacebook/build.gradle.kts` file is configured to copy facebook dependencies into a `build/outputs/deps` folder. Some of this content is then referenced by the .NET MAUI sample project:

```xml
<ItemGroup>
<AndroidLibrary Include="..\android\native\mauifacebook\build\outputs\deps\facebook-common*.aar">
<Bind>false</Bind>
<Visible>false</Visible>
</AndroidLibrary>
<AndroidLibrary Include="..\android\native\mauifacebook\build\outputs\deps\facebook-core*.aar">
<Bind>false</Bind>
<Visible>false</Visible>
</AndroidLibrary>
</ItemGroup>
```

In some cases first party NuGet packages will exist for missing dependencies. In other cases, you may need to manually include the dependencies in the project as demonstrated in the sample. We hope to improve this type of dependency inclusion guess work in the future by introducing support for `@(AndroidMavenPackage)` references in Android projects.

> NOTE: Getting this repository building in CI and producing assembly and/or NuGet artifacts is a near term goal but is not currently available.

Expand Down
2 changes: 1 addition & 1 deletion eng/Common.android.targets
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<_AndroidGradleInputs Include="$(_AndroidProjectDirFullPath)/**/*.properties" Exclude="$(_AndroidProjectModuleBuildPath)/**/*" />
</ItemGroup>

<Target Condition=" '$(AndroidBuildAar)' == 'true' " DependsOnTargets="$(BuildAarDependsOnTargets)" BeforeTargets="ProcessFrameworkReferences" Name="BuildAar" Inputs="@(_AndroidGradleInputs)" Outputs="$(_AndroidAarOutputPath)">
<Target Name="BuildAar" Condition=" '$(AndroidBuildAar)' == 'true' " DependsOnTargets="$(BuildAarDependsOnTargets)" BeforeTargets="$(CoreResolveReferencesDependsOn)" Inputs="@(_AndroidGradleInputs)" Outputs="$(_AndroidAarOutputPath)">

<Error Condition=" '$(AndroidProjectDir)' == '' " Text="The AndroidProjectDir property must be set." />
<Error Condition=" '$(AndroidProjectModule)' == '' " Text="The AndroidProjectModule property must be set." />
Expand Down
58 changes: 34 additions & 24 deletions eng/Common.macios.targets
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<Project>

<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>

<XcodeDefaultBuildDir>.build</XcodeDefaultBuildDir>
<XcodeBuildDirName Condition=" '$(XcodeBuildDirName)' == '' ">$(XcodeDefaultBuildDir)</XcodeBuildDirName>

Expand All @@ -23,6 +25,7 @@
<_XcArchiveiOSFullPath>$([System.IO.Path]::Combine($(_XcodeBuildDirFullPath), $(XcodeScheme)-ios.xcarchive))</_XcArchiveiOSFullPath>
<_XcArchiveiOSSimulatorFullPath>$([System.IO.Path]::Combine($(_XcodeBuildDirFullPath), $(XcodeScheme)-iossimulator.xcarchive))</_XcArchiveiOSSimulatorFullPath>
<_XcArchiveMacCatalystFullPath>$([System.IO.Path]::Combine($(_XcodeBuildDirFullPath), $(XcodeScheme)-maccatalyst.xcarchive))</_XcArchiveMacCatalystFullPath>
<_XcArchiveExtraArgs>ENABLE_BITCODE=NO SKIP_INSTALL=NO SWIFT_INSTALL_OBJC_HEADER=YES BUILD_LIBRARY_FOR_DISTRIBUTION=YES OTHER_LDFLAGS='-ObjC' OTHER_SWIFT_FLAGS='-no-verify-emitted-module-interface' OBJC_CFLAGS='-fno-objc-msgsend-selector-stubs -ObjC'</_XcArchiveExtraArgs>

<_XcFrameworkFullPath>$([System.IO.Path]::Combine($(_XcodeBuildDirFullPath), $(XcodeScheme).xcframework))</_XcFrameworkFullPath>
</PropertyGroup>
Expand All @@ -34,22 +37,35 @@
<_XcodeProjectInputs Include="$(_XcodeProjectFullPath)/*.xcworkspace" />
</ItemGroup>

<Target Condition=" '$(XcodeBuildXCFramework)' == 'true' " DependsOnTargets="$(BuildXCFrameworkDependsOnTargets)" BeforeTargets="ProcessFrameworkReferences" Name="BuildXCFramework" Inputs="@(_XcodeProjectInputs)" Outputs="$(_XcFrameworkFullPath)/Info.plist">
<PropertyGroup Condition="$(TargetFramework.Contains('ios')) Or $(TargetFramework.Contains('maccatalyst'))">
<_GenerateBindingsDependsOn>
BuildXCFramework;
ObjSharpieBind;
$(_GenerateBindingsDependsOn);
</_GenerateBindingsDependsOn>
</PropertyGroup>

<Target Name="BuildXCFramework"
Condition=" '$(XcodeBuildXCFramework)' == 'true' "
DependsOnTargets="$(BuildXCFrameworkDependsOnTargets)"
Inputs="@(_XcodeProjectInputs)"
Outputs="$(_XcFrameworkFullPath)/Info.plist">
<Error Condition=" !Exists('$(_XcodeProjectFullPath)') " Text="Xcode project '$(_XcodeProjectFullPath)' not found." />

<Exec Condition=" '$(XcodeBuildiOS)' == 'True' " Command="xcodebuild -project $(_XcodeProjectFullPath) archive -scheme $(XcodeScheme) -configuration Release -archivePath $(_XcArchiveiOSFullPath) -destination 'generic/platform=iOS' -derivedDataPath $(_XcodeBuildDirFullPath) -IDECustomBuildProductsPath='' -IDECustomBuildIntermediatesPath='' ENABLE_BITCODE=NO SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES OTHER_SWIFT_FLAGS='-no-verify-emitted-module-interface' OBJC_CFLAGS='-fno-objc-msgsend-selector-stubs -ObjC'" />
<Exec Condition=" '$(XcodeBuildiOSSimulator)' == 'True' " Command="xcodebuild -project $(_XcodeProjectFullPath) archive -scheme $(XcodeScheme) -configuration Release -archivePath $(_XcArchiveiOSSimulatorFullPath) -destination 'generic/platform=iOS Simulator' -derivedDataPath $(_XcodeBuildDirFullPath) -IDECustomBuildProductsPath='' -IDECustomBuildIntermediatesPath='' ENABLE_BITCODE=NO SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES OTHER_SWIFT_FLAGS='-no-verify-emitted-module-interface' OBJC_CFLAGS='-fno-objc-msgsend-selector-stubs -ObjC'" />
<Exec Condition=" '$(XcodeBuildMacCatalyst)' == 'True' " Command="xcodebuild -project $(_XcodeProjectFullPath) archive -scheme $(XcodeScheme) -configuration Release -archivePath $(_XcArchiveMacCatalystFullPath) -destination 'generic/platform=macOS,variant=Mac Catalyst' -derivedDataPath $(_XcodeBuildDirFullPath) -IDECustomBuildProductsPath='' -IDECustomBuildIntermediatesPath='' ENABLE_BITCODE=NO SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES OTHER_SWIFT_FLAGS='-no-verify-emitted-module-interface' OBJC_CFLAGS='-fno-objc-msgsend-selector-stubs -ObjC'" />
<Exec Condition=" '$(XcodeBuildiOS)' == 'True' " Command="xcodebuild -project $(_XcodeProjectFullPath) archive -scheme $(XcodeScheme) -configuration $(Configuration) -archivePath $(_XcArchiveiOSFullPath) -destination 'generic/platform=iOS' $(_XcArchiveExtraArgs)" />
<Exec Condition=" '$(XcodeBuildiOSSimulator)' == 'True' " Command="xcodebuild -project $(_XcodeProjectFullPath) archive -scheme $(XcodeScheme) -configuration $(Configuration) -archivePath $(_XcArchiveiOSSimulatorFullPath) -destination 'generic/platform=iOS Simulator' $(_XcArchiveExtraArgs)" />
<Exec Condition=" '$(XcodeBuildMacCatalyst)' == 'True' " Command="xcodebuild -project $(_XcodeProjectFullPath) archive -scheme $(XcodeScheme) -configuration $(Configuration) -archivePath $(_XcArchiveMacCatalystFullPath) -destination 'generic/platform=macOS,variant=Mac Catalyst' $(_XcArchiveExtraArgs)" />

<ItemGroup>
<XcodeBuiltFrameworks Condition=" '$(XcodeBuildiOS)' == 'True' " Include="$(_XcArchiveiOSFullPath)/Products/Library/Frameworks/$(XcodeScheme).framework" />
<XcodeBuiltFrameworks Condition=" '$(XcodeBuildiOSSimulator)' == 'True' " Include="$(_XcArchiveiOSSimulatorFullPath)/Products/Library/Frameworks/$(XcodeScheme).framework" />
<XcodeBuiltFrameworks Condition=" '$(XcodeBuildMacCatalyst)' == 'True' " Include="$(_XcArchiveMacCatalystFullPath)/Products/Library/Frameworks/$(XcodeScheme).framework" />
<_CreateXcFxArgs Include="-create-xcframework" />
<_CreateXcFxArgs Condition=" '$(XcodeBuildiOS)' == 'True' " Include="-archive $(_XcArchiveiOSFullPath) -framework $(XcodeScheme).framework" />
<_CreateXcFxArgs Condition=" '$(XcodeBuildiOSSimulator)' == 'True' " Include="-archive $(_XcArchiveiOSSimulatorFullPath) -framework $(XcodeScheme).framework" />
<_CreateXcFxArgs Condition=" '$(XcodeBuildMacCatalyst)' == 'True' " Include="-archive $(_XcArchiveMacCatalystFullPath) -framework $(XcodeScheme).framework" />
<_CreateXcFxArgs Include="-output $(_XcFrameworkFullPath)" />
</ItemGroup>

<RemoveDir Directories="$(_XcFrameworkFullPath)" />

<Exec Command="xcodebuild -create-xcframework @(XcodeBuiltFrameworks->'-framework %(Identity)', ' ') -output $(_XcFrameworkFullPath)" />
<Exec Command="xcodebuild @(_CreateXcFxArgs, ' ')" />
</Target>

<PropertyGroup>
Expand All @@ -61,24 +77,18 @@
<ItemGroup>
<ObjcBindingApiDefinitionFiles Include="$(ObjSharpieBindOutputDir)/ApiDefinitions.cs" />
<_ObjSharpieInputs Include="$(ObjSharpieSourceHeader)" />

</ItemGroup>

<Target Name="ObjSharpieBind" BeforeTargets="ProcessFrameworkReferences" DependsOnTargets="BuildXCFramework" Inputs="@(_ObjSharpieInputs)" Outputs="@(ObjcBindingApiDefinitionFiles)" Condition="'$(ObjSharpieBind)' == 'true'">

<Exec Command="xcodebuild -showsdks" ConsoleToMSBuild="true" Condition=" '$(ObjSharpieBindXcodeSdkName)' == '' ">
<Output TaskParameter="ConsoleOutput" PropertyName="_XcodeShowSdksOutput" />
</Exec>

<PropertyGroup>
<ObjSharpieBindXcodeSdkName Condition=" '$(ObjSharpieBindXcodeSdkName)' == '' ">$([System.Text.RegularExpressions.Regex]::Match($(_XcodeShowSdksOutput), `iphoneos[^; \n\r\t]+`))</ObjSharpieBindXcodeSdkName>
<ObjSharpieBindNamespace Condition=" '$(ObjSharpieBindNamespace)' == '' ">Binding</ObjSharpieBindNamespace>
</PropertyGroup>

<Target Name="ObjSharpieBind"
Condition="'$(ObjSharpieBind)' == 'true'"
Inputs="@(_ObjSharpieInputs)"
Outputs="@(ObjcBindingApiDefinitionFiles)">
<ItemGroup>
<ObjSharpieBindScopes Include="$(_XcArchiveiOSFullPath)/Products/Library/Frameworks/$(XcodeScheme).framework/Headers/" />
<_ObjSharpieArgs Include="--output=$(ObjSharpieBindOutputDir)" />
<_ObjSharpieArgs Include="--namespace=$(ObjSharpieBindNamespace)" />
<_ObjSharpieArgs Include="--framework $(_XcArchiveiOSFullPath)/Products/Library/Frameworks/$(XcodeScheme).framework" />
</ItemGroup>

<Exec Command="sharpie bind --sdk=$(ObjSharpieBindXcodeSdkName) --output=$(ObjSharpieBindOutputDir) --namespace=$(ObjSharpieBindNamespace) @(ObjSharpieBindScopes->'--scope=%(Identity)', ' ') $(ObjSharpieSourceHeader)" />
<Exec Command="sharpie bind @(_ObjSharpieArgs, ' ')" />
</Target>

</Project>
30 changes: 30 additions & 0 deletions facebook/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Facebook Slim Binding
This folder contains a slim binding for the Facebook SDK which demonstrates simple [App Events][0] usage.

### Build and Run
```shell
dotnet build sample -t:Run -f net8.0-android
dotnet build sample -t:Run -f net8.0-ios
```

### Configure
The included sample requires some modification to fully function. You will need to log in to
a Facebook developer account and configure an app to recieve App Events from this sample.
For more details, reference the [Get Started (Android)][1] or [Get Started (iOS)][2] pages.

#### Android
The following app identifiers should be updated in the `strings.xml` file of the sample application:

1. Replace the `YOUR_APP_ID` string in the `facebook/sample/Platforms/Android/Resources/values/strings.xml` file with your Facebook App ID.
2. Replace the `YOUR_CLIENT_TOKEN` string in the `facebook/sample/Platforms/Android/Resources/values/strings.xml` file with your Facebook App Client Token.

#### iOS
The following app identifiers should be updated in the `Info.plist` file of the sample application:

1. Replace the `YOUR_APP_ID` string in the `facebook/sample/Platforms/iOS/Info.plist` file with your Facebook App ID.
2. Replace the `YOUR_CLIENT_TOKEN` string in the `facebook/sample/Platforms/iOS/Info.plist` file with your Facebook App Client Token.


[0]: https://developers.facebook.com/docs/app-events/
[1]: https://developers.facebook.com/docs/app-events/getting-started-app-events-android
[2]: https://developers.facebook.com/docs/app-events/getting-started-app-events-ios
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
<AndroidGenerateResourceDesigner>false</AndroidGenerateResourceDesigner>
</PropertyGroup>
<ItemGroup>
<AndroidLibrary Include="../native/mauifacebook/build/outputs/aar/mauifacebook.aar">
<AndroidLibrary Include="../native/mauifacebook/build/outputs/aar/mauifacebook-release.aar">
<Link>mauifacebook.aar</Link>
<Bind>True</Bind>
<Pack>True</Pack>
<Visible>False</Visible>
<Bind>true</Bind>
<Pack>true</Pack>
<Visible>false</Visible>
</AndroidLibrary>
</ItemGroup>

Expand Down
15 changes: 15 additions & 0 deletions facebook/android/native/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
build
captures
.externalNativeBuild
.cxx
local.properties
5 changes: 0 additions & 5 deletions facebook/android/native/build.gradle

This file was deleted.

4 changes: 4 additions & 0 deletions facebook/android/native/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id("com.android.library") version "8.2.2" apply false
}
1 change: 0 additions & 1 deletion facebook/android/native/mauifacebook/.gitignore

This file was deleted.

40 changes: 0 additions & 40 deletions facebook/android/native/mauifacebook/build.gradle

This file was deleted.

45 changes: 45 additions & 0 deletions facebook/android/native/mauifacebook/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
plugins {
id("com.android.library")
}

android {
namespace = "com.microsoft.mauifacebook"
compileSdk = 34

defaultConfig {
minSdk = 21
}

buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
}

configurations {
create("copyDependencies")
}

dependencies {
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.google.android.material:material:1.11.0")
implementation("com.facebook.android:facebook-android-sdk:latest.release")
"copyDependencies"("com.facebook.android:facebook-android-sdk:latest.release")
}

project.afterEvaluate {
tasks.register<Copy>("copyDeps") {
from(configurations["copyDependencies"])
into("${projectDir}/build/outputs/deps")
}
tasks.named("preBuild") { finalizedBy("copyDeps") }
}
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ public class FacebookSdk {

static AppEventsLogger _logger;

public static void initialize(Activity activity, Boolean isDebug) {
public static void initializeSDK(Activity activity, Boolean isDebug) {
Application application = activity.getApplication();
com.facebook.FacebookSdk.sdkInitialize(application);

if (isDebug) {
com.facebook.FacebookSdk.setIsDebugEnabled(true);
Expand All @@ -28,6 +29,10 @@ public static void initialize(Activity activity, Boolean isDebug) {
_logger = AppEventsLogger.newLogger(activity);
}

public static void enableAutoLogAppEvents(Boolean enabled) {
com.facebook.FacebookSdk.setAutoLogAppEventsEnabled(enabled);
}

public static void logEvent(String eventName) {
_logger.logEvent(eventName);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ dependencyResolutionManagement {
}

rootProject.name = "MauiFacebook"
include ':mauifacebook'
include(":mauifacebook")
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,19 @@
<Nullable>enable</Nullable>
<ImplicitUsings>true</ImplicitUsings>
<IsBindingProject>true</IsBindingProject>

<XcodeProject>$(MSBuildThisFileDirectory)../native/MauiFacebook.xcodeproj</XcodeProject>
<ObjSharpieBindNamespace>Facebook</ObjSharpieBindNamespace>
</PropertyGroup>

<ItemGroup>
<ObjcBindingApiDefinition Include="ApiDefinitions.cs"/>
<!-- <ObjcBindingCoreSource Include="StructsAndEnums.cs"/> -->
<NativeReference Include="../native/.build/MauiFacebook.xcframework">
<Kind>Framework</Kind>
<SmartLink>True</SmartLink>
<SmartLink>true</SmartLink>
</NativeReference>
</ItemGroup>

<PropertyGroup>
<XcodeBuildMacCatalyst>True</XcodeBuildMacCatalyst>
<XcodeProject>$(MSBuildThisFileDirectory)../native/MauiFacebook.xcodeproj</XcodeProject>
<ObjSharpieBindNamespace>Facebook</ObjSharpieBindNamespace>
<BuildXCFrameworkDependsOnTargets>$(BuildXCFrameworkDependsOnTargets);NativeDependencies</BuildXCFrameworkDependsOnTargets>
</PropertyGroup>


<Target Name="NativeDependencies">
<PropertyGroup>
<FacebookiOSSdkVersion>17.0.0</FacebookiOSSdkVersion>
<FacebookiOSSdkUrl>https://github.com/facebook/facebook-ios-sdk/releases/download/v$(FacebookiOSSdkVersion)/FacebookSDK_Dynamic.xcframework.zip</FacebookiOSSdkUrl>
</PropertyGroup>

<DownloadFile SourceUrl="$(FacebookiOSSdkUrl)" DestinationFolder="$([System.IO.Path]::GetFullPath($(MSBuildProjectDirectory)/../native/.build))">
<Output TaskParameter="DownloadedFile" ItemName="FacebookiOSSdkArchives" />
</DownloadFile>

<Exec Command="unzip -o -d $([System.IO.Path]::GetFullPath($(MSBuildProjectDirectory)/../native/.build)) @(FacebookiOSSdkArchives)" />

</Target>

<Import Project="$(MSBuildThisFileDirectory)..\..\..\eng\Common.macios.targets" />
</Project>
Loading

0 comments on commit d40ccc7

Please sign in to comment.