[Solved] iOS Push Notifications (code included)

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:

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

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")

use LenB instead of Len, please.

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

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")

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 :slight_smile:

Will be great :slight_smile:

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

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)

[code] //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
[/code]

next is when socket is Connected:

[code] if firstCon=true then
Print(“We are connected with the Socket!”)
firstCon=false
end if

print"------------------------------"
sendPush //send out a PushNotification
print"------------------------------"

[/code]

in sendPush are:

[code] 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[/code]

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

[code] 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[/code]

Thanks to Christian for fixing the Problem with the deviceToken

Greetings

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

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

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

[quote=44805:@Christian Bader]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)

[code] //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
[/code]

next is when socket is Connected:

[code] if firstCon=true then
Print(“We are connected with the Socket!”)
firstCon=false
end if

print"------------------------------"
sendPush //send out a PushNotification
print"------------------------------"

[/code]

in sendPush are:

[code] 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[/code]

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

[code] 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[/code]

Thanks to Christian for fixing the Problem with the deviceToken

Greetings[/quote]