Giter Club home page Giter Club logo

swift-actioncableclient's Introduction

ActionCableClient

Version License Platform Carthage compatible

ActionCable is a new WebSockets server being released with Rails 5 which makes it easy to add real-time features to your app. This Swift client makes it dead-simple to connect with that server, abstracting away everything except what you need to get going.

Installation

To install, simply:

Cocoapods

Add the following line to your Podfile and run pod install

pod "ActionCableClient"

Carthage

Add the following to your Cartfile and run carthage update as normal.

github "danielrhodes/Swift-ActionCableClient"

Usage

Get Started & Connect

import ActionCableClient

self.client = ActionCableClient(url: URL(string: "ws://domain.tld/cable")!)

// Connect!
client.connect()

client.onConnected = {
    print("Connected!")
}

client.onDisconnected = {(error: Error?) in
    print("Disconnected!")
}

Subscribe to a Channel

// Create the Room Channel
let roomChannel = client.create("RoomChannel") //The channel name must match the class name on the server

// More advanced usage
let room_identifier = ["room_id" : identifier]
let roomChannel = client.create("RoomChannel", identifier: room_identifier, autoSubscribe: true, bufferActions: true)

Channel Callbacks

// Receive a message from the server. Typically a Dictionary.
roomChannel.onReceive = { (JSON : Any?, error : ErrorType?) in
    print("Received", JSON, error)
}

// A channel has successfully been subscribed to.
roomChannel.onSubscribed = {
    print("Yay!")
}

// A channel was unsubscribed, either manually or from a client disconnect.
roomChannel.onUnsubscribed = {
    print("Unsubscribed")
}

// The attempt at subscribing to a channel was rejected by the server.
roomChannel.onRejected = {
    print("Rejected")
}

Perform an Action on a Channel

// Send an action
roomChannel["speak"](["message": "Hello, World!"])

// Alternate less magical way:
roomChannel.action("speak", ["message": "Hello, World!"])

// Note: The `speak` action must be defined already on the server

Authorization & Headers

// ActionCable can be picky about origins, so if you
// need it can be set here.
client.origin = "https://domain.tld/"

// If you need any sort of authentication, you 
// will not have cookies like you do in the browser,
// so set any headers here.
//
// These are available in the `Connection`
// on the server side.

client.headers = [
    "Authorization": "sometoken"
]

Misc

client.onPing = {
    
}

For more documentation, see the wiki

Requirements

Starscream: The underlying WebSocket library.

Author

Daniel Rhodes, [email protected]

License

ActionCableClient is available under the MIT license. See the LICENSE file for more info.

swift-actioncableclient's People

Contributors

ahbou avatar danielrhodes avatar danipralea avatar dentelezhkin avatar plarson avatar vaughankg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

swift-actioncableclient's Issues

Creating channel blocks main thread

Hello again @danielrhodes
I found out that creating a Channel sometime blocks the main thread.
My code:

webSocketsRoomChannel = SocketRouter.shared.client.create(WebSocketEventsChannel.channel, identifier: channelIdPayload, autoSubscribe: true, bufferActions: true)

The stack:
screenshot 2016-12-01 18 39 38

I will come up with a fix if I find one
Update:
screenshot 2016-12-01 19 08 48

Is this an infinite cycle?

Unable to update to latest version

Hello and thanks for the library!
I am having issues updating the library to its latest version - 0.2.1

Not specifying the version - installs the ActionCableClient to 0.1.4
If I set it as pod 'ActionCableClient', '0.2.1', I get the following error:

[!] Unable to satisfy the following requirements:

- `ActionCableClient (= 0.2.1)` required by `Podfile`

None of your spec sources contain a spec satisfying the dependency: `ActionCableClient (= 0.2.1)`.

You have either:
 * out-of-date source repos which you can update with `pod repo update`.
 * mistyped the name or version.
 * not added the source repo that hosts the Podspec to your Podfile.

UPDATE:
I ended up using pod 'ActionCableClient', :git=> 'https://github.com/danielrhodes/Swift-ActionCableClient', :branch => '0.2.2' which fixed it, it but I'm guessing something is wrong with the default install.

Unique identifier mechanic is broken

The last commit that adds the UID mechanic is not working correctly, since it's always relying on the first element of the identifier dictionary. The issue happens when the order is different in the JSONSerializer.deserialize method. We had a regression in iOS 10 because the order of the JSON is different than iOS 11. See below:

iOS 11

{"identifier":"{\"member_id\":\"20c5edcc-5dda-4f43-a0df-b86a908001b6\",\"channel\":\"ConversationsChannel\"}","type":"confirm_subscription"}

iOS 10

{"identifier":"{\"channel\":\"ConversationsChannel\",\"member_id\":\"20c5edcc-5dda-4f43-a0df-b86a908001b6\"}","type":"confirm_subscription"}

This cause a problem because the channel's key in unconfirmedChannels in this example is the member's uuid (since it's always the first element of the identifier dictionary in the create method, but the message.uid is ConversationsChannel under iOS 10 because that's the first element of the onText text JSON.

A quick fix would be to remove the channel key, but I think the solution is not really elegant to be honest. We could also create a unique hash using a similar technique like this one:
https://github.com/rails/rails/blob/master/actioncable/app/assets/javascripts/action_cable/subscription.coffee#L54

JSON decoding error for ping in v0.1.5

Since version v0.1.5 the ping message fails JSON decoding with:
[ActionCableClient] Error decoding message: Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.}

Sending un-supported action

Hello, I have successfully implemented the library, but on the course of doing that, I kept sending invalid actions to the server. The server did acknowledge that by echoing Unable to process ChannelEventsChannel#entity_typing) while I was sending room.action("entity_typing")

Basically I was sending an action not recognised by the server. It was ok for me, cause I had server support, but it shouldn't have reached to that and I should have known from the start that I was sending an invalid action by receiving an error when sending it.

Just a thought.

Crash when server returns a disconnect response

Our rails server occasionally returns the following response

{"type":"disconnect","reason":"unauthorized","reconnect":false}"

This will cause the code to crash on line 112 of JSONSerializer.swift:

            return Message(channelIdentifier: channelIdentifier!,      // <<-- there is no "identifier" member in the response, so channelIdentfier will be nil
                           actionName: messageActionName,
                           messageType: MessageType.message,
                           data: messageValue,
                           error: messageError)

Recommend that the code be fixed to not force-unwrap channelIdentifier and treat the disconnect the same as a reject

The use of 4G can not connect successfully

work for WiFi.

used 4G got "write wait timed out" error.

ActionCableClient.ConnectionError.UnknownDomain(Error Domain=WebSocket Code=2 \"write wait timed out\" UserInfo={NSLocalizedDescription=write wait timed out}

I can not get header info in server side

Rails side get nil

module ApplicationCable
  class Connection < ActionCable::Connection::Base
    def connect
      p request.headers["Authorization"]
    end
  end
end

iOS side

 func setupClient() -> Void {
        self.client.headers = [
            "Authorization": "sometoken"
        ]
      
          self.client.willConnect = {
              print("Will Connect")
          }
          
          self.client.onConnected = {
              print("Connected to \(self.client.url)")
          }
          
          self.client.onDisconnected = {(error: ConnectionError?) in
            print("Disconected with error: \(String(describing: error))")
          }
          
          self.client.willReconnect = {
              print("Reconnecting to \(self.client.url)")
              return true
          }
          
          self.channel = client.create(ChatViewController.ChannelIdentifier)
          self.channel?.onSubscribed = {
              print("Subscribed to \(ChatViewController.ChannelIdentifier)")
          }
        
          self.channel?.onReceive = {(data: Any?, error: Error?) in
            if let error = error {
                print(error.localizedDescription)
                return
            }
            
            let JSONObject = JSON(data!)
            let msg = ChatMessage(name: JSONObject["name"].string!, message: JSONObject["message"].string!)
            self.history.append(msg)
            self.chatView?.tableView.reloadData()
            
            
            // Scroll to our new message!
            if (msg.name == self.name) {
                let indexPath = IndexPath(row: self.history.count - 1, section: 0)
                self.chatView?.tableView.scrollToRow(at: indexPath, at: .bottom, animated: false)
            }
        }
        
        self.client.connect()
    }

Authentication Question

What type of headers would I need to set for authentication with this? Do I just need to pass a users.id?

client.headers = [
    "Authorization": "sometoken"
]

Rails Log:

Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2016-04-14 18:47:13 +0000
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
  ESC[1mESC[36mUser Load (1.3ms)ESC[0m  ESC[1mESC[34mSELECT  "users".* FROM "users" WHERE "users"."id" IS NULL LIMIT $1ESC[0m  [["LIMIT", 1]]
An unauthorized connection attempt was rejected
Failed to upgrade to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)

XCode Log:

ActionCableClient.TransmitError.NotConnected
Connected!
Disconnected!

Swift Compiler Error

I got the error in WebSocket.swift after installing with pod: Pods/Starscream/Source/WebSocket.swift:553:34: Missing argument for parameter #1 in call

error

disconnected and reconnect

let client = ActionCableClient(URL: NSURL(string: "ws://localhost:3000/cable")!)
client.onDisconnected = { [weak self] error in
    print(error)
}

when I got the below error message on Disconnected callback, that client don't reconnect.

ActionCableClient.ConnectionError.unknownDomain(Error Domain=WebSocket Code=2 "write wait timed out" UserInfo={NSLocalizedDescription=write wait timed out})

how should I make it reconnect?

Channel action fired without errors without internet connection

There's something weird. When I call channel.Action without internet connection it doesn't return any error. isSubscribed seems to be true even without internet connection.

Any idea?

Update: Seems like the client doesn't detect the lost connection. How can I add ActionCableClient manually to the project to test it?

What I do is:

  • Connect to action cable
  • Subscribe to channel
  • Kill internet connection
  • Send an action
  • It's sended without issues, channel.action doesn't fire the expected error

masked and rsv data is not currently supported

After the success of login, first try socket connection and success. when I logout and re-login, and connection socket again, I got below:

ActionCableClient.ConnectionError.ProtocolViolation(Error Domain=WebSocket Code=1002 "masked and rsv data is not currently supported" UserInfo={NSLocalizedDescription=masked and rsv data is not currently supported})

please help...

Command /bin/sh failed with exit code 1 and Embedded pods framework

Hi Team am using the action cable client but when I run it, my Xcode doesn't compile it and throws me this error. Am using Xcode 9.2 for building the project. And I don't know whats happen wrong with the action cables. Yesterday I use it and it works very well but today when I come and try to run the project, it throws me this error. I don't know whats going on with this project. And how to solve this issue. Please help me out team.

screen shot 2017-12-14 at 10 45 44 am

onConnect is not being called

Hi,
I have a this simple connection function

`func initializeActionCabel()
{
self.client = ActionCableClient(url: URL(string: "ws://ip.of.my.server:3000.tld/cable")!)

    self.client.willConnect = {
        print("Will Connect")
    }
    
    self.client.onConnected = {
        print("Action Cable Connected!")
        self.channel = self.client.create("ChatChannel")
    }
    
    self.client.onDisconnected = {(error: ConnectionError?) in
        print("Action Cable Disconnected! \(error.debugDescription)")
    }
    
    self.client.onRejected = {
        print("Action Cable Connection Rejected!")
    }
    
    self.client.willReconnect = {
        print("Reconnecting to \(self.client.url)")
        return true
    }
    
    self.client.onPing = {
        print("On Ping")
    }
    
    self.channel?.onSubscribed = {
        print("Subscribed to 'ChatChannel'")
    }
    
    self.channel?.onReceive = {(data: Any?, error: Error?) in
        print("On Receive")
        if let _ = error {
            print(error)
            return
        }
    }
    
    // Connect!
    self.client.connect()
}`

Problem is: willReconnect and onDisconnected are being called just fine. But onConnected callback is not called ever.

Can you please comment or see if i'm missing something? Thanks in advance.

Cheers.

32bits devices not subscribed

When I run my app in the iPhone 6 or 7 it works fine, but when I run it in the 5c, it connects but doesn't subscribe to ActionCable

swift 3 support

upon attempting to use swift 3 via pods

pod 'Starscream', :git => 'https://github.com/daltoniam/Starscream.git', :branch => 'swift3'
pod 'ActionCableClient', :git => 'https://github.com/danielrhodes/Swift-ActionCableClient', :branch => 'swift3'

xcode 8 requested that it convert the starscream library to latest syntax. I believe that the switft3 branch here can use the 2.0.0 release of starscream to fix this issue.

Until then using ActionCableClient for swift 3 doesn't seem doable on Xcode8.

Hopefully I'm wrong and there is a solution for this?

Cheers!

Support Objective-C API

How can it generate umbrella headers like Starscream?

## Carthage/.../Starscream.framework/Headers/Starscream-Swift.h ##

...

SWIFT_CLASS("_TtC10Starscream9WebSocket")
@interface WebSocket : NSObject <NSStreamDelegate>
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, readonly, copy) NSString * _Nonnull ErrorDomain;)
+ (NSString * _Nonnull)ErrorDomain;
@property (nonatomic, strong) OS_dispatch_queue * _Nonnull callbackQueue;
@property (nonatomic, copy) NSArray<NSString *> * _Nullable optionalProtocols;
@property (nonatomic, readonly, copy) NSString * _Nonnull headerWSUpgradeName;
@property (nonatomic, readonly, copy) NSString * _Nonnull headerWSUpgradeValue;
@property (nonatomic, readonly, copy) NSString * _Nonnull headerWSHostName;
@property (nonatomic, readonly, copy) NSString * _Nonnull headerWSConnectionName;
@property (nonatomic, readonly, copy) NSString * _Nonnull headerWSConnectionValue;
@property (nonatomic, readonly, copy) NSString * _Nonnull headerWSProtocolName;
@property (nonatomic, readonly, copy) NSString * _Nonnull headerWSVersionName;
@property (nonatomic, readonly, copy) NSString * _Nonnull headerWSVersionValue;
@property (nonatomic, readonly, copy) NSString * _Nonnull headerWSKeyName;
@property (nonatomic, readonly, copy) NSString * _Nonnull headerOriginName;
@property (nonatomic, readonly, copy) NSString * _Nonnull headerWSAcceptName;
@property (nonatomic, readonly) NSInteger BUFFER_MAX;
@property (nonatomic, readonly) uint8_t FinMask;
@property (nonatomic, readonly) uint8_t OpCodeMask;
@property (nonatomic, readonly) uint8_t RSVMask;
@property (nonatomic, readonly) uint8_t MaskMask;
@property (nonatomic, readonly) uint8_t PayloadLenMask;
@property (nonatomic, readonly) NSInteger MaxFrameSize;
@property (nonatomic, readonly) NSInteger httpSwitchProtocolCode;
@property (nonatomic, readonly, copy) NSArray<NSString *> * _Nonnull supportedSSLSchemes;
@property (nonatomic, copy) void (^ _Nullable onConnect)(void);
@property (nonatomic, copy) void (^ _Nullable onDisconnect)(NSError * _Nullable);
@property (nonatomic, copy) void (^ _Nullable onText)(NSString * _Nonnull);
@property (nonatomic, copy) void (^ _Nullable onData)(NSData * _Nonnull);
@property (nonatomic, copy) void (^ _Nullable onPong)(NSData * _Nullable);
@property (nonatomic, copy) NSDictionary<NSString *, NSString *> * _Nonnull headers;
@property (nonatomic) BOOL voipEnabled;
@property (nonatomic) BOOL disableSSLCertValidation;
@property (nonatomic, copy) NSArray<NSNumber *> * _Nullable enabledSSLCipherSuites;
@property (nonatomic, copy) NSString * _Nullable origin;
@property (nonatomic) NSInteger timeout;
@property (nonatomic, readonly) BOOL isConnected;
@property (nonatomic, readonly, copy) NSURL * _Nonnull currentURL;
/**
  Used for setting protocols.
*/
- (nonnull instancetype)initWithUrl:(NSURL * _Nonnull)url protocols:(NSArray<NSString *> * _Nullable)protocols OBJC_DESIGNATED_INITIALIZER;
- (nonnull instancetype)initWithUrl:(NSURL * _Nonnull)url writeQueueQOS:(NSQualityOfService)writeQueueQOS protocols:(NSArray<NSString *> * _Nullable)protocols;
/**
  Connect to the WebSocket server on a background thread.
*/
- (void)connect;
/**
  Write a string to the websocket. This sends it as a text frame.
  If you supply a non-nil completion block, I will perform it when the write completes.
  \param string The string to write.

  \param completion The (optional) completion handler.

*/
- (void)writeWithString:(NSString * _Nonnull)string completion:(void (^ _Nullable)(void))completion;
/**
  Write binary data to the websocket. This sends it as a binary frame.
  If you supply a non-nil completion block, I will perform it when the write completes.
  \param data The data to write.

  \param completion The (optional) completion handler.

*/
- (void)writeWithData:(NSData * _Nonnull)data completion:(void (^ _Nullable)(void))completion;
/**
  Write a ping to the websocket. This sends it as a control frame.
  Yodel a   sound  to the planet.    This sends it as an astroid. http://youtu.be/Eu5ZJELRiJ8?t=42s
*/
- (void)writeWithPing:(NSData * _Nonnull)ping completion:(void (^ _Nullable)(void))completion;
/**
  Delegate for the stream methods. Processes incoming bytes
*/
- (void)stream:(NSStream * _Nonnull)aStream handleEvent:(NSStreamEvent)eventCode;
- (nonnull instancetype)init SWIFT_UNAVAILABLE;
@end

...

Xcode 10.3

in Xcode 10.3
- after pod:
Downloading dependencies
Installing ActionCableClient (0.2.3)
Installing Starscream (2.0.4)
Generating Pods project
Integrating client project

[!] Please close any current Xcode sessions and use SwiftAcabClient.xcworkspace for this project from now on.
Sending stats
Pod installation complete! There is 1 dependency from the Podfile and 2 total pods installed.

- after run xcworkspace:
๐Ÿ‘Ž SWIFT_VERSION '3.0' is unsupported, supported versions are: 4.0, 4.2, 5.0. (in target 'ActionCableClient')

0.2.4 is not available in Cocoapods

pod repo update and pod install installs ActionCableClient (0.2.3) and Starscream 2.0.4 (was 3.0.4). The project can't be built due to Swift compiler errors.

Did you push version0.2.4 to pod trunk?

Action Cable on receive method is not called

Hello Daniel am using the action cable, I will explain you the scenario for the onReceive method not called.

When we start the application then the action cable is working fine, But if I logout from my application and then login from different user then the action cable of onReceive method is not called. I don't understand what happens but if I kill the application and then start it again. Then the action cables onReceive method will work. I don't know what am doing wrong.

Can you suggest me what I have to do.

Message not received when app is in background mode

Problem in background mode. When the app goes background state Receive message is just stopped and no further updates from peer. It gets active and returns the older messages when I become foreground. This is stopping my integration and looking for alternative SDK. Am I missing anything around to config? ( enabled all background config under capability )

Module compiled with Swift 3.0

Trying to use master branch with Xcode 3.1 and got this error:

Module compiled with Swift 3.0: cannot be imported in Swift 3.0.1

Rename identifier to data or params

Hi @danielrhodes,

I think it would be clearer to rename identifier to params or perhaps data in the create method (create(channel, identifier:, autoSubscribe:, bufferActions:). I see that the underlying API send identifier to the backend, but since name is a standalone parameter, I think it would make sense to abstract it a little bit more.

Disconnect block does not fire

Hello again. I've setup my client, but the the onDisconnected block is not getting called.
My setup:

func connect(appId:String?, token: String?) {
        guard let applicationId = appId, let token = token else {
            print("cannot connect to the web socket server without an app id AND a token!")
            return
        }
        let baseURL = "..."
        let urlString = "\(baseURL)?application_id=\(applicationId)&authentication_token=\(token)"
        client = ActionCableClient(url: URL(string: urlString)!)
        let reconnectionStrategy : RetryStrategy = .logarithmicBackoff(maxRetries: 30, maxIntervalTime: 30.0)
        client.reconnectionStrategy = reconnectionStrategy
        client.onConnected = {
            print("\(self.className) : Connected!")
        }
        
        client.onDisconnected = {(error: Error?) in
            print("\(self.className) : Disconnected!")
        }
        client.connect()
    }

Problem with unconfirmed list of channels

Hey,

the problem is related to unsubscribed channels which from some server or others reasons couldn't be subscribed (without any confirmation). If the channel's event ChannelEventsChannel appends unconfirmedChannels list cannot be released properly and is returning all the time. I suggest to release this array when unsubscribe() is called.

Clear channels

Is there a way to clear autoSubscribed channels, let say when a user sign out? I can disconnect the websocket, but when I reconnect it when the other user log in, old subscriptions remain. Note that I'm using a Singleton ActionCable Manager, so maybe I should just reset the singleton instance?

Problem when installed with Carthage.

I did two tests using Cocoapods and Carthage, with cocoapods the framework works fine, but when I installed with carthage the following error happen on line 301:

Thread1: EXC_BAD_ACCESS(code=EXC_I386_GPLFT)

XCode version 8.3.3

image:
screen shot 2017-08-16 at 19 46 29

Message of type unrecognized is treated as normal message in deserialize then fails as channelName does not exist

In JSONSerializer.deserialize, unrecognized message is grouped with message, but ultimately fails since message may be malformed eg does not contain channelName

case .welcome, .ping, .unrecognized:
                return Message(channelName: nil,
                               actionName: nil,
                               messageType: messageType,
                               data: nil,
                               error: nil)
            case .message:
                var messageActionName : String?
                var messageValue      : AnyObject?
                var messageError      : Swift.Error?
                
                do {
                    // No channel name was extracted from identifier
                    guard let _ = channelName
                        else { throw SerializationError.protocolViolation }
                    
                    // No message was extracted from identifier
                    guard let messageObj = JSONObj["message"]
                        else { throw SerializationError.protocolViolation }
                    
                    if let actionObj = messageObj["action"], let actionStr = actionObj as? String {
                        messageActionName = actionStr
                    }
                    
                    messageValue = messageObj
                } catch {
                  messageError = error
                }
                
                return Message(channelName: channelName!,
                               actionName: messageActionName,
                               messageType: MessageType.message,
                               data: messageValue,
                               error: messageError)

In onMessage, unrecognized message is not further processed.

fileprivate func onMessage(_ message: Message) {
            switch(message.messageType) {
            case .unrecognized:
                break
            case .welcome:
                break
            case .ping:
                if let callback = onPing {
                    DispatchQueue.main.async(execute: callback)
                }
            case .message:
                if let channel = channels[message.channelName!] {
                    // Notify Channel
                    channel.onMessage(message)

I suggest unrecognized be grouped with welcome and ping message types.

Headers not being assigned

After some debugging I've found that the headers setter is calling the getter which calls a dynamic getter and ignores the new values

This declaration

    open var headers : [String: String]? {
        get { return socket.request.allHTTPHeaderFields }
        set {
            for (field, value) in headers ?? [:] {
                socket.request.setValue(value, forHTTPHeaderField: field)
            }
        }
    }

Should be replaced with this

    open var headers : [String: String]? {
        get { return socket.request.allHTTPHeaderFields }
        set {
            for (field, value) in newValue ?? [:] {
                socket.request.setValue(value, forHTTPHeaderField: field)
            }
        }
    }

If you need a test just run this example

  let client: ActionCableClient = {
    let _client = ActionCableClient(url: Defaults.Api.cableURL)
    _client.headers = [
      "Origin": "https://server.example"
    ]
    return _client
  }()
  print(client.headers)
  client.headers = [
    "Origin": "https://server.example",
    "Accept": "accept/json"
  ]
  print(client.headers)
  if !client.isConnected {
    client.connect()
  }

https://github.com/danielrhodes/Swift-ActionCableClient/blob/master/Source/Classes/ActionCableClient.swift#L77

Master fails to compile with Carthage

Using XCode 9.2 and Carthage, targeting the master branch as it seems to have Swift 4 support merged in. Below is the error:

CompileSwift normal arm64
    cd /Users/brian/Projects/FreightrollMobile/Carthage/Checkouts/Swift-ActionCableClient
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend -emit-bc /Users/brian/Projects/FreightrollMobile/Carthage/Checkouts/Swift-ActionCableClient/Source/Classes/JSONSerializer.swift /Users/brian/Projects/FreightrollMobile/Carthage/Checkouts/Swift-ActionCableClient/Source/Classes/Error.swift /Users/brian/Projects/FreightrollMobile/Carthage/Checkouts/Swift-ActionCableClient/Source/Classes/ActionCableClient.swift /Users/brian/Projects/FreightrollMobile/Carthage/Checkouts/Swift-ActionCableClient/Source/Classes/RetryHandler.swift /Users/brian/Projects/FreightrollMobile/Carthage/Checkouts/Swift-ActionCableClient/Source/Classes/Channel.swift /Users/brian/Projects/FreightrollMobile/Carthage/Checkouts/Swift-ActionCableClient/Source/Classes/Constants.swift -target arm64-apple-ios8.0 -Xllvm -aarch64-use-tbi -enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.2.sdk -I /Users/brian/Library/Caches/org.carthage.CarthageKit/DerivedData/9.2_9C40b/Swift-ActionCableClient/0db1c05448fd484b88c92aecd38489233ecc13e4/Build/Intermediates.noindex/ArchiveIntermediates/ActionCableClient-iOS/BuildProductsPath/Release-iphoneos -F /Users/brian/Library/Caches/org.carthage.CarthageKit/DerivedData/9.2_9C40b/Swift-ActionCableClient/0db1c05448fd484b88c92aecd38489233ecc13e4/Build/Intermediates.noindex/ArchiveIntermediates/ActionCableClient-iOS/BuildProductsPath/Release-iphoneos -g -import-underlying-module -module-cache-path /Users/brian/Library/Caches/org.carthage.CarthageKit/DerivedData/9.2_9C40b/Swift-ActionCableClient/0db1c05448fd484b88c92aecd38489233ecc13e4/ModuleCache -swift-version 4 -serialize-debugging-options -report-errors-to-debugger -Xcc "-I/Users/brian/Library/Caches/org.carthage.CarthageKit/DerivedData/9.2_9C40b/Swift-ActionCableClient/0db1c05448fd484b88c92aecd38489233ecc13e4/Build/Intermediates.noindex/ArchiveIntermediates/ActionCableClient-iOS/IntermediateBuildFilesPath/ActionCableClient.build/Release-iphoneos/ActionCableClient iOS.build/swift-overrides.hmap" -Xcc -iquote -Xcc "/Users/brian/Library/Caches/org.carthage.CarthageKit/DerivedData/9.2_9C40b/Swift-ActionCableClient/0db1c05448fd484b88c92aecd38489233ecc13e4/Build/Intermediates.noindex/ArchiveIntermediates/ActionCableClient-iOS/IntermediateBuildFilesPath/ActionCableClient.build/Release-iphoneos/ActionCableClient iOS.build/ActionCableClient-generated-files.hmap" -Xcc "-I/Users/brian/Library/Caches/org.carthage.CarthageKit/DerivedData/9.2_9C40b/Swift-ActionCableClient/0db1c05448fd484b88c92aecd38489233ecc13e4/Build/Intermediates.noindex/ArchiveIntermediates/ActionCableClient-iOS/IntermediateBuildFilesPath/ActionCableClient.build/Release-iphoneos/ActionCableClient iOS.build/ActionCableClient-own-target-headers.hmap" -Xcc "-I/Users/brian/Library/Caches/org.carthage.CarthageKit/DerivedData/9.2_9C40b/Swift-ActionCableClient/0db1c05448fd484b88c92aecd38489233ecc13e4/Build/Intermediates.noindex/ArchiveIntermediates/ActionCableClient-iOS/IntermediateBuildFilesPath/ActionCableClient.build/Release-iphoneos/ActionCableClient iOS.build/ActionCableClient-all-non-framework-target-headers.hmap" -Xcc -ivfsoverlay -Xcc /Users/brian/Library/Caches/org.carthage.CarthageKit/DerivedData/9.2_9C40b/Swift-ActionCableClient/0db1c05448fd484b88c92aecd38489233ecc13e4/Build/Intermediates.noindex/ArchiveIntermediates/ActionCableClient-iOS/IntermediateBuildFilesPath/ActionCableClient.build/all-product-headers.yaml -Xcc -iquote -Xcc "/Users/brian/Library/Caches/org.carthage.CarthageKit/DerivedData/9.2_9C40b/Swift-ActionCableClient/0db1c05448fd484b88c92aecd38489233ecc13e4/Build/Intermediates.noindex/ArchiveIntermediates/ActionCableClient-iOS/IntermediateBuildFilesPath/ActionCableClient.build/Release-iphoneos/ActionCableClient iOS.build/ActionCableClient-project-headers.hmap" -Xcc -I/Users/brian/Library/Caches/org.carthage.CarthageKit/DerivedData/9.2_9C40b/Swift-ActionCableClient/0db1c05448fd484b88c92aecd38489233ecc13e4/Build/Intermediates.noindex/ArchiveIntermediates/ActionCableClient-iOS/BuildProductsPath/Release-iphoneos/include -Xcc "-I/Users/brian/Library/Caches/org.carthage.CarthageKit/DerivedData/9.2_9C40b/Swift-ActionCableClient/0db1c05448fd484b88c92aecd38489233ecc13e4/Build/Intermediates.noindex/ArchiveIntermediates/ActionCableClient-iOS/IntermediateBuildFilesPath/ActionCableClient.build/Release-iphoneos/ActionCableClient iOS.build/DerivedSources/arm64" -Xcc "-I/Users/brian/Library/Caches/org.carthage.CarthageKit/DerivedData/9.2_9C40b/Swift-ActionCableClient/0db1c05448fd484b88c92aecd38489233ecc13e4/Build/Intermediates.noindex/ArchiveIntermediates/ActionCableClient-iOS/IntermediateBuildFilesPath/ActionCableClient.build/Release-iphoneos/ActionCableClient iOS.build/DerivedSources" -Xcc -ivfsoverlay -Xcc "/Users/brian/Library/Caches/org.carthage.CarthageKit/DerivedData/9.2_9C40b/Swift-ActionCableClient/0db1c05448fd484b88c92aecd38489233ecc13e4/Build/Intermediates.noindex/ArchiveIntermediates/ActionCableClient-iOS/IntermediateBuildFilesPath/ActionCableClient.build/Release-iphoneos/ActionCableClient iOS.build/unextended-module-overlay.yaml" -Xcc -working-directory/Users/brian/Projects/FreightrollMobile/Carthage/Checkouts/Swift-ActionCableClient -emit-module-doc-path "/Users/brian/Library/Caches/org.carthage.CarthageKit/DerivedData/9.2_9C40b/Swift-ActionCableClient/0db1c05448fd484b88c92aecd38489233ecc13e4/Build/Intermediates.noindex/ArchiveIntermediates/ActionCableClient-iOS/IntermediateBuildFilesPath/ActionCableClient.build/Release-iphoneos/ActionCableClient iOS.build/Objects-normal/arm64/ActionCableClient.swiftdoc" -serialize-diagnostics-path "/Users/brian/Library/Caches/org.carthage.CarthageKit/DerivedData/9.2_9C40b/Swift-ActionCableClient/0db1c05448fd484b88c92aecd38489233ecc13e4/Build/Intermediates.noindex/ArchiveIntermediates/ActionCableClient-iOS/IntermediateBuildFilesPath/ActionCableClient.build/Release-iphoneos/ActionCableClient iOS.build/Objects-normal/arm64/JSONSerializer.dia" -O -module-name ActionCableClient -emit-module-path "/Users/brian/Library/Caches/org.carthage.CarthageKit/DerivedData/9.2_9C40b/Swift-ActionCableClient/0db1c05448fd484b88c92aecd38489233ecc13e4/Build/Intermediates.noindex/ArchiveIntermediates/ActionCableClient-iOS/IntermediateBuildFilesPath/ActionCableClient.build/Release-iphoneos/ActionCableClient iOS.build/Objects-normal/arm64/ActionCableClient.swiftmodule" -emit-objc-header-path "/Users/brian/Library/Caches/org.carthage.CarthageKit/DerivedData/9.2_9C40b/Swift-ActionCableClient/0db1c05448fd484b88c92aecd38489233ecc13e4/Build/Intermediates.noindex/ArchiveIntermediates/ActionCableClient-iOS/IntermediateBuildFilesPath/ActionCableClient.build/Release-iphoneos/ActionCableClient iOS.build/Objects-normal/arm64/ActionCableClient-Swift.h" -emit-dependencies-path "/Users/brian/Library/Caches/org.carthage.CarthageKit/DerivedData/9.2_9C40b/Swift-ActionCableClient/0db1c05448fd484b88c92aecd38489233ecc13e4/Build/Intermediates.noindex/ArchiveIntermediates/ActionCableClient-iOS/IntermediateBuildFilesPath/ActionCableClient.build/Release-iphoneos/ActionCableClient iOS.build/Objects-normal/arm64/JSONSerializer.d" -num-threads 4 -o "/Users/brian/Library/Caches/org.carthage.CarthageKit/DerivedData/9.2_9C40b/Swift-ActionCableClient/0db1c05448fd484b88c92aecd38489233ecc13e4/Build/Intermediates.noindex/ArchiveIntermediates/ActionCableClient-iOS/IntermediateBuildFilesPath/ActionCableClient.build/Release-iphoneos/ActionCableClient iOS.build/Objects-normal/arm64/JSONSerializer.bc" -o "/Users/brian/Library/Caches/org.carthage.CarthageKit/DerivedData/9.2_9C40b/Swift-ActionCableClient/0db1c05448fd484b88c92aecd38489233ecc13e4/Build/Intermediates.noindex/ArchiveIntermediates/ActionCableClient-iOS/IntermediateBuildFilesPath/ActionCableClient.build/Release-iphoneos/ActionCableClient iOS.build/Objects-normal/arm64/Error.bc" -o "/Users/brian/Library/Caches/org.carthage.CarthageKit/DerivedData/9.2_9C40b/Swift-ActionCableClient/0db1c05448fd484b88c92aecd38489233ecc13e4/Build/Intermediates.noindex/ArchiveIntermediates/ActionCableClient-iOS/IntermediateBuildFilesPath/ActionCableClient.build/Release-iphoneos/ActionCableClient iOS.build/Objects-normal/arm64/ActionCableClient.bc" -o "/Users/brian/Library/Caches/org.carthage.CarthageKit/DerivedData/9.2_9C40b/Swift-ActionCableClient/0db1c05448fd484b88c92aecd38489233ecc13e4/Build/Intermediates.noindex/ArchiveIntermediates/ActionCableClient-iOS/IntermediateBuildFilesPath/ActionCableClient.build/Release-iphoneos/ActionCableClient iOS.build/Objects-normal/arm64/RetryHandler.bc" -o "/Users/brian/Library/Caches/org.carthage.CarthageKit/DerivedData/9.2_9C40b/Swift-ActionCableClient/0db1c05448fd484b88c92aecd38489233ecc13e4/Build/Intermediates.noindex/ArchiveIntermediates/ActionCableClient-iOS/IntermediateBuildFilesPath/ActionCableClient.build/Release-iphoneos/ActionCableClient iOS.build/Objects-normal/arm64/Channel.bc" -o "/Users/brian/Library/Caches/org.carthage.CarthageKit/DerivedData/9.2_9C40b/Swift-ActionCableClient/0db1c05448fd484b88c92aecd38489233ecc13e4/Build/Intermediates.noindex/ArchiveIntermediates/ActionCableClient-iOS/IntermediateBuildFilesPath/ActionCableClient.build/Release-iphoneos/ActionCableClient iOS.build/Objects-normal/arm64/Constants.bc"
/Users/brian/Projects/FreightrollMobile/Carthage/Checkouts/Swift-ActionCableClient/Source/Classes/ActionCableClient.swift:96:27: error: incorrect argument label in call (have 'request:', expected 'url:')
        socket = WebSocket(request: request)
                          ^~~~~~~~
                           url

** ARCHIVE FAILED **


The following build commands failed:
	CompileSwift normal armv7
	CompileSwiftSources normal arm64 com.apple.xcode.tools.swift.compiler
	CompileSwift normal arm64

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.