[Solved] iOS Push Notifications (code included)

  1. 6 years ago

    Christian B

    7 Nov 2013 Pre-Release Testers
    Edited 6 years ago

    Hello, i trying now since two Days to sending out Push Notifications to Server.. but i am not so good in working with Bytes in XOJO.

    Here my Problem.. i want to convert my PHP Code to Xojo.. but i dont get it to Work..

    String need to look so:
    -image-
    PHP Code (WORKS):

    // in payload is a JSON Obj
    // deviceToken is my DeviceToken like: 26d2c345998sd18d0ac5e6fbd1578125c71062cdxx2031215edc07f99fd474fc (modified some parts)
    chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;

    I dont know how to convert this to Xojo.. maybe anyone can help me..

    Greetings

    i allready wrote the complete Code with comments for this project to interprate.. here the quote:

    @Christian B ok.. not with interface.. i have done it now with a console application and just test values.. but it works.. i think evryone would be able to translate / modify this code and here it is:

    First: Etablish a Connection to Apple Push Notification Server (use SSLSocket instead of TCPSocket) (you need a own ca for this)

      //Get CA File
      dim f as FolderItem
      f = New FolderItem("/Users/cba/Sites/phpSimplePush/ck.pem",FolderItem.PathTypeShell)
      Dim versuch as Integer
      
      //Create new Socket
      cSocket = new gSocket
      
      //CA File there?
      if f<>Nil then
        //Set parameter
        cSocket.CertificateFile=f
        cSocket.CertificatePassword="passwort"
        cSocket.Secure=true
        cSocket.ConnectionType=cSocket.TLSv1
        cSocket.Address="gateway.sandbox.push.apple.com"
        cSocket.Port=2195
      else
        Print"Certificate is missing!"
        Return
      end if
      
      
      //connect the socket
      cSocket.Connect
      
      
      //while the socket isn't connected
      While Not cSocket.SSLConnected
        //check to see if the socket got an error
        If cSocket.LastErrorCode <> 0 then
          Exit
        End If
        
        //poll the socket to let it do its thing
        cSocket.Poll
      Wend
      
      //if we broke the loop because we're connected
      If cSocket.SSLConnected then
        
      Else
        
        'Print"Error in Connection"
        LoadSocket //Try again to connect
      End If
      

    next is when socket is Connected:

      if firstCon=true then
        Print("We are connected with the Socket!")
        firstCon=false
      end if
      
      
      print"------------------------------"
      sendPush //send out a PushNotification
      print"------------------------------"
      
      

    in sendPush are:

      Dim versuch as Integer = 125
      Dim push as String = "{"+chr(34)+"aps"+chr(34)+":{"+chr(34)+"alert"+chr(34)+":"+chr(34)+"Test!"+chr(34)+","+chr(34)+"sound"+chr(34)+":"+chr(34)+"default"+chr(34)+"}}"
      Dim aps as New JSONItem(push)
      Dim packet As String
      
      //Brings actually a finished value back Parameters are not used yet!
      packet = packNotification(0, "DOSENT MATTER BECOUSE I USE FOR TESTING FIXED VALUES", aps.ToString)
      counting=counting+1 //Count how much APNs are sended
      print str(counting) //Print Count of ABNs
      
      cSocket.Write(packet) //send out APN
      cSocket.Poll

    and in packNotification are (warning.. parameters are not used yet but you are able to modify it w/o problems:

    command as Byte, token as String, payload as String returns String

      Dim r As New Random //randomizer for testing
      Dim ri As Integer = r.InRange(0, 1)
      
      if ri = 0 then
        token = "devicetoken" //use parameter or replace this part with your devicetoken
      elseif ri = 1 then
        token = "devicetoken" 
      end if
      Dim tokenMB As MemoryBlock = (token) //iOS Device token
      Dim payloadMB As MemoryBlock = payload //JSON String
      Dim packet As New MemoryBlock(5 + tokenMB.Size + payloadMB.Size) //Complete PacketSize (in this example 117 Bytes)
      Dim pos As Integer //Define Packet Position
      Dim i As Integer
      
      packet.LittleEndian = false //Make Packet BigEndian
      
      packet.Byte(0) = 0 //Command
      
      packet.Int16Value(1) = 32 //tokenSize
      pos = 3 //define next position in MemoryBlock
      dim pSize as Integer = (Len(payload)) //define Length from jSON String
      
      packet.StringValue(pos,32) = decodehex(token) //Put the Token into the MemBlock
      pos = pos + 32 //Define next position in MemoryBlock
      
      packet.Int16Value(pos) = payloadMB.Size //Put the JSON String Size into the MemBlock
      pos = pos + 2 //Define next position in MemoryBlock
      
      
      i = 0
      while i < payloadMB.Size
        packet.Byte(pos) = payloadMB.Byte(i)  //Put the JSON Bytes into the MemBlock
        i = i + 1
        pos = pos + 1
      wend
      
      
      return packet

    Thanks to Christian for fixing the Problem with the deviceToken

    Greetings

  2. Alwyn B

    7 Nov 2013 Pre-Release Testers, Xojo Pro Johannesburg, South Africa
    Edited 6 years ago

    You can try this method, I haven't tested it though...

    Function packNotification(command As Byte, token As String, payload As String) As String
      Dim packet As New MemoryBlock(5 + Len(token) + Len(payload))
      Dim pos As Integer
      Dim i As Integer
      Dim tokenMB As  MemoryBlock = token
      Dim payloadMB As MemoryBlock = payload
      
      packet.LittleEndian = false
      
       ' command
      
      packet.Byte(0) = 0
      
      ' token length
      
      packet.Int16Value(1) = tokenMB.Size
      pos = 3
      
      ' token
      
      i = 0
      while i < tokenMB.Size
        packet.Byte(pos) = tokenMB.Byte(i)
        i = i + 1
        pos = pos + 1
      wend
      
      ' payload length
      
      packet.Int16Value(pos) = payloadMB.Size
      pos = pos + 2
      
      ' token
      
      i = 0
      while i < payloadMB.Size
        packet.Byte(pos) = payloadMB.Byte(i)
        i = i + 1
        pos = pos + 1
      wend
      
      return packet
      
    End Function

    You would use it as follow...

    Dim packet As string
      
    packet = packNotification(0, "my token", "my payload")
  3. Christian S

    7 Nov 2013 Pre-Release Testers, Xojo Pro, XDC Speakers, Third Party Store Germany

    use LenB instead of Len, please.

  4. Christian B

    7 Nov 2013 Pre-Release Testers

    thanks for the code.. but theres left the conversation of the token. The Token is a Hex Value and it need to be in a Binary value.. (check phpCode: pack('H*', $deviceToken)

    Php pack = Pack given arguments into a binary string according to format.
    H = Hex string, high nibble first

  5. Alwyn B

    7 Nov 2013 Pre-Release Testers, Xojo Pro Johannesburg, South Africa
    Edited 6 years ago

    How about this...

    Function packNotification(command As Byte, token As String, payload As String) As String
      Dim tokenMB As MemoryBlock = DecodeHex(token)
      Dim payloadMB As MemoryBlock = payload
      Dim packet As New MemoryBlock(5 + tokenMB.Size + payloadMB.Size)
      Dim pos As Integer
      Dim i As Integer
      
      packet.LittleEndian = false
      
       ' command
      
      packet.Byte(0) = 0
      
      ' token length
      
      packet.Int16Value(1) = tokenMB.Size
      pos = 3
      
      ' token
      
      i = tokenMB.Size - 1
      while i >= 0
        packet.Byte(pos) = tokenMB.Byte(i)
        i = i - 1
        pos = pos + 1
      wend
      
      ' payload length
      
      packet.Int16Value(pos) = payloadMB.Size
      pos = pos + 2
      
      ' payload
      
      i = 0
      while i < payloadMB.Size
        packet.Byte(pos) = payloadMB.Byte(i)
        i = i + 1
        pos = pos + 1
      wend
      
      return packet
      
    End Function

    ...and then...

    Dim packet As string
      
    packet = packNotification(0, "aabbcc", "my payload")
  6. Christian S

    7 Nov 2013 Pre-Release Testers, Xojo Pro, XDC Speakers, Third Party Store Germany

    you put in the token reverse which is wrong.
    I fixed the problem with Christian's code earlier today on the phone, so maybe he can post our final code as example for others :-)

  7. Valdemar D

    7 Nov 2013 Pre-Release Testers, Xojo Pro Europe ( France, Paris )

    Will be great :)

  8. Christian B

    8 Nov 2013 Pre-Release Testers

    i will fix some last things in connection to apples SSL Server and then i will post the code including the Interface + pref file. so any iOS dev can use this code

    Greetings

  9. Christian B

    8 Nov 2013 Pre-Release Testers

    ok.. not with interface.. i have done it now with a console application and just test values.. but it works.. i think evryone would be able to translate / modify this code and here it is:

    First: Etablish a Connection to Apple Push Notification Server (use SSLSocket instead of TCPSocket) (you need a own ca for this)

      //Get CA File
      dim f as FolderItem
      f = New FolderItem("/Users/cba/Sites/phpSimplePush/ck.pem",FolderItem.PathTypeShell)
      Dim versuch as Integer
      
      //Create new Socket
      cSocket = new gSocket
      
      //CA File there?
      if f<>Nil then
        //Set parameter
        cSocket.CertificateFile=f
        cSocket.CertificatePassword="Latsyrc2"
        cSocket.Secure=true
        cSocket.ConnectionType=cSocket.TLSv1
        cSocket.Address="gateway.sandbox.push.apple.com"
        cSocket.Port=2195
      else
        Print"Certificate is missing!"
        Return
      end if
      
      
      //connect the socket
      cSocket.Connect
      
      
      //while the socket isn't connected
      While Not cSocket.SSLConnected
        //check to see if the socket got an error
        If cSocket.LastErrorCode <> 0 then
          Exit
        End If
        
        //poll the socket to let it do its thing
        cSocket.Poll
      Wend
      
      //if we broke the loop because we're connected
      If cSocket.SSLConnected then
        
      Else
        
        'Print"Error in Connection"
        LoadSocket //Try again to connect
      End If
      

    next is when socket is Connected:

      if firstCon=true then
        Print("We are connected with the Socket!")
        firstCon=false
      end if
      
      
      print"------------------------------"
      sendPush //send out a PushNotification
      print"------------------------------"
      
      

    in sendPush are:

      Dim versuch as Integer = 125
      Dim push as String = "{"+chr(34)+"aps"+chr(34)+":{"+chr(34)+"alert"+chr(34)+":"+chr(34)+"Test!"+chr(34)+","+chr(34)+"sound"+chr(34)+":"+chr(34)+"default"+chr(34)+"}}"
      Dim aps as New JSONItem(push)
      Dim packet As String
      
      //Brings actually a finished value back Parameters are not used yet!
      packet = packNotification(0, "DOSENT MATTER BECOUSE I USE FOR TESTING FIXED VALUES", aps.ToString)
      counting=counting+1 //Count how much APNs are sended
      print str(counting) //Print Count of ABNs
      
      cSocket.Write(packet) //send out APN
      cSocket.Poll

    and in packNotification are (warning.. parameters are not used yet but you are able to modify it w/o problems:

    command as Byte, token as String, payload as String returns String

      Dim r As New Random //randomizer for testing
      Dim ri As Integer = r.InRange(0, 1)
      
      if ri = 0 then
        token = "devicetoken" //use parameter or replace this part with your devicetoken
      elseif ri = 1 then
        token = "devicetoken" 
      end if
      Dim tokenMB As MemoryBlock = (token) //iOS Device token
      Dim payloadMB As MemoryBlock = payload //JSON String
      Dim packet As New MemoryBlock(5 + tokenMB.Size + payloadMB.Size) //Complete PacketSize (in this example 117 Bytes)
      Dim pos As Integer //Define Packet Position
      Dim i As Integer
      
      packet.LittleEndian = false //Make Packet BigEndian
      
      packet.Byte(0) = 0 //Command
      
      packet.Int16Value(1) = 32 //tokenSize
      pos = 3 //define next position in MemoryBlock
      dim pSize as Integer = (Len(payload)) //define Length from jSON String
      
      packet.StringValue(pos,32) = decodehex(token) //Put the Token into the MemBlock
      pos = pos + 32 //Define next position in MemoryBlock
      
      packet.Int16Value(pos) = payloadMB.Size //Put the JSON String Size into the MemBlock
      pos = pos + 2 //Define next position in MemoryBlock
      
      
      i = 0
      while i < payloadMB.Size
        packet.Byte(pos) = payloadMB.Byte(i)  //Put the JSON Bytes into the MemBlock
        i = i + 1
        pos = pos + 1
      wend
      
      
      return packet

    Thanks to Christian for fixing the Problem with the deviceToken

    Greetings

  10. Valdemar D

    8 Nov 2013 Pre-Release Testers, Xojo Pro Europe ( France, Paris )

    Have you a sample project that we can download ?
    :)

  11. Roberto C

    26 Jan 2014 Pre-Release Testers, Xojo Pro Europe (Milan, Italy)

    Yes... Have you a sample project that we can download ? This could be nice for doing some tests! :)

  12. Christian B

    20 Feb 2014 Pre-Release Testers Answer

    i allready wrote the complete Code with comments for this project to interprate.. here the quote:

    @Christian B ok.. not with interface.. i have done it now with a console application and just test values.. but it works.. i think evryone would be able to translate / modify this code and here it is:

    First: Etablish a Connection to Apple Push Notification Server (use SSLSocket instead of TCPSocket) (you need a own ca for this)

      //Get CA File
      dim f as FolderItem
      f = New FolderItem("/Users/cba/Sites/phpSimplePush/ck.pem",FolderItem.PathTypeShell)
      Dim versuch as Integer
      
      //Create new Socket
      cSocket = new gSocket
      
      //CA File there?
      if f<>Nil then
        //Set parameter
        cSocket.CertificateFile=f
        cSocket.CertificatePassword="passwort"
        cSocket.Secure=true
        cSocket.ConnectionType=cSocket.TLSv1
        cSocket.Address="gateway.sandbox.push.apple.com"
        cSocket.Port=2195
      else
        Print"Certificate is missing!"
        Return
      end if
      
      
      //connect the socket
      cSocket.Connect
      
      
      //while the socket isn't connected
      While Not cSocket.SSLConnected
        //check to see if the socket got an error
        If cSocket.LastErrorCode <> 0 then
          Exit
        End If
        
        //poll the socket to let it do its thing
        cSocket.Poll
      Wend
      
      //if we broke the loop because we're connected
      If cSocket.SSLConnected then
        
      Else
        
        'Print"Error in Connection"
        LoadSocket //Try again to connect
      End If
      

    next is when socket is Connected:

      if firstCon=true then
        Print("We are connected with the Socket!")
        firstCon=false
      end if
      
      
      print"------------------------------"
      sendPush //send out a PushNotification
      print"------------------------------"
      
      

    in sendPush are:

      Dim versuch as Integer = 125
      Dim push as String = "{"+chr(34)+"aps"+chr(34)+":{"+chr(34)+"alert"+chr(34)+":"+chr(34)+"Test!"+chr(34)+","+chr(34)+"sound"+chr(34)+":"+chr(34)+"default"+chr(34)+"}}"
      Dim aps as New JSONItem(push)
      Dim packet As String
      
      //Brings actually a finished value back Parameters are not used yet!
      packet = packNotification(0, "DOSENT MATTER BECOUSE I USE FOR TESTING FIXED VALUES", aps.ToString)
      counting=counting+1 //Count how much APNs are sended
      print str(counting) //Print Count of ABNs
      
      cSocket.Write(packet) //send out APN
      cSocket.Poll

    and in packNotification are (warning.. parameters are not used yet but you are able to modify it w/o problems:

    command as Byte, token as String, payload as String returns String

      Dim r As New Random //randomizer for testing
      Dim ri As Integer = r.InRange(0, 1)
      
      if ri = 0 then
        token = "devicetoken" //use parameter or replace this part with your devicetoken
      elseif ri = 1 then
        token = "devicetoken" 
      end if
      Dim tokenMB As MemoryBlock = (token) //iOS Device token
      Dim payloadMB As MemoryBlock = payload //JSON String
      Dim packet As New MemoryBlock(5 + tokenMB.Size + payloadMB.Size) //Complete PacketSize (in this example 117 Bytes)
      Dim pos As Integer //Define Packet Position
      Dim i As Integer
      
      packet.LittleEndian = false //Make Packet BigEndian
      
      packet.Byte(0) = 0 //Command
      
      packet.Int16Value(1) = 32 //tokenSize
      pos = 3 //define next position in MemoryBlock
      dim pSize as Integer = (Len(payload)) //define Length from jSON String
      
      packet.StringValue(pos,32) = decodehex(token) //Put the Token into the MemBlock
      pos = pos + 32 //Define next position in MemoryBlock
      
      packet.Int16Value(pos) = payloadMB.Size //Put the JSON String Size into the MemBlock
      pos = pos + 2 //Define next position in MemoryBlock
      
      
      i = 0
      while i < payloadMB.Size
        packet.Byte(pos) = payloadMB.Byte(i)  //Put the JSON Bytes into the MemBlock
        i = i + 1
        pos = pos + 1
      wend
      
      
      return packet

    Thanks to Christian for fixing the Problem with the deviceToken

    Greetings

or Sign Up to reply!