There's nothing wrong with passing state around. In general I find it preferable as you are less likely to need to change it later if you need more data in the function.
Dialyzer didn't catch this because out_socket is a tuple. Which could be a record of type apns_msg.