iOS Question Trying to get silent push notifications working

Discussion in 'iOS Questions' started by henrywood, Apr 14, 2015.

  1. henrywood

    henrywood Active Member Licensed User

    I am trying to grasp push notifications on iOS and also trying to get silent notifications working.

    Silent notifications should be supported on iOS7+ according to http://hayageek.com/ios-silent-push-notifications/

    I have this code:

    Code:
    'Code module
    #Region  Project Attributes
       
    #ApplicationLabel: B4i Example
       
    #Version: 1.0.0
       
    'Orientation possible values: Portrait, LandscapeLeft, LandscapeRight and PortraitUpsideDown
       ' FIXME
       #iPhoneOrientations: Portrait, LandscapeLeft, LandscapeRight
       
    #iPadOrientations: Portrait, LandscapeLeft, LandscapeRight, PortraitUpsideDown

       
    ' Register for *SILENT* push notifications
       #PlistExtra: <key>UIBackgroundModes</key><array><string>remote-notification</string></array>

       
    ' DEFAULT APP FONT
       #AppFont: roboto-light.ttf

    #End Region

    Sub Process_Globals
       
    'These global variables will be declared once when the application starts.
       'Public variables can be accessed from all modules.
       Public App As Application
       
    Public NavControl As NavigationController
       
    Private Page As Page

       
    Dim theURI As String

       
    Dim Const POSITION_TOP_LEFT As Int  = 1
       
    Dim Const POSITION_TOP_RIGHT As Int = 2
       
    Dim Const POSITION_BOTTOM_LEFT As Int = 3
       
    Dim Const POSITION_BOTTOM_RIGHT As Int = 4
       
    Dim Const POSITION_CENTER As Int = 5

       
    Public Const ADS_GRACE_PERIOD_DAYS As Int = 7           '   7 Days grace period for ads

       
    ' Valid anims:    zoom_enter, zoom_exit
       '         card_flip_left_in, card_flip_left_out
       '         card_flip_right_in, card_flip_right_out
       '         fade_out, fade_in
       Public ACTIVITY_ANIMATION_IN_DEFAULT As String = "zoom_enter"   '   Default inAnimation
       Public ACTIVITY_ANIMATION_OUT_DEFAULT As String = "zoom_exit"   '   Default OutAnimation

       
    ' Get from Google Console
       Dim GCM_API_KEY As String = "XXXXX"

       
    #If B4A
         
    Dim locale As AHLocale : locale.Initialize
         
    Dim trans As AHTranslator : trans.Initialize(File.DirAssets, locale.ISOCode)
         
    Dim dt As AHDateTime : dt.Initialize
       
    #End if

       
    Public CURRENTUSER As User
       
    Public CurrentNumberOfBeaconsToday As Int = 0

       
    ' Global ACTIVITY DESIGN
       Public Const DEFAULT_FONT As String = "roboto-light.ttf"
       
    Public Const DEFAULT_HEADLINE_SIZE As Int = 20
       
    Public Const FULLSCREEN_ON_GLOBALLY As Boolean = True
       
    Public Const ACTIVITY_GLOBAL_BG_COLOR As Int = Colors.ARGB(255255255255)
       
    Public Const ACTIVITY_GLOBAL_TXT_COLOR As Int = Colors.ARGB(000,0 )

       
    Public STARTED_FROM_HOME_PAGE_SHORTCUT As Boolean = False

       
    Public Const TOPMENU_MAX_NUMBER_OF_VISIBLE_ITEMS_AT_A_TIME As Int = 8
       
    Public Const DIALOGS_ANIMATION_DEFAULT As String = "zoom"     '   Default animation to use when showing dialogs
                                       '   Available animations:
                                       '   zoom
                                       '   slide_from_top, slide_from_top_and_back
                                       '   slide_from_bottom, slide_from_bottom_and_back,
                                       '   slide_from_left,slide_from_left_and_back,
                                       '   slide_from_right,slide_from_right_and_back
       Dim GPS1 As Location
       
    Dim DB As SQL

       
    'This code is essential if you want to use the menu for most activity.
       Dim MenuItem As List

       
    ' TODO: Add support for only showing X (configurable at signup) ads from the same company within a 24 hour
       '     window...


       
    Dim TRACKING_SIMILARITY_PCT As Double = 80.00

       
    ' TIMERS
       Dim Clear24Timer As Timer
       
    Dim CLEAR_SEEN_ADS_24_INTERVAL As Int = 864000000 : Clear24Timer.Initialize("Clear24Timer", CLEAR_SEEN_ADS_24_INTERVAL) : Clear24Timer.Enabled = True' Every 24 hours
       Dim AdsSeenTimer As Timer : AdsSeenTimer.Initialize("AdsSeenTimer", ADS_GRACE_PERIOD_DAYS * 86400) : AdsSeenTimer.Enabled = True

       
    Dim DEVICE_ID As String

       
    Dim PROXIMITY_THRESHOLD_NEAR As Int = 5
       
    Dim PROXIMITY_THRESHOLD_MIDDLE As Int = 15
       
    Dim PROXIMITY_THRESHOLD_FAR As Int = 400
       
    #If DEBUG
       Dim APP_VENDOR_ID As String = "F782DA6-4FA2-4E98-8024-BC5B71E0893E"
       Dim APP_APPLICATION_NAME As String = ":%s" ' This string *MUST* match the ProximityUUID of the ANDROID APP !!!
       
    #End If
       
    #If RELEASE
       Dim APP_VENDOR_ID As String = "FE1D7269-84E6-4E54-BD95-8447D088ED6F"
       Dim APP_APPLICATION_NAME As String = "xxxx:%s" ' This string *MUST* match the ProximityUUID of the iOS APP !!!
       
    #End If

       
    #IF DEBUG
       Public Const DEBUG As Boolean = True
       
    #End If
       
    #If RELEASE
       Public Const DEBUG As Boolean = False
       
    #End If
       
    #If RELEASE_INTERNAL
       Public Const DEBUG As Boolean =  True
       
    #End If

       
    ' MAPS AND LISTS
       Public AdsSeen As Map : AdsSeen.Initialize
       
    Public knownBeacons As Map : knownBeacons.Initialize

       
    Dim DB_FILENAME As String = "db.db"
     

    End Sub

    Private Sub Application_Start (Nav As NavigationController)

       NavControl = Nav

       
    ' Register for push notifications
       App.RegisterUserNotifications(TrueTrueTrue'allow badge, sound and alert
       App.RegisterForRemoteNotifications
       CheckForPushMessage

       
    ' Go to First page
       FirstPage.Show

    End Sub

    #Region PUSH NOTIFICATIONS

    Private Sub CheckForPushMessage

       
    If App.LaunchOptions.IsInitialized AND _
         App.LaunchOptions.ContainsKey(
    "UIApplicationLaunchOptionsRemoteNotificationKey"Then
         
    Dim data As Object = app.LaunchOptions.Get("UIApplicationLaunchOptionsRemoteNotificationKey")
         
    Dim no As NativeObject = app
         no.GetField(
    "delegate").RunMethod("application:didReceiveRemoteNotification:", _
                           
    Array(App, data))
         
    End If

    End Sub

    ' TODO: Is this sub called *ONLY* when the device is first registered for PUSH NOTIFICATIONS ???
    Private Sub Application_PushToken (Success As Boolean, Token() As Byte)

         
    If Success Then
       
         
    Dim bc As ByteConverter
         
    Dim j As HttpJob
         j.Initialize(
    "j", Me)
         
    'Dim paramsStr As String = "deviceID="&Main.DEVICE_ID&"&uuid="&Main.CURRENTUSER.ID&"&apptype=IOS&app="&Main.APP_APPLICATION_NAME.Replace("%s", "")
         Dim paramsStr As String = "deviceID=" & bc.HexFromBytes(Token) & "&uuid="&CURRENTUSER.ID&"&apptype=IOS&app="&APP_APPLICATION_NAME.Replace("%s""")
         j.PostString(Callbacks.CB_DEVICE_REGISTRATION_URL & paramsStr)
         
    Else
         Utils.Log_(
    "Error getting token: " & LastException)
         
    End If

    End Sub

    ' Called if the app is not in the foreground
    Private Sub Application_RemoteNotification (Message As Map)

         
    If DEBUG Then
         Utils.Log_(
    "Remote notification: " & Message)
         
    End If

       
    Dim m As Map = Message.Get("aps")
         
    Dim tempMap As Map = Message.Get("data")
       
    Dim thetype As String = tempMap.Get("type")

       
    ' Parse the Data
       Dim Map1 As Map
       
    Dim List1 As List
       Map1.Initialize
       List1.Initialize

       
    Dim TYPE_OF_NOTIFICATION As Int = thetype

       
    If m.Get("content-available") = "1" Then       '   It's a silent notification

           
    ' Select what to do
         Select TYPE_OF_NOTIFICATION

           
    Case PushIncomingHandler.NOTIFICATION_TYPE_BEACONS_FOUND_CLEAR
             knownBeacons.Clear
       
           
    Case PushIncomingHandler.NOTIFICATION_TYPE_COMPANY_BOUGHT_MEMBERSHIP_ADDON

             Map1 = tempMap.Get(
    "data")
             PushIncomingHandler.MarkThatCompanyHasMembership(Map1)
       
           
    Case PushIncomingHandler.NOTIFICATION_TYPE_COMPANY_CANCELLED_MEMBERSHIP_ADDON
             Map1 = tempMap.Get(
    "data")
             PushIncomingHandler.RemoveThatCompanyHasMembership(Map1)
       
           
    Case PushIncomingHandler.NOTIFICATION_TYPE_DELETED_CATEGORIES
             List1 = tempMap.Get(
    "data")
             PushIncomingHandler.DeleteCategories(List1)
       
           
    Case PushIncomingHandler.NOTIFICATION_TYPE_DELETED_TAGS
             List1 = tempMap.Get(
    "data")
             PushIncomingHandler.DeleteTags(List1)

           
    Case PushIncomingHandler.NOTIFICATION_TYPE_DO_APPLICATION_UPDATE
               Map1 = tempMap.Get(
    "data")
               
    Dim v As String = Map1.Get("version")
               CallSubDelayed2(Updater, 
    "AskUpdate", v)
           
           
    Case PushIncomingHandler.NOTIFICATION_TYPE_EDITED_COMPANY
             Map1 = tempMap.Get(
    "data")
             PushIncomingHandler.updateCompanyNaming(Map1)

           
    Case PushIncomingHandler.NOTIFICATION_TYPE_NEW_CATEGORY_ADDED
             Map1 = tempMap.Get(
    "data")
             PushIncomingHandler.addNewCategory(Map1)
       
           
    Case PushIncomingHandler.NOTIFICATION_TYPE_NEW_COMPANY
             Map1 = tempMap(
    "data")
             PushIncomingHandler.addNewCompany(Map1)

           
    Case PushIncomingHandler.NOTIFICATION_TYPE_NEW_SERVERS_INDEX
             PushIncomingHandler.reloadServersIndex

           
    Case PushIncomingHandler.NOTIFICATION_TYPE_NEW_TAGS_ADDED
             List1 = tempMap.Get(
    "data")
             PushIncomingHandler.addNewTags(List1) 

           
    Case PushIncomingHandler.NOTIFICATION_TYPE_PUSHED_AD_FROM_COMPANY
             Map1 = tempMap.Get(
    "data")
             CallSubDelayed2(AdViewer, 
    "onAdFromCompanyArrival", Map1)

           
    Case PushIncomingHandler.NOTIFICATION_TYPE_RELOAD_CATEGORY_TREE
             PushIncomingHandler.reloadCategoriesTree

           
    Case PushIncomingHandler.NOTIFICATION_TYPE_DELETED_COMPANIES
             List1 = tempMap.Get(
    "data")
             PushIncomingHandler.DeleteCompanies(List1)
       
           
    Case PushIncomingHandler.NOTIFICATION_TYPE_RELOAD_TAGS_INDEX
             PushIncomingHandler.reloadTagsIndex

           
    Case PushIncomingHandler.NOTIFICATION_TYPE_EDITED_LOCATION
             Map1 = tempMap.Get(
    "data")
             PushIncomingHandler.updateLocationInfo(Map1)
         
           
    Case PushIncomingHandler.NOTIFICATION_TYPE_NEW_LOCATIONS_ADDED
             List1 = tempMap.Get(
    "data")
             PushIncomingHandler.AddNewLocations(List1)
         
           
    Case PushIncomingHandler.NOTIFICATION_TYPE_DELETED_LOCATIONS
             List1 = tempMap.Get(
    "data")
             PushIncomingHandler.DeleteLocations(List1)

           
    Case PushIncomingHandler.NOTIFICATION_TYPE_DELETED_ADS
             List1 = tempMap.Get(
    "data")
             PushIncomingHandler.removeAdIDs(List1)
         
           
    Case PushIncomingHandler.NOTIFICATION_TYPE_EDITED_AD
             Map1 = tempMap.Get(
    "data")
             PushIncomingHandler.updateAd(Map1)
         
           
    Case PushIncomingHandler.NOTIFICATION_TYPE_NEW_AD_ADDED
             Map1 = tempMap.Get(
    "data")
             PushIncomingHandler.AddNewAd(Map1)
       
           
    ' When a user removes a friend from his friend list -> a notification of type
           ' "NOTIFICATION_TYPE_UNFRIEND_CURRENT_USER_FROM_REMOTE_USER" is sent to the device of
           ' the removed user. The message should carry info on what list the recipient should
           ' be removed from
           Case PushIncomingHandler.NOTIFICATION_TYPE_UNFRIEND_CURRENT_USER_FROM_REMOTE_USER
             Map1 = tempMap.Get(
    "data")
             PushIncomingHandler.UnfriendCurrentUserFrom(Map1)

           
    ' When a user adds a friend from his friend list -> a notification of type
           ' "NOTIFICATION_TYPE_UNFRIEND_CURRENT_USER_FROM_REMOTE_USER" is sent to the device of
           ' the removed user. The message should carry info on what list the recipient should
           ' be added from
           Case PushIncomingHandler.NOTIFICATION_TYPE_BEFRIEND_CURRENT_USER_WITH_REMOTE_USER
             Map1 = tempMap.Get(
    "data")
             PushIncomingHandler.BefriendCurrentUserWith(Map1)
       
           
    Case PushIncomingHandler.NOTIFICATION_TYPE_ADD_TO_A_SHARED_LIST
             Map1 = tempMap.Get(
    "data")
             PushIncomingHandler.receiveMessageForShoppingList(Map1)

           
    Case PushIncomingHandler.NOTIFICATION_TYPE_REMOVE_FROM_A_SHARED_LIST
             Map1 = tempMap.Get(
    "data")
             PushIncomingHandler.removeItemsFromUserFromShoppingList(Map1)

           
    Case Else
             
    If DEBUG Then
               Utils.Log_(
    "Unknown type of push notification received: "& TYPE_OF_NOTIFICATION)
             
    End If
         
         
    End Select

         
    If DEBUG Then
           Utils.Log_(
    "Received silent push notification: " & m)
         
    End If
     
         
    ' TODO: What do I need to call here for IOS to be happy ?

         
    Else                         '   Not a silent notification

           
    If DEBUG Then
           Utils.Log_(
    "Received a normal push notification: " & m)
           
    End If
     
         
    End If

    End Sub

    Private Sub JobDone(j As HttpJob)

       
    If j.Success Then
         
    If DEBUG Then
           Utils.Log_(
    "Token uploaded successfully.")
         
    End If
         
    Else
         
    If DEBUG Then
           Utils.Log_(
    "Error uploading token")
         
    End If
         
    End If

         j.Release

    End Sub

    #End Region

    Private Sub Page1_Resize(Width As Int, Height As Int)

    End Sub

    Private Sub Application_Background

    End Sub

    My questions:

    1. Is the "Application_PushToken" sub called *ONLY* when the device is first registered for PUSH NOTIFICATIONS (like the registration in GCM) - and is the event fired only once and only after calling
    App.RegisterUserNotifications(True, True, True) and
    App.RegisterForRemoteNotifications
    ?

    2. At the line that has the comment "TODO: What do I need to call here for IOS to be happy ?":
    What do I need to call for iOS to be happy ? What confuses me is what I've read here:
    http://www.g8production.com/post/72656082173/ios7-multitasking-silent-notifications about
    returning a UIBackgroundFetchResult ?

    All my processing of push notifications should be completed within the 30 seconds of wall clock time given by Apple. It simply updates the local DB with the data in the push message

    3. In the case where the user has not allowed push notifications, will the silent push notifications that I try to get working also be affected ? And if so, what is the alternative to using push notifications ?

    4. How can I find out if the user disallows or allows push notifications ? Can I react to some kind of event or can I read the settings ?

    5. Will "Application_RemoteNotification" sub be called regardless of wether or not my application is running/is in the foreground ?

    6. Is this line:
    #PlistExtra: <key>UIBackgroundModes</key><array><string>remote-notification</string></array>

    enough to support silent push notifications ?


    Sorry for a long post but I hope that the subject is of interest to others as well who are (like me) starting out on the journey of iOS development....


    Thanks


    /Henrik
     
    Last edited: Apr 14, 2015
  2. Erel

    Erel Administrator Staff Member Licensed User

    Currently it is not possible to intercept silent notifications as the app delegate doesn't implement the required method: application:didReceiveRemoteNotification:fetchCompletionHandler:
     
  3. henrywood

    henrywood Active Member Licensed User

    Since it is very important for me to have support for silent notifications (in order to finish the iOS version of my app), what are the chances that the next update to/version of B4i will support this method ?

    If needed I would be willing pay for this change (as otherwise I cannot finish my app)
     
  4. Erel

    Erel Administrator Staff Member Licensed User

    It is highly possible that it will be supported. However I don't know for now when it will be available. Sorry.
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice