Code Monkey home page Code Monkey logo

swiftphoenixclient's Issues

Support receive hooks

The phoenix js sdk allows to receive the reply to a pushed message:

// from the phoenix.js file
channel.push("new_msg", {body: e.target.val}, 10000)
.receive("ok", (msg) => console.log("created message", msg) )
.receive("error", (reasons) => console.log("create failed", reasons) )
.receive("timeout", () => console.log("Networking issue...") );

The receive("ok") callback will be called with the response_payload returned in the channel:

def handle_in("ping", payload, socket) do
  response_payload = %{"some_result" => 123}
  {:reply, {:ok, response_payload, socket}
end

This allows for an easier message -> reply style of programming when using channels. At the moment we do not have this functionality in the iOS SDK. The implementation in JS just listens for a phx_reply event and compares the ref ids.
I might look into that issue soon, but I guess it would require a little bit more work or refactoring. Also since it requires parsing json please first have a look at #49.

#join message argument does nothing...?

Howdy,

This could very well be a case of me missing the point, or just being an idiot, but from what I can tell and how I'd like to use this, setting a join message does nothing. Join calls rejoin, and correctly connects to the channel, but rejoin uses it's own hard coded message and payload.

E.g.

https://github.com/davidstump/SwiftPhoenixClient/blob/master/Pod/Classes/Phoenix.swift#L201-L216

    func rejoin(chan: Phoenix.Channel) {
      chan.reset()
      let joinMessage = Phoenix.Message(subject: "status", body: "joining")
      let payload = Phoenix.Payload(topic: chan.topic!, event: "phx_join", message: joinMessage)
      send(payload)
      chan.callback(chan)
    }

    public func join(topic  topic: String, message: Phoenix.Message, callback: (AnyObject -> Void)) {
      let chan = Phoenix.Channel(topic: topic, message: message, callback: callback, socket: self)
      channels.append(chan)
      if isConnected() {
        print("joining")
        rejoin(chan)
      }
    }

Is there something I'm missing from the guides that makes this behavior required or a reason why the message argument is even provided?

Update Documentation

CocoaPods is now all setup and pushed to trunk. Need to update documentation to reference installation and usage via CocoaPods.

Swift 3 Support

Hey there!

Just wanted to have a place to discuss Swift 3 issues.

I've started working on a migration now that Starscream has a branch supporting it. Any chance you could make a new branch here to push to?

Cheers.

Create a new 0.2.0 release tag, so we an push to CocoaPods

I think we have an old (unnecessary) release tag for 0.2.0. Can you create a new one so that we can push to CocoaPods?

I'm assuming that you have to create the release tags, since I don't think that they come across in my pull requests. Once the tag is created, I can push to CocoaPods (test out my ability to do so), if you'd like.

FYI: I'm preparing to create a Swift 2.0 branch, to support tvOS. I tried to use the existing code with a tvOS app and it barfed on syntax changes. So, I'd just like to wrap up the current version (as a pod release) before starting on Swift 2.0 things.

Leave not public and has wrong event

I've avoided creating a pull request for this as I'm hanging out for #17 to get pulled in, and my fork currently conflicts with that as it also fixes the same issue.

The leave methods on Phoenix.Socket and Phoenix.Channel aren't public, and the leave method that is there isn't using the right phx_leave event in the message. You can see my commit here for the fix: sjrmanning@8f652ad

Nothing happens when joining

I'm using a simple Phoenix instance, and have a simple channel join event working in js. I'm using the following on iOS:

    let socket = Socket(domainAndPort: "localhost:4000", path: "socket", transport: "websocket")
    socket.join(topic: "room:lobby", message: Message(subject: "status", body: "joining")) { channel in
        let channel = channel as! Channel
        print("join")
    }

But nothing is logged on the server. I'm watching the traffic going through the server's port 4000 and am seeing some packets flow every time I trigger the above code.

Not sure if I should post this in the Phoenix Framework project as well.

It is not possible to dealloc a socket instance.

When I am storing my socket in a property like

var socket: Phoenix.Socket?

and lets say I want to close the connection when the user performs a logout:

socket = nil

The socket is never deallocated because it has up to three NSTimers which hold a strong reference to the socket. (reconnect, hearbeat, sendBufferTimer).
A solution would be to expose a disconnect method which stops all timers and leaves all channels. The channels hold also a strong reference, which can be solved by #37 or automatically leaving all channels on disconnect.

Non Working Usage Example

When trying this example, from the bottom of the Channels and Events section in the Usage Guide:

/// Called before the `.on(event:, callback:)` hook is called for all events. Allows you to
/// hook in an manipulate or spy on the incoming payload before it is sent out to it's
/// bound handler. You must return the payload, modified or unmodified
channel.onMessage { (event, payload, ref) -> Payload in 
    payload["modified"] = true
    return payload 
}

XCode tells me for the payload["modified"] = true part that it

🛑 Cannot assign through subscript: 'payload' is a 'let' constant

socket closed: Optional("connection closed by server")

Hi, thanks for awesome pod!
I tried socket.join and send message.
but, 40sec after joining, connection closed automatically.

(10sec later)socket message: {"topic":"phoenix","ref":null,"payload":{},"event":"heartbeat"}
(20sec later)socket message: {"topic":"phoenix","ref":null,"payload":{},"event":"heartbeat"}
(40sec later)socket closed: Optional("connection closed by server")

so I added timeout value to phoenix_server/web/channels/user_socket.ex

defmodule PhoenixServer.UserSocket do
  use Phoenix.Socket

  ## Channels
  channel "rooms:*", PhoenixServer.RoomChannel

  ## Transports
  transport :websocket, Phoenix.Transports.WebSocket,
    timeout: :infinity

  def connect(_params, socket) do
    {:ok, socket}
  end

  def id(_socket), do: nil
end

but, it doesn't work...

What should I do to keep socket connection?

Better Name?

@mudphone Any thoughts on the repo name? The current name was just a quick filler when I started playing with channels. Thanks :)

Channel Presence

Phoenix 1.2 introduced Presence.

Was wondering if this library will be supporting it.

Thanks!

iOS 8

Is it possible to make version 2 work with iOS 8 rather than 9 only?

CFNetwork SSLHandshake failed (-9807)

Getting this error while connecting to HTTP socket?

2017-04-19 12:52:57.445851+0530 WebRTCConnection[2396:344111] CFNetwork SSLHandshake failed (-9807)

Does this library allow setting something like

NSExceptionAllowsInsecureHTTPLoads

Swift 3 errors

Hi,

I installed SwiftPhoenixClient using cocoapods on an empty project, but when I try to open the xcworkspace, Xcode8 says that I need to choose to convert the code to either Swift3 or Swift2.3

After choosing Swift3 and letting XCode convert the code, I ended up with >30 errors, about 20 of which were due to StarScream and about 10 of which were because of SwiftPhoenixClient.

Do I need to install StarScream manually (not via the SwiftPhoenixClient cocoapods dependency), since it appears to be the cause of the errors?

Thanks,
Jake
xcode_errors

Handle error when sending data

I use Swift Phoenix Client in my app to sending & receive data with Phoenix sockets. If I use the traditional way with channel.on to receive data on events, I use also your specific way to send data with method socket.send. But I doesn't really understand how I can handle errors at this moment, in others words, how can I verifiy if the connection is always established, if my message was send correctly etc.

Add to Cocoapods

Would be ideal to allow people to pull this in via Cocoapods.

How to disable console log..?

Hi, Thanks for the great framework.
how can I disable and enable console log for this frame work...?

{"topic":"phoenix","ref":"165","payload":{"status":"ok","response":{}},"join_ref":null,"event":"phx_reply"}
json: {"event":"heartbeat","topic":"phoenix","ref":"166","payload":{"body":"Pong"}}
socket message: {"topic":"phoenix","ref":"166","payload":{"status":"ok","response":{}},"join_ref":null,"event":"phx_reply"}

"Invalid HTTP upgrade"

Hey,

I am testing the iOS client with the phoenix chat example. Everything works fine locally. When I deploy to heroku, I can't connect through web socket via the iOS client ( js client works fine). I get this error:
socket closed: Optional("Invalid HTTP upgrade").
Can you help me understanding what's wrong? and how to fix it?

Thanks!

Channel `onClose` is never called

A Channel's onClose closure is never called.

It could potentially be hooked into the leave method.
Possible fix is to call the closure after channel has been given the ok after a leave event

Current:

public func leave(timeout: Int? = nil) -> Push {
return socket.push(topic: topic, event: PhoenixEvent.leave)
}

Proposed:

    public func leave(timeout: Int? = nil) -> Push {
        return socket.push(topic: topic, event: PhoenixEvent.leave)
            .receive("ok") { payload in
                self.onClose?(payload)
            }
    }

leave function on Socket is private

I cannot find a way to close a socket connection, other than the method as seen in the leave() function in the Socket class:

let leavingMessage = Phoenix.Message(subject: "status", body: "leaving")
let payload = Phoenix.Payload(topic: topic, event: "leave", message: leavingMessage)
socket.send(payload)

Why not make the leave() function public in the Socket class?

Support installation via Carthage

Carthage is a simplified dependency manager for iOS/OS-X. I know that you already have a Podspec (which I plan on using for now) but Carthage might be another great place to publish the client... and hopefully, allow you to do so with minimal hassle.

Can't keep connection up, seemingly different errors every now and then

Connections dies at random times after initially connecting, most often with the error right here. If I try to reconnect, it does not do anything and usually end up with a new error (will edit and update once I get it the next time).

I have a separate WebSocket connection also using StarScream that is connected to another server, and it seems to be running fine, so I suppose the error could be in this layer (SwiftPhoenixClient) and not below.

This however, when connected to either my local phoenix app or the remote deployed one keeps disconnecting and it takes a reboot of the app to get it up again. I'll dump more data as I get it.

EventManager.121: Socket log string: SwiftPhoenixClient: transport, Connected to ws://192.168.127.92:4000/events/websocket?token=Bearer%20THIS%20IS%20A%20TOKEN&terminal=951654322
EventManager.121: Socket log string: SwiftPhoenixClient: push, Sending {"event":"phx_join","topic":"terminal:123123123123","payload":{"status":"joining"},"ref":"1","join_ref":"1"}
EventManager.121: Socket log string: SwiftPhoenixClient: push, Sending {"event":"phx_join","topic":"place:123123123123","payload":{"status":"joining"},"ref":"2","join_ref":"2"}
EventManager.110: Connected to the event server.
EventManager.121: Socket log string: SwiftPhoenixClient: receive , {"topic":"terminal:123123123123","ref":"1","payload":{"status":"ok","response":{}},"event":"phx_reply"}
Join channel Optional("terminal:123123123123")
Phoenix reply @ terminal:123123123123: SwiftPhoenixClient.Message
EventManager.121: Socket log string: SwiftPhoenixClient: receive , {"topic":"place:123123123123","ref":"2","payload":{"status":"ok","response":{}},"event":"phx_reply"}
Join channel Optional("place:123123123123")
Phoenix reply @ place:123123123123: SwiftPhoenixClient.Message
EventManager.121: Socket log string: SwiftPhoenixClient: push, Sending {"event":"heartbeat","topic":"phoenix","payload":{},"ref":"3"}
EventManager.121: Socket log string: SwiftPhoenixClient: transport, WSError(type: Starscream.ErrorType.protocolError, message: "", code: 1000)
EventManager.117: Connection error: WSError(type: Starscream.ErrorType.protocolError, message: "", code: 1000)
EventManager.121: Socket log string: SwiftPhoenixClient: channel, error terminal:123123123123
EventManager.121: Socket log string: SwiftPhoenixClient: channel, error place:123123123123
2018-07-16 13:10:01.789333+0200 APP[4346:1817409] SocketStream read error [0x1c4362f40]: 1 54

Update README/Docs

Update README to walk a user through the new changes from @mudphone making everything compatible with the newest versions of Swift and Phoenix.

Long polling support?

Is Long polling supported? From what I can see the WebSocket implementation is highly coupled with the socket implementation. Do you have any plans to de-couple these and add support for other transport layers?

Alternative client

Hello, wanted to let you know that I've built alternative client on Swift, while I've used many places of this project for ideas, it was total overhaul, so I though making it separate project would be better than PR.

I wouldn't write here about that, but looking at your README looks like you don't have much time for maintenance, and I thought it would be a good idea to let developers know about alternatives, and I don't have any intentions to insult you here.

Basically it supports iOS 8 (#28), Carthage (#10), token authorisation (#9). Otherwise it's almost the same, except that it allows you to pass callbacks for messages to which server :replyes (the feature I've needed, and the reason I've built it).

Link to it: https://github.com/almassapargali/PhoenixWebSocket
Thanks, anyway!

No rejoin when loosing network connection

Hello,
I am using SwiftPhoenixClient in my Mac OS application.

I've just updated to 0.8.1, the previous version was 0.6.0.

0.8.1 does not rejoin.
My code:
`socket = Socket(url: "ws://...")

    socket.onOpen = { 
        print("onOpen")
    }
    socket.onClose = { 
        print("onClose")
    }
    socket.onError = { error in
        print("onError")
    }
    socket.connect()
    
    channel = self.socket?.channel("mychannel")                
    
    channel.onError {
        (payload) in print("Error: ", payload)
    }
    
   channel.onClose {
        (payload) in print("Channel Closed")            
    }
    
   channel.join().receive("ok") { (payload) in
        print("Channel Joined", payload)
        }.receive("error"){ (payload) in
            print("Failed to join", payload)
        }.receive("timeout") { (payload) in
            print("Networking issue...", payload)
    }`

So when I'm online it connects successfully, and prints "onOpen"->"Channel Joined"
Then I turn off my network and receive "onError".
Next step is to turn on it again - no actions. This method is not called:
open func stream(_ aStream: Stream, handle eventCode: Stream.Event)
But if I do the same for 0.6.0 - it works perfectly.

I wouldn't like to use 0.6.0 because new APIs look much better.
Could you help me with this please?

Enhancement or bridge to Objective-C

Hey!

I would love to help, just some thoughts;

There's a existing Objective-C library, I have opened a issue to see if it's still maintained. By the looks of it, I think its abandoned.

I'm still learning Elixir and playing around with Phoenix. I am comfortable in Objective-C and have some experience with Swift. What I can do is, either help out with some of the issues labeled as enhancements or write the bridging header to Objective-C.

Any enhancements that should be prioritised?

Cheers 😄

More robust Unit Tests

There are some basic Unit tests set up around creating a Socket, but I would love to see a more robust test which sets up a mock server and actually "sends" and "receives" messages back and forth

labeling this as easy for now if anyone wants to take up the task.

Auth token example for Swift library

I've just finished reading great book "Programming Phoenix". The sample to create video annotation identifies a user through window-token which is part of DOM itself. What is the approach for the client library?. What is best approach I can apply to keep my channel specific for a user and safe.
Phoenix <3 !

Params not sent when joining a Channel

It looks to me like #85 forgot about /// The params sent when joining the channel.

When I try to:

let channel = socket.channel("room:secret", params: ["token": "Super Secret Room Token"])

channel.join()
    .receive("ok") { payload in print("Channel Joined", payload) }
    .receive("error") { payload in print("Failed to join", payload) }
    .receive("timeout") { payload in print("Networking issue...", payload) }

I never seem to receive the token server side.

onError event

I'm new to swift, so I may be misreading the source code on this, but it doesn't look like there is a way to know about an error event? I would really like to be able to listen for errors and respond to error events.

Setup socket

Hello,

Is possible to initialize socket within viewDidLoad method it's important to pass some special parameters like token for example the scenario is user login get the token and after construct socket object in my example doesn't seems to work any ideas?

Update cocoapods

As I mentioned in #32 there was an issue where the phoenix websocket server was killing the connection after 30 seconds or so. I ran into this issue while running the a project where the dependency was installed via from the cocoapods repo, when running with the dependency locally, I have had no issues.

If you have the time, could you please update the version hosted on cocoapods to be current with master?

Thanks!

Token Authorization

Hi there,

Thank you for the awesome pod!

I'm building a chat app using this, but I want to check user authentication when socket joining.
It's related phoenixframework/phoenix#699 .

Do you have a plan to pass not only Phoenix.Message but something?

Best,

Stabilize 0.7.0

This is a list of things to investigate/change before making 0.7.0 a finalized release

Things to change

  • Change .close(reset:) to default to true instead of false
  • Investigate issue with using wss://hostname.com causing:
socket closed: The operation couldn’t be completed. (Starscream.WSError error 1.)
Error: WSError(type: Starscream.ErrorType.upgradeError, message: "Invalid HTTP upgrade", code: 403)

Potentially future release

  • Improve error handling when opening a socket
  • Allow disable sending heartbeat

JSON parsing

May I ask why you used an external JSON parsing library? It causes some troubles with my messages. Two examples:
JSON:

{
    "someString": "with value",
    "data": [{
        "title": "Hello",
        "nested": [{
            "subtitle": "One level deep",
            "id": 1
        }]
    }]
}

It does not parse nested JSON:

let json = "{\"someString\":\"with value\",\"data\":[{\"title\":\"Hello\",\"nested\":[{\"subtitle\":\"One level deep\",\"id\":1}]}]}"
// parsing json as in Phoenix.swift
let parsed = JSON.parse(json)
let msg: [String: AnyObject] = parsed.asDictionary!
// msg is then stored in Phoenix.Message

// For comparison the ios native way
let data = json.dataUsingEncoding(NSUTF8StringEncoding)!
let iosMsg = try! NSJSONSerialization.JSONObjectWithData(data, options: [])

// in the debugger you can see that it did not parse the nested elements:
po msg
 2 elements
   [0] : 2 elements
    - .0 : "data"
     .1 : [{"title":"Hello","nested":[{"subtitle":"One level deep","id":1}]}]
   [1] : 2 elements
    - .0 : "someString"
     .1 : with value

// the native ios solution however parses it correctly:
po iosMsg
 2 elements
   [0] : 2 elements
    - .0 : someString
    - .1 : with value
   [1] : 2 elements
    - .0 : data
     .1 : 1 elements
       [0] : 2 elements
         [0] : 2 elements
          - .0 : title
          - .1 : Hello
         [1] : 2 elements
          - .0 : nested
           .1 : 1 elements
             [0] : 2 elements
               [0] : 2 elements
                - .0 : subtitle
                - .1 : One level deep
               [1] : 2 elements
                - .0 : id

Type casting is a problem / not working:

// again with the parsed json from above, I try to cast the AnyObject to a Swift String:
// msg["someString"]
// ▿ Optional<AnyObject>
//   ▿ Some : with value

msg["someString"] as! String
// Could not cast value of type 'SwiftPhoenixClient.JSON' (0x10fec19e8) to 'NSString' (0x111031b48).
// error: Execution was interrupted, reason: signal SIGABRT.
// The process has been returned to the state before expression evaluation.

// which fails, in the chat app example the solution is the following, which looks quite ugly:
"\(msg["someString"])"
// also this solution gets worse when parsing integers:
Int64("\(msg["id"]!)")

// native ios solution:
iosMsg["someString"] as! String
// => "with value" a real String

Maybe we should provide a way to access the raw String or NSData inside the Phoenix.Message coming from the websocket? Then it would be possible to choose a different parser.

Background disconnect / reconnect strategy

I have a connection that basically should exist whenever the app is running. iOS will not allow you to run sockets in the background unless you're a VoIP app and basically we're not really doing that. What is the strategy to follow to disconnect and reconnect? We sometimes run into problems with the StarScream layer giving a -1000 protocol layer error when we disconnect when going into background an reconnect again coming to the foreground

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.