Xamarin.Forms implementation of Facebook Audience Network - xamarin

I'm struggling with implementation of Facebook Audience Network in my Xamarin.Forms app.
Available nuget package is old and has obsolete metods.
I was able to implement ads by my own, test interstital ads are displaying correctly, but when other users are using my app ads are not displayed at all. I see in logs that FAN returned error code 1001 with "No fill" message.
What have I done:
added to solution new Android class parse project. Project contains 'AudienceNetwork.aar` file from facebok page. Build action set to LibraryProjectZip
I had to add some classes to fix build errors:
public partial class AdView
{
internal partial class IAdViewLoadConfigBuilderInvoker
{
IAdLoadAdConfig IAdLoadConfigBuilder.Build()
{
return Build();
}
IAdLoadConfigBuilder IAdLoadConfigBuilder.WithBid(string p0)
{
return WithBid(p0);
}
}
}
public partial class InterstitialAd
{
IAdLoadConfigBuilder IFullScreenAd.BuildLoadAdConfig()
{
return BuildLoadAdConfig();
}
IFullScreenAdShowConfigBuilder IFullScreenAd.BuildShowAdConfig()
{
return BuildShowAdConfig();
}
internal partial class IInterstitialAdLoadConfigBuilderInvoker
{
IAdLoadAdConfig IAdLoadConfigBuilder.Build()
{
return Build();
}
IAdLoadConfigBuilder IAdLoadConfigBuilder.WithBid(string p0)
{
return WithBid(p0);
}
}
internal partial class IInterstitialAdShowConfigBuilderInvoker
{
IFullScreenAdShowAdConfig IFullScreenAdShowConfigBuilder.Build()
{
return Build();
}
}
}
public abstract partial class NativeAdBase
{
internal partial class INativeAdLoadConfigBuilderInvoker
{
IAdLoadAdConfig IAdLoadConfigBuilder.Build()
{
return Build();
}
IAdLoadConfigBuilder IAdLoadConfigBuilder.WithBid(string p0)
{
return WithBid(p0);
}
}
}
public partial class RewardedVideoAd
{
IAdLoadConfigBuilder IFullScreenAd.BuildLoadAdConfig()
{
return BuildLoadAdConfig();
}
IFullScreenAdShowConfigBuilder IFullScreenAd.BuildShowAdConfig()
{
return BuildShowAdConfig();
}
internal partial class IRewardedVideoAdLoadConfigBuilderInvoker
{
IAdLoadAdConfig IAdLoadConfigBuilder.Build()
{
return Build();
}
IAdLoadConfigBuilder IAdLoadConfigBuilder.WithBid(string p0)
{
return WithBid(p0);
}
}
internal partial class IRewardedVideoAdShowConfigBuilderInvoker
{
IFullScreenAdShowAdConfig IFullScreenAdShowConfigBuilder.Build()
{
return Build();
}
}
}
public abstract partial class AdComponentFrameLayout
{
public void SetLayoutParams(ViewGroup.LayoutParams p0)
{
SetLayoutParams(p0);
}
}
public abstract partial class AdNativeComponentView
{
public void SetLayoutParams(ViewGroup.LayoutParams p0)
{
SetLayoutParams(p0);
}
}
internal partial class IInterstitialAdApiInvoker
{
IAdLoadConfigBuilder IFullScreenAd.BuildLoadAdConfig()
{
return BuildLoadAdConfig();
}
IFullScreenAdShowConfigBuilder IFullScreenAd.BuildShowAdConfig()
{
return BuildShowAdConfig();
}
}
public partial class InitSettingsBuilder
{
AudienceNetworkAds.IInitSettingsBuilder AudienceNetworkAds.IInitSettingsBuilder.WithInitListener(AudienceNetworkAds.IInitListener p0)
{
return WithInitListener(p0);
}
AudienceNetworkAds.IInitSettingsBuilder AudienceNetworkAds.IInitSettingsBuilder.WithMediationService(string p0)
{
return WithMediationService(p0);
}
AudienceNetworkAds.IInitSettingsBuilder AudienceNetworkAds.IInitSettingsBuilder.WithPlacementIds(IList<string> p0)
{
return WithPlacementIds(p0);
}
}
internal partial class IRewardedVideoAdApiInvoker
{
IAdLoadConfigBuilder IFullScreenAd.BuildLoadAdConfig()
{
return BuildLoadAdConfig();
}
IFullScreenAdShowConfigBuilder IFullScreenAd.BuildShowAdConfig()
{
return BuildShowAdConfig();
}
}
in Android project in MainActivity:
AudienceNetworkAds.Initialize(this);
InterstitialAdsRenderer
public class InterstitalAdsRenderer : IInterstitalAdsService
{
InterstitialAd _interstitial;
public void Show(string adsId)
{
//AdSettings.AddTestDevice("fe9823bf-946e-4a43-b38c-f958d0bfaa31");
_interstitial = new InterstitialAd(Application.Context, adsId);
var loadAdConfig = _interstitial.BuildLoadAdConfig()
.WithAdListener(new InterstitialAdListener(_interstitial))
.Build();
_interstitial.LoadAd(loadAdConfig);
}
}
internal class InterstitialAdListener : Java.Lang.Object, IInterstitialAdListener
{
private readonly InterstitialAd _interstitial;
public InterstitialAdListener(InterstitialAd interstitial)
{
}
public void OnAdClicked(IAd p0)
{
}
public void OnAdLoaded(IAd p0)
{
_interstitial.Show();
}
public void OnError(IAd p0, AdError p1)
{
Console.WriteLine("OnError: " + p1.ErrorMessage);
}
public void OnLoggingImpression(IAd p0)
{
}
public void OnInterstitialDismissed(IAd p0)
{
}
public void OnInterstitialDisplayed(IAd p0)
{
}
}
As I said earlier test ads in test device(emulator added to testsDevices) is displaying ads correctly, but on the production there is no ads :/
Anyone had implemented facebok ads in Xamarin.Forms project and can tell me how can I do this correctly?

this error normally means that you have not logged in to Facebook app or Facebook app is not available in the device that you are running your app

Related

How can I use the CXF HttpConduitFeature for DOSGi?

Has anyone succesfully used the CXF HttpConduitFeature for DOSGi ?
Looking at the CXF code for HttpConduitFeature.java
public class HttpConduitFeature extends DelegatingFeature<HttpConduitFeature.Portable> {
public HttpConduitFeature() {
super(new Portable());
}
public void setConduitConfig(HttpConduitConfig conduitConfig) {
delegate.setConduitConfig(conduitConfig);
}
public static class Portable implements AbstractPortableFeature {
private HttpConduitConfig conduitConfig;
#Override
public void initialize(Client client, Bus bus) {
Conduit conduit = client.getConduit();
if (conduitConfig != null && conduit instanceof HTTPConduit) {
conduitConfig.apply((HTTPConduit)conduit);
}
}
public void setConduitConfig(HttpConduitConfig conduitConfig) {
this.conduitConfig = conduitConfig;
}
}
}
And this method from the class JAXRSClientFactoryBean.java
protected void applyFeatures(AbstractClient client) {
if (getFeatures() != null) {
getFeatures().forEach(feature -> {
feature.initialize(client.getConfiguration(), getBus());
});
}
}
Which is what happens from the RsProvider-class in CXF-DOSGi, I don't understand how the initialize() from the HttpConduitFeature.Portable class will ever get called..
I tried to create my own implementation, a copy from HttpConduitFeature, but with an override of the method initialize(final InterceptorProvider interceptorProvider, final Bus bus), but then I have nothing to add the conduitConfig to. I don't see how I can make progress here.
Anyone has a better idea to add a Basic Authentication AuthorizationPolicy to my DOSGi client ? This was my attempt :
public class BasicAuthorizationIntent implements IntentsProvider {
#Override
public List<?> getIntents() {
HttpConduitConfig conduitConfig = new HttpConduitConfig();
conduitConfig.setAuthorizationPolicy(basicAuthorization());
HttpConduitFeature conduitFeature = new HttpConduitFeature();
conduitFeature.setConduitConfig(conduitConfig);
return Arrays.asList((Object) conduitFeature);
}
private AuthorizationPolicy basicAuthorization() {
AuthorizationPolicy authorizationPolicy = new AuthorizationPolicy();
authorizationPolicy.setUserName("dosgi");
authorizationPolicy.setPassword("dosgi");
authorizationPolicy.setAuthorizationType("Basic");
return authorizationPolicy;
}
}

Issue getting fault message from message context in Masstransit

I have an application that needs to intercept the current message consume context and extract a value that is defined in a base interface. That value is a tenant code that is eventually used in an EF database context.
I have a provider that takes a MassTransit ConsumerContext, and then using context.TryGetMessage(), extracts the tenant code, which is ultimately used to switch database contexts to a specific tenant database.
The issue lies in the MessageContextTenantProvider below. If a non-fault message is consumed then ConsumeContext<IBaseEvent> works fine. However if it is a fault, ConsumeContext<Fault<IBaseEvent>> doesn't work as expected.
Durring debugging I can see that the message context for a fault is ConsumeContext<Fault<IVerifyEvent>>, but why doesn't it work with a base interface as per the standard message? Of course, ConsumeContext<Fault<IVerifiedEvent>> works fine, but I have a lot of message types, and I don't want to have to define them all in that tenant provider.
Any ideas?
public interface ITenantProvider
{
string GetTenantCode();
}
public class MessageContextTenantProvider : ITenantProvider
{
private readonly ConsumeContext _consumeContext;
public MessageContextTenantProvider(ConsumeContext consumeContext)
{
_consumeContext = consumeContext;
}
public string GetTenantCode()
{
// get tenant from message context
if (_consumeContext.TryGetMessage(out ConsumeContext<IBaseEvent> baseEvent))
{
return baseEvent.Message.TenantCode; // <-- works for the non fault consumers
}
// get tenant from fault message context
if (_consumeContext.TryGetMessage<Fault<IBaseEvent>>(out var gebericFaultEvent))
{
return gebericFaultEvent.Message.Message.TenantCode; // <- doesn't work generically
}
// get tenant from fault message context (same as above)
if (_consumeContext.TryGetMessage(out ConsumeContext<Fault<IBaseEvent>> faultEvent))
{
return faultEvent.Message.Message.TenantCode; // <= generically doesn't work when using the base interface?
}
// get tenant from specific concrete fault class
if (_consumeContext.TryGetMessage(out ConsumeContext<Fault<IVerifiedEvent>> verifiedFaultEvent))
{
return verifiedFaultEvent.Message.Message.TenantCode; // <-- this works
}
// not able to extract tenant
return null;
}
}
public partial class VerificationDbContext
{
string connectionString;
public string ConnectionString
{
get
{
if (connectionString == null)
{
string tenantCode = _tenantProvider.GetTenantCode();
connectionString = _tenantConnectionManager.GetConnectionString(orgId);
}
return connectionString;
}
}
private readonly ITenantProvider _tenantProvider;
private readonly ITenantConnectionManager _tenantConnectionManager;
public VerificationDbContext(ITenantProvider tenantProvider, ITenantConnectionManager tenantConnectionManager)
{
_tenantProvider = tenantProvider;
_tenantConnectionManager = tenantConnectionManager;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (string.IsNullOrEmpty(this.ConnectionString))
{
optionsBuilder.UseSqlServer(#"Data Source=.\SQLEXPRESS;Initial Catalog=VerificationDb;Integrated Security=True")
.ConfigureWarnings((warningBuilder) => warningBuilder.Ignore(RelationalEventId.AmbientTransactionWarning));
}
else
{
optionsBuilder.UseSqlServer(this.ConnectionString)
.ConfigureWarnings((warningBuilder) => warningBuilder.Ignore(RelationalEventId.AmbientTransactionWarning));
}
}
}
public interface ITenantConnectionManager
{
string GetConnectionString(string tenantCode);
}
public class TenantConnectionManager : ITenantConnectionManager
{
private ITenantRepository _tenantRepository;
public TenantConnectionManager(ITenantRepository tenantRepository)
{
_tenantRepository = tenantRepository;
}
public string GetConnectionString(string tenantCode)
{
return _tenantRepository.GetByTenantCode(tenantCode).ConnectionString;
}
}
public interface IBaseEvent
{
string TenantCode { get; }
}
public interface IVerifiedEvent : IBaseEvent
{
string JobReference { get; }
}
public class VerifiedEventConsumer : IConsumer<IVerifiedEvent>
{
private readonly IVerifyCommand _verifyCommand;
private readonly ITenantProvider _tenantProvider;
public VerifiedEventConsumer(ITenantProvider tenantProvider, IVerifyCommand verifyCommand)
{
_verifyCommand = verifyCommand;
_tenantProvider = tenantProvider;
}
public async Task Consume(ConsumeContext<IVerifiedEvent> context)
{
await _verifyCommand.Execute(new VerifyRequest
{
JobReference = context.Message.JobReference,
TenantCode = context.Message.TenantCode
});
}
}
public class VerifiedEventFaultConsumer : IConsumer<Fault<IVerifiedEvent>>
{
private readonly IVerifyFaultCommand _verifyFaultCommand;
private readonly ITenantProvider _tenantProvider;
public CaseVerifiedEventFaultConsumer(ITenantProvider tenantProvider, IVerifyFaultCommand verifyFaultCommand)
{
_verifyFaultCommand = verifyFaultCommand;
_tenantProvider = tenantProvider;
}
public async Task Consume(ConsumeContext<Fault<ICaseVerifiedEvent>> context)
{
await _verifyFaultCommand.Execute(new VerifiedFaultRequest
{
JobReference = context.Message.Message.JobReference,
Exceptions = context.Message.Exceptions
});
}
}
I've solved the issue by using the GreenPipes TryGetPayload extension method:
public class MessageContextTenantProvider : ITenantProvider
{
private readonly ConsumeContext _consumeContext;
public MessageContextTenantProvider(ConsumeContext consumeContext)
{
_consumeContext = consumeContext;
}
public string GetTenantCode()
{
// get tenant from message context
if (_consumeContext.TryGetMessage(out ConsumeContext<IBaseEvent> baseEvent))
{
return baseEvent.Message.TenantCode;
}
// get account code from fault message context using Greenpipes
if (_consumeContext.TryGetPayload(out ConsumeContext<Fault<IBaseEvent>> payloadFaultEvent))
{
return payloadFaultEvent.Message.Message.TenantCode;
}
// not able to extract tenant
return null;
}
}

HttpRouteBuilder - Where did it go and Why?

I upgraded my nuget package for the Web API 2 from the RC1 to 5.0.0, and was dumbfounded to find that HttpRouteBuilder, which used to be accessible, was made internal. Along with that, there is no longer an overload for HttpConfiguration.MapHttpAttributeRoutes that takes HttpRouteBuilder as an argument. Why?
I was using that, and it solves a major problem in my project. What do I use instead?
Background:
I am writing a server that uses Attribute Routing for Web API 2. I implemented a class that inherited from HttpRouteBuilder so that I could inject a couple extra path segments to every URI. For example, if the default route builder ended up creating a route for //myserver/user/update, my route builder would modify that route to //myserver/{instance}/user/update. I wanted this done automatically so that I didn't have to stick that in every single of my hundreds of HttpGet, HttpPost, etc. attributes. So now how do I handle that with this major change?
That internalling broke something I was working on as well.
A change set made on August 21st 2013 made this api alteration to fix this issue. According to that issue the only reason functionality was removed was to make Web Api closer to MVC's api. Not a particularly good justification in my opinion.
To resolve my issues I implemented a custom IHttpActionSelector derived from ApiControllerActionSelector. I hope it is not going to be my final solution since it really is far too much code for a simple thing. This approach should work for your problem too.
In my project each route needs to be modified according to which assembly it was found in. In following simplified code every route is prefixed with /Api (before a controller's RoutePrefixAttribute if present).
The actual IHttpActionSelector:
public class PrefixWithApiControllerActionSelector : WrappingApiControllerActionSelector {
protected override HttpActionDescriptor WrapHttpActionDescriptor(HttpActionDescriptor actionDescriptor) {
if (actionDescriptor is ReflectedHttpActionDescriptor)
return new PrefixWithApiReflectedHttpActionDescriptor((ReflectedHttpActionDescriptor)actionDescriptor);
return actionDescriptor;
}
}
public abstract class WrappingApiControllerActionSelector : ApiControllerActionSelector {
protected abstract HttpActionDescriptor WrapHttpActionDescriptor(HttpActionDescriptor actionDescriptor);
public override ILookup<string, HttpActionDescriptor> GetActionMapping(HttpControllerDescriptor controllerDescriptor) {
return base.GetActionMapping(controllerDescriptor).SelectMany(grouping => {
return grouping.Select(actionDescriptor => new KeyValuePair<string, HttpActionDescriptor>(grouping.Key, WrapHttpActionDescriptor(actionDescriptor)));
}).ToLookup(_ => _.Key, _ => _.Value);
}
}
The part that changes the route:
public class PrefixWithApiHttpRouteInfoProvider : WrappedHttpRouteInfoProvider {
public PrefixWithApiHttpRouteInfoProvider(IHttpRouteInfoProvider infoProvider, HttpControllerDescriptor controllerDescriptor) : base(infoProvider, controllerDescriptor) { }
public override string Template {
get {
var parts = new List<string>();
parts.Add("Api");
var prefix = ControllerDescriptor.GetCustomAttributes<RoutePrefixAttribute>().FirstOrDefault();
if (prefix != null && !string.IsNullOrEmpty(prefix.Prefix)) {
parts.Add(prefix.Prefix);
}
if (!string.IsNullOrEmpty(InfoProvider.Template)) {
parts.Add(InfoProvider.Template);
}
var route = "~/" + string.Join("/", parts);
if (route.Length > 2 && route.EndsWith("/", StringComparison.Ordinal)) {
route = route.Substring(0, route.Length - 1);
}
return route;
}
}
}
public abstract class WrappedHttpRouteInfoProvider : IHttpRouteInfoProvider {
private readonly IHttpRouteInfoProvider _infoProvider;
private readonly HttpControllerDescriptor _controllerDescriptor;
protected WrappedHttpRouteInfoProvider(IHttpRouteInfoProvider infoProvider, HttpControllerDescriptor controllerDescriptor) {
_infoProvider = infoProvider;
_controllerDescriptor = controllerDescriptor;
}
public virtual string Name {
get { return InfoProvider.Name; }
}
public virtual string Template {
get { return _infoProvider.Template; }
}
public virtual int Order {
get { return InfoProvider.Order; }
}
protected HttpControllerDescriptor ControllerDescriptor {
get { return _controllerDescriptor; }
}
protected IHttpRouteInfoProvider InfoProvider {
get { return _infoProvider; }
}
}
The glue:
public class PrefixWithApiReflectedHttpActionDescriptor : WrappedReflectedHttpActionDescriptor {
public PrefixWithApiReflectedHttpActionDescriptor(ReflectedHttpActionDescriptor descriptor) : base(descriptor) {}
public override Collection<T> GetCustomAttributes<T>(bool inherit) {
if (typeof(T) == typeof(IHttpRouteInfoProvider)) {
var attributes = Descriptor.GetCustomAttributes<T>(inherit).Cast<IHttpRouteInfoProvider>().Select(_ => new PrefixWithApiHttpRouteInfoProvider(_, Descriptor.ControllerDescriptor));
return new Collection<T>(attributes.Cast<T>().ToList());
}
return Descriptor.GetCustomAttributes<T>(inherit);
}
public override Collection<T> GetCustomAttributes<T>() {
if (typeof(T) == typeof(IHttpRouteInfoProvider)) {
var attributes = Descriptor.GetCustomAttributes<T>().Cast<IHttpRouteInfoProvider>().Select(_ => new PrefixWithApiHttpRouteInfoProvider(_, Descriptor.ControllerDescriptor));
return new Collection<T>(attributes.Cast<T>().ToList());
}
return Descriptor.GetCustomAttributes<T>();
}
}
public abstract class WrappedReflectedHttpActionDescriptor : ReflectedHttpActionDescriptor {
private readonly ReflectedHttpActionDescriptor _descriptor;
protected WrappedReflectedHttpActionDescriptor(ReflectedHttpActionDescriptor descriptor) : base(descriptor.ControllerDescriptor, descriptor.MethodInfo) {
_descriptor = descriptor;
}
public override HttpActionBinding ActionBinding {
get { return Descriptor.ActionBinding; }
set { Descriptor.ActionBinding = value; }
}
public override Collection<T> GetCustomAttributes<T>(bool inherit) {
return Descriptor.GetCustomAttributes<T>(inherit);
}
public override Collection<T> GetCustomAttributes<T>() {
return Descriptor.GetCustomAttributes<T>();
}
public override Collection<System.Web.Http.Filters.FilterInfo> GetFilterPipeline() {
return Descriptor.GetFilterPipeline();
}
public override Collection<System.Web.Http.Filters.IFilter> GetFilters() {
return Descriptor.GetFilters();
}
public override System.Collections.Concurrent.ConcurrentDictionary<object, object> Properties {
get { return Descriptor.Properties; }
}
public override IActionResultConverter ResultConverter {
get { return Descriptor.ResultConverter; }
}
public override Collection<HttpMethod> SupportedHttpMethods {
get { return Descriptor.SupportedHttpMethods; }
}
public override Collection<HttpParameterDescriptor> GetParameters() {
return Descriptor.GetParameters();
}
public override Task<object> ExecuteAsync(HttpControllerContext controllerContext, IDictionary<string, object> arguments, CancellationToken cancellationToken) {
return Descriptor.ExecuteAsync(controllerContext, arguments, cancellationToken);
}
public override string ActionName {
get { return Descriptor.ActionName; }
}
public override Type ReturnType {
get { return Descriptor.ReturnType; }
}
protected ReflectedHttpActionDescriptor Descriptor {
get { return _descriptor; }
}
}
To use this functionality just substitute the IHttpActionSelector service with PrefixWithApiControllerActionSelector in the config.
If you find a cleaner way of doing things please post your solution!

How to declare MVVM RelayCommand in viewmodel

How to use relay command in set, I use the following way, throws interface bug on set method
public RelayCommand ChartCommand
{
set
{
ChartCommand = new RelayCommand<string>(e => ExecuteChartCommand(e));
}
}
public void ExecuteChartCommand(string vendor)
{
}
You should really be doing it this way:
private RelayCommand<string> m_ChartCommand;
public RelayCommand<string> ChartCommand
{
get
{
return m_ChartCommand ?? (m_ChartCommand = new RelayCommand<string>(e => ExecuteChartCommand(e));
}
}
public void ExecuteChartCommand(string vendor)
{
}
.

How to load a view in a particular region dynamically in Prism

In Prism Silverlight5, I have a shell which is divided into two vertical regions(leftRegion,rightRegion) & there are 2 views in Module1 i.e. (View1,View2). In leftRegion I have a View1 loaded which has a button. I want to dynamically load View2 on rightRegion using ViewModel & MEF.ViewModel code is :
[Export(typeof(LeftViewViewModel))]
public class LeftViewViewModel:ViewModelBase,IViewModel
{
[Import]
public IRegionManager CullingRegion { get; set; }
[ImportingConstructor]
public LeftViewViewModel(LeftView view)
:base(view)
{
LoadCommand = new DelegateCommand(LoadControl,CanLoadControl);
}
private void LoadControl()
{
CullingRegion.RegisterViewWithRegion("RightRegion", typeof(RightView));
}
protected bool CanLoadControl()
{
return true;
}
public DelegateCommand LoadCommand { get; set; }
}
LeftView.xaml.cs is :
[Import]
public ViewModels.IViewModel ViewModel
{
get { return (IViewModel) DataContext; }
set { DataContext = value; }
}
IModule implementation is :
[ModuleExport(typeof(CullingModuleModule1))]
public class CullingModuleModule1:IModule
{
[Import]
public IRegionManager CullingRegion { get; set; }
public void Initialize()
{
CullingRegion.RegisterViewWithRegion("ShellContentRegion", typeof (Container));
CullingRegion.RegisterViewWithRegion("LeftRegion", typeof(LeftView));
}
}
First of,I think your ViewModel should not be referenced by a View.
You may need to review View Injection with MEF.
As I've seen in multiple posts :
[Export]
public class YourViewClassName : UserControl
{
public YourViewClassName()
{
}
[Import]
public ILeftViewModel
{
get { return (ILeftViewModel )DataContext; }
set { DataContext = value; }
}
}
[Export(typeof(LeftViewViewModel))]
public class LeftViewViewModel : ILeftViewModel //ILeftViewModel inherits from IViewModel
{
public LeftViewViewModel()
{
}
}
Inside Module Initializer :
CullingRegion.Regions[YourRegionName].Add(ServiceLocator.Current.GetInstance<YourViewClassName>());
Hope it helps

Resources