Skip to content

Instantly share code, notes, and snippets.

@luigisaggese
Last active October 24, 2017 14:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save luigisaggese/66b395de43642567fe1529b43d057261 to your computer and use it in GitHub Desktop.
Save luigisaggese/66b395de43642567fe1529b43d057261 to your computer and use it in GitHub Desktop.
PushNotification Localytics
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using Facebook.CoreKit;
using Firebase.Core;
using Firebase.DynamicLinks;
using Foundation;
using Google.MobileAds;
using Google.SignIn;
using HockeyApp.iOS;
using JR.UI.Touch.Helpers;
using JR.UI.Touch.Repository.Entities;
using JR.UI.Touch.Views;
using LocalyticsXamarin.iOS;
using MvvmCross.iOS.Platform;
using MvvmCross.iOS.Views;
using MvvmCross.iOS.Views.Presenters;
using MvvmCross.Platform;
using SQLite;
using StoreKit;
using UIKit;
using static System.String;
using BannerView = Google.MobileAds.DoubleClick.BannerView;
using Loader = Firebase.Analytics.Loader;
//using FirebaseAnalyticsBinding;
namespace JR.UI.Touch
{
// The UIApplicationDelegate for the application. This class is responsible for launching the
// User Interface of the application, as well as listening (and optionally responding) to
// application events from iOS.
[Register("AppDelegate")]
public class AppDelegate : MvxApplicationDelegate
{
#region Events Override
// This method is invoked when the application has loaded and is ready to run. In this
// method you should instantiate the window, load the UI into it and then make the window
// visible.
//
// You have 17 seconds to return from this method, or iOS will terminate your application.
public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
Loader.ForceLoad();
Firebase.Core.App.Configure();
Firebase.InstanceID.Loader.ForceLoad();
Loader.ForceLoad();
Google.Core.Loader.ForceLoad();
Firebase.DynamicLinks.Loader.ForceLoad();
Options.DefaultInstance.DeepLinkUrlScheme = "jobrapido";
ServicePointManager.ServerCertificateValidationCallback +=
(sender, cert, chain, sslPolicyErrors) => true;
Facebook.CoreKit.Settings.AppID = "1565183867039238";
Facebook.CoreKit.Settings.DisplayName = "Jobrapido Lavoro";
connectFlags.Add(ENABLE_LOGGING_IOS, true);
Settings.CurrentTrafficSource = JobrapidoTrafficSource.None;
Profile.EnableUpdatesOnAccessTokenChange(true);
UIApplication.CheckForIllegalCrossThreadCalls = false;
Window = new UIWindow(UIScreen.MainScreen.Bounds) {BackgroundColor = UIColor.White};
var setup = new Setup(this, Window);
setup.Initialize();
LocalyticsApi.SetAppVersion(AppIdGenerator.AppVersion);
Window.MakeKeyAndVisible();
Utils.PreselectCountry();
if (!Settings.IsSearchViewShowable)
try
{
Utils.NavigationService.Navigate(new OnBoardingViewModel());
}
catch (Exception e)
{
Mvx.TaggedTrace(GetType().Name, "Exception :" + e.Message);
if (e.InnerException != null)
Mvx.TaggedTrace(GetType().Name, "InnerException :" + e.InnerException.Message);
}
else
try
{
var parameter = Empty;
if (launchOptions != null && launchOptions.ContainsKey(UIApplication.LaunchOptionsUrlKey))
{
var url = (NSUrl) launchOptions.ValueForKey(UIApplication.LaunchOptionsUrlKey);
if (url.AbsoluteString.Contains("mysearches") || url.AbsoluteString.Contains("adverts"))
parameter = "mysearches";
else if (url.AbsoluteString.Contains("favouritejob"))
parameter = "favouritejob";
else if (url.AbsoluteString.Contains("profile"))
parameter = "profile";
}
Utils.NavigateToHomeViewModel(parameter);
}
catch (Exception e)
{
Mvx.TaggedTrace(GetType().Name, "Exception :" + e.Message);
if (e.InnerException != null)
Mvx.TaggedTrace(GetType().Name, "InnerException :" + e.InnerException.Message);
}
if (launchOptions != null || UIApplication.SharedApplication.ApplicationIconBadgeNumber > 0)
ProcessNotification(launchOptions);
if (launchOptions != null && launchOptions.ContainsKey(UIApplication.LaunchOptionsUrlKey))
OpenUrl(application, (NSUrl) launchOptions.ValueForKey(UIApplication.LaunchOptionsUrlKey), "",
new NSObject());
if (launchOptions?.ObjectForKey(UIApplication.LaunchOptionsUserActivityDictionaryKey) != null)
{
var userActivityDictionary =
(NSDictionary) launchOptions[UIApplication.LaunchOptionsUserActivityDictionaryKey];
NSUserActivity userActivity = null;
for (nuint i = 0; i < userActivityDictionary.Count; i++)
{
//id key, id obj, BOOL *stop
var obj = userActivityDictionary.Values[i];
if (!(obj is NSUserActivity)) continue;
userActivity = (NSUserActivity) obj;
break;
}
if (userActivity != null && userActivity.ActivityType.Equals(NSUserActivityType.BrowsingWeb))
{
var universalLink = userActivity.WebPageUrl.AbsoluteString;
OpenUrl(application, new NSUrl(universalLink), "Universal Link", null);
}
}
//FIRApp.Configure();
// Optional: set Google Analytics dispatch interval to e.g. 20 seconds.
Utils.Instance.CreateTable<CachedEntity>(CreateFlags.AutoIncPK);
Utils.Instance.CreateTable<JobSeekerTable>(CreateFlags.AutoIncPK);
Utils.Instance.CreateTable<JobSeekerStatement>(CreateFlags.AutoIncPK);
Utils.Instance.CreateTable<UserToken>(CreateFlags.AutoIncPK);
Localytics.Integrate(LocalyticsId);
var manager = BITHockeyManager.SharedHockeyManager;
manager.Configure("7de426aeab7a43dca46ef137b13de87e");
manager.CrashManager.CrashManagerStatus = BITCrashManagerStatus.AutoSend;
manager.StartManager();
if (!application.ApplicationState.Equals(UIApplicationState.Background))
{
Localytics.OpenSession();
Localytics.Upload();
}
Utils.NativeAds = new SortedDictionary<string, NativeAd>();
Utils.BannerViewAds = new SortedDictionary<string, BannerView>();
Utils.BannerViewHome = new SortedDictionary<string, BannerView>();
Utils.AdLoaders = new Dictionary<string, AdLoader>();
//tracker.AppleAppID = "842642357";
//tracker.AppsFlyerDevKey = "r8tKMw9cvk357AAyJfobHk";
//tracker.TrackAppLaunch();
return ApplicationDelegate.SharedInstance.FinishedLaunching(application,
launchOptions ?? new NSDictionary());
}
#endregion
public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
var myDeviceToken = deviceToken?.Description;
if (!IsNullOrWhiteSpace(myDeviceToken))
{
myDeviceToken = myDeviceToken.Trim('<').Trim('>').Replace(" ", "");
Settings.DeviceTokenForPush = myDeviceToken;
}
Localytics.SetPushToken(deviceToken);
}
/// <summary>
/// Processes the notification.
/// </summary>
/// <param name="options">Options.</param>
public static void ProcessNotification(NSDictionary options)
{
var presenter = (MvxIosViewPresenter) Mvx.Resolve<IMvxIosViewPresenter>();
if (options != null && options.ContainsKey(new NSString("statements")))
if (presenter.TabBarViewController != null)
{
var tabBarController = (TabBarController) presenter.TabBarViewController;
Settings.CurrentTrafficSource = JobrapidoTrafficSource.Notification;
tabBarController.ViewModel.JobOpportunityCommand.ExecuteAsync(options
.ObjectForKey(new NSString("statements")).ToString());
tabBarController.SelectedIndex = 1;
UIApplication.SharedApplication.CancelAllLocalNotifications();
return;
}
if (UIApplication.SharedApplication.ApplicationIconBadgeNumber <= 0) return;
{
Settings.CurrentTrafficSource = JobrapidoTrafficSource.Notification;
if (presenter.TabBarViewController == null) return;
var tabBarController = (TabBarController) presenter.TabBarViewController;
tabBarController.ViewModel.JobOpportunityCommand.Execute(null);
tabBarController.SelectedIndex = 1;
UIApplication.SharedApplication.CancelAllLocalNotifications();
}
}
public override void WillEnterForeground(UIApplication application)
{
base.WillEnterForeground(application);
Settings.CurrentTrafficSource = JobrapidoTrafficSource.None;
Localytics.OpenSession();
Localytics.Upload();
}
public override bool WillContinueUserActivity(UIApplication application, string userActivityType)
{
return true;
}
// Support Universal Links
public override bool ContinueUserActivity(UIApplication application, NSUserActivity userActivity,
UIApplicationRestorationHandler completionHandler)
{
if (!userActivity.ActivityType.Equals(NSUserActivityType.BrowsingWeb))
return DynamicLinks.SharedInstance.HandleUniversalLink(userActivity.WebPageUrl, (dynamicLink, error) =>
{
if (error != null)
return;
if (dynamicLink.Url == null)
return;
if (IsNullOrWhiteSpace(dynamicLink.Url.Path) || dynamicLink.Url.Path == "/")
return;
OpenUrl(application, new NSUrl(dynamicLink.Url.AbsoluteString), "Firebase Dynamic Link", null);
});
var universalLink = userActivity.WebPageUrl.AbsoluteString;
OpenUrl(application, new NSUrl(universalLink), "Universal Link", null);
return true;
}
public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options)
{
var openUrlOptions = new UIApplicationOpenUrlOptions(options);
OpenUrl(app, url, openUrlOptions.SourceApplication, openUrlOptions.Annotation);
return true;
}
public override void OnActivated(UIApplication application)
{
AppEvents.ActivateApp();
Settings.CurrentTrafficSource = JobrapidoTrafficSource.None;
if (application.ApplicationIconBadgeNumber > 0)
{
Settings.CurrentTrafficSource = JobrapidoTrafficSource.Notification;
var parameters = new Dictionary<string, string>
{
{"BadgeValue", UIApplication.SharedApplication.ApplicationIconBadgeNumber.ToString()}
};
LocalyticsApi.LogEvent("OpenAppFromBadge", parameters);
}
Localytics.OpenSession();
Localytics.Upload();
}
public override bool OpenUrl(UIApplication application, NSUrl url, string sourceApplication,
NSObject annotation)
{
Debug.Write("url: " + url);
var dynamicLink = DynamicLinks.SharedInstance?.FromUniversalLinkUrl(url) ??
DynamicLinks.SharedInstance?.FromCustomSchemeUrl(url);
Debug.Write("dynamicLink: " + dynamicLink);
if (true.Equals(url?.AbsoluteUrl?.ToString()?.Contains("fb1565183867039238")))
return ApplicationDelegate.SharedInstance.OpenUrl(application, url, sourceApplication, annotation);
if (true.Equals(url?.AbsoluteUrl?.ToString()?.StartsWith("com.google")))
return SignIn.SharedInstance.HandleUrl(url, sourceApplication ?? "com.apple.SafariViewService",
new NSObject());
if (!true.Equals(url?.AbsoluteUrl?.ToString()?.Contains("jobrapido")) &&
(dynamicLink == null || !true.Equals(dynamicLink?.Url?
.AbsoluteUrl?.ToString()
.Contains("jobrapido")))) return Localytics.HandleTestModeURL(url);
if (!IsNullOrEmpty(sourceApplication) && sourceApplication != "Universal Link")
Settings.CurrentTrafficSource = JobrapidoTrafficSource.Localytics;
Debug.WriteLine("url: " + url);
SelectViewController(dynamicLink != null ? dynamicLink.Url : url);
return true;
}
private static void SelectViewController(NSUrl url)
{
var found = false;
Debug.WriteLine("NSUrl url: " + url);
Debug.WriteLine("url.AbsoluteString: " + url.AbsoluteString);
if (url.AbsoluteString.Contains("notification"))
{
Utils.RequestRegistrationToPushNotification(null);
return;
}
if (url.AbsoluteString.Contains("review"))
{
if (UIDevice.CurrentDevice.CheckSystemVersion(10, 3))
SKStoreReviewController.RequestReview();
else
UIApplication.SharedApplication.OpenUrl(
new NSUrl("itms-apps://itunes.apple.com/app/id842642357?action=write-review"));
return;
}
var presenter = (CustomMvxIosViewPresenter) Mvx.Resolve<IMvxIosViewPresenter>();
if (presenter.TabBarViewController != null)
{
var tabBarController = presenter.TabBarViewController as TabBarController;
found = true;
if (tabBarController != null)
{
var viewModel = tabBarController.ViewModel as BaseViewModel;
viewModel.ExternalCallRoutingCommand.ExecuteAsync(url.AbsoluteString);
}
}
else
{
Utils.BaseViewModelAssembler.ExternalCallRouting(url.AbsoluteString);
}
if (found) return;
{
if (!(RootViewController is MvxNavigationController)) return;
var viewController = (MvxNavigationController) RootViewController;
BaseViewModel viewModel;
var controller = viewController.VisibleViewController as TabBarController;
if (controller != null)
viewModel = controller.ViewModel;
else
viewModel = ((MvxViewController) viewController.VisibleViewController).ViewModel as BaseViewModel;
if (viewModel == null) return;
if (url.AbsoluteString != null && url.AbsoluteString.Contains("confirmation"))
viewModel.ExternalCallRoutingCommand.ExecuteAsync(url.AbsoluteString);
}
}
public override void DidEnterBackground(UIApplication application)
{
Localytics.DismissCurrentInAppMessage();
Localytics.CloseSession();
Localytics.Upload();
Settings.CurrentTrafficSource = JobrapidoTrafficSource.None;
base.DidEnterBackground(application);
}
public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo,
Action<UIBackgroundFetchResult> completionHandler)
{
ProcessNotification(userInfo);
Localytics.DidReceiveNotificationResponseWithUserInfo(userInfo);
completionHandler(UIBackgroundFetchResult.NoData);
}
public override void ReceivedRemoteNotification(UIApplication application, NSDictionary userInfo)
{
ProcessNotification(userInfo);
}
#region Property Class
[Export("window")]
private static UIWindow Window { get; set; }
//AppsFlyerTracker tracker = AppsFlyerTracker.SharedTracker();
private readonly Dictionary<string, object> connectFlags = new Dictionary<string, object>();
private static readonly string ENABLE_LOGGING_IOS = "TJC_OPTION_ENABLE_LOGGING";
public static readonly string TrackingId = "UA-23280831-4";
private static readonly string LocalyticsId = "cd09c17c0db3b7b45b009aa-a6d3d866-e085-11e5-ab8b-00342b7f5075";
public static bool IsIphone4S => UIScreen.MainScreen.Bounds.Size.Height == 480;
public static bool IsIphone5 => UIScreen.MainScreen.Bounds.Size.Height == 568;
public static bool IsIphone6 => UIScreen.MainScreen.Bounds.Size.Height == 667;
public static bool IsIphone6Plus => UIScreen.MainScreen.Bounds.Size.Height == 736;
public static UIViewController VisibleViewController
{
get
{
var visibleViewController = RootViewController;
if (!(visibleViewController is MvxNavigationController)) return visibleViewController;
visibleViewController = ((MvxNavigationController) visibleViewController).VisibleViewController;
if ((visibleViewController as TabBarController)?.VisibleUIViewController != null)
visibleViewController = ((TabBarController) visibleViewController).VisibleUIViewController;
return visibleViewController;
}
}
public static UIViewController RootViewController
{
get
{
var presenter = (MvxIosViewPresenter) Mvx.Resolve<IMvxIosViewPresenter>();
UIViewController rootViewController;
if (presenter.MasterNavigationController != null)
rootViewController = presenter.MasterNavigationController;
else if (((TabBarController) presenter.TabBarViewController)?.VisibleUIViewController != null)
rootViewController = ((TabBarController) presenter.TabBarViewController).VisibleUIViewController;
else
rootViewController = UIApplication.SharedApplication.Windows.Where(x =>
x.RootViewController != null && !string.Equals(x.RootViewController.Class.Name,
"UIInputWindowController", StringComparison.CurrentCultureIgnoreCase)
&& x.RootViewController.Class.Name.ToLower() != "uitexteffectwindow"
&& !string.Equals(x.RootViewController.Class.Name,
"UIApplicationRotationFollowingControllerNoTouches",
StringComparison.CurrentCultureIgnoreCase))
.OrderByDescending(w => w.WindowLevel).FirstOrDefault()?.RootViewController;
return rootViewController;
}
}
#endregion
}
}
{
"request_id":"2a8c222f-7db0-49e3-ba36-64ddab9f2255",
"campaign_key":"JA-IT",
"target_type":"customer_id",
"messages":[
{
"target":"290261032341",
"alert":"New job offers for you!",
"ios":{
"badge": 2,
"extra":{
"statements":"java||1~test|ke|4"
}
}
}
]
}
package net.jobrapido.bo.pushnotification;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
public final class LocalyticsPayload {
public final String request_id;
public final String campaign_key;
public final String target_type;
public final Message messages[];
@JsonCreator
public LocalyticsPayload(@JsonProperty("request_id") final String request_id, @JsonProperty("campaign_key") final String campaign_key,
@JsonProperty("target_type") final String target_type, @JsonProperty("messages") final Message[] messages) {
this.request_id = request_id;
this.campaign_key = campaign_key;
this.target_type = target_type;
this.messages = messages;
}
public static final class Message {
public final String target;
public final String alert;
public final Ios ios;
@JsonCreator
public Message(@JsonProperty("target") final String target, @JsonProperty("alert") final String alert,
@JsonProperty("ios") final Ios ios) {
this.target = target;
this.alert = alert;
this.ios = ios;
}
public static final class Ios {
public final long badge;
public final Extra extra;
@JsonCreator
public Ios(@JsonProperty("badge") final int badge, @JsonProperty("extra") final Extra extra) {
this.badge = badge;
this.extra = extra;
}
}
public static final class Extra {
public final String statements;
@JsonCreator
public Extra(@JsonProperty("statements") final String statements) {
this.statements = statements;
}
}
}
}
import org.apache.commons.codec.binary.Base64;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.log4j.Logger;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
public static String AUTHORIZATION_HEADER_LOCALYTICS = "Basic "
+ new String(Base64.encodeBase64(("fb23feae03b95ded50f0d48-b3b206f6-4fb5-11e5-8a24-003e57fecdee"
+ ":" + "5d5222dc0eec04438d13ff6-b3b20b00-4fb5-11e5-8a24-003e57fecdee").getBytes()));
public static JobSeekerLogEvent sendPushNotificationWithLocalytics(final String customerId)
throws Exception {
JobSeekerLogEvent pushResult = JobSeekerLogEvent.SYSTEM_PUSH_NOTIFICATION_ERROR;
final List<Message> alerts = new ArrayList<>();
final String message = "New job offers for you!";
final String extra = "java||1~test|ke|4"; // EXAMPLE DATA: this value change for each customer
final int searchesWithNewJobs = 2; // EXAMPLE DATA: this value change for each customer
alerts.add(new Message(customerId,
message,
new Ios(searchesWithNewJobs, new Extra(extra))));
final Message[] alertArr = new Message[alerts.size()];
final LocalyticsPayload payload = new LocalyticsPayload(UUID.randomUUID().toString(), "JA-"
+ JE.System.Config.getLocaleCountry(), "customer_id", alerts.toArray(alertArr));
if (notifyByLocalytics(payload)) {
pushResult = JobSeekerLogEvent.SYSTEM_PUSH_NOTIFICATION_ALERT;
}
return pushResult;
}
public static boolean notifyByLocalytics(final LocalyticsPayload payload) throws Exception {
final String appId = "cd09c17c0db3b7b45b009aa-a6d3d866-e085-11e5-ab8b-00342b7f5075";
return sendToLocalytics(new ObjectMapper().writeValueAsString(payload),
"https://messaging.localytics.com/v2/push/" + appId);
}
private static boolean sendToLocalytics(final String json, final String url) throws Exception
{
boolean bResult = false;
try (final CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
final HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new StringEntity(json, ContentType.APPLICATION_JSON));
httpPost.setHeader("Authorization", AUTHORIZATION_HEADER_LOCALYTICS);
final int statusCode = httpClient.execute(httpPost).getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_ACCEPTED) {
bResult = true;
} else {
logger.error("Localytics Status Code: " + statusCode);
logger.error("Url: " + url);
logger.error("Authentication Header: " + AUTHORIZATION_HEADER_LOCALYTICS);
logger.error("Json is: " + json);
}
}
return bResult;
}
public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
var myDeviceToken = deviceToken?.Description;
if (!IsNullOrWhiteSpace(myDeviceToken))
{
myDeviceToken = myDeviceToken.Trim('<').Trim('>').Replace(" ", "");
Settings.DeviceTokenForPush = myDeviceToken;
}
Localytics.SetPushToken(deviceToken);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment