Skip to content

Commit

Permalink
Added initial files
Browse files Browse the repository at this point in the history
  • Loading branch information
nikhiljohn10 committed Dec 31, 2020
1 parent 62a727f commit 3236cb9
Show file tree
Hide file tree
Showing 17 changed files with 974 additions and 14 deletions.
20 changes: 6 additions & 14 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,25 +36,17 @@ playground.xcworkspace

# Swift Package Manager
#
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
# Packages/
# Package.pins
# Package.resolved
# *.xcodeproj
#
# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
# hence it is not needed unless you have added a package configuration file to your project
# .swiftpm
Packages/
Package.pins
Package.resolved
*.xcodeproj
.swiftpm

.build/

# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
# Pods/
Pods/
#
# Add this line if you want to avoid checking in source code from the Xcode workspace
# *.xcworkspace
Expand Down
28 changes: 28 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// swift-tools-version:5.3
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "GitterFayeSwift",
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "GitterFayeSwift",
targets: ["GitterFayeSwift"]),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
.package(url: "https://github.com/daltoniam/Starscream.git", from: "4.0.4"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "GitterFayeSwift",
dependencies: ["Starscream"]),
.testTarget(
name: "GitterFayeSwiftTests",
dependencies: ["GitterFayeSwift"]),
]
)
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# GitterFayeSwift

![Swift Package](https://img.shields.io/badge/SwiftPM-0.1.0-important)

Faye Client for Gitter in Swift
150 changes: 150 additions & 0 deletions Sources/GitterFayeSwift/Bayuex.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
//
// Bayuex.swift
//
//
// Created by Nikhil John on 29/12/20.
//

import Foundation


// FIXME: comparison operators with optionals were removed from the Swift Standard Libary.
// Consider refactoring the code to use the non-optional operators.
fileprivate func < <T : Comparable>(lhs: T?, rhs: T?) -> Bool {
switch (lhs, rhs) {
case let (l?, r?):
return l < r
case (nil, _?):
return true
default:
return false
}
}

// FIXME: comparison operators with optionals were removed from the Swift Standard Libary.
// Consider refactoring the code to use the non-optional operators.
fileprivate func > <T : Comparable>(lhs: T?, rhs: T?) -> Bool {
switch (lhs, rhs) {
case let (l?, r?):
return l > r
default:
return rhs < lhs
}
}

// MARK: Private Bayuex Methods
extension FayeClient {

/**
Bayeux messages
*/

// Bayeux Handshake
// "channel": "/meta/handshake",
// "version": "1.0",
// "minimumVersion": "1.0beta",
// "supportedConnectionTypes": ["long-polling", "callback-polling", "iframe", "websocket]
func handshake(token: String) {
writeOperationQueue.sync { [unowned self] in
let connTypes = [BayeuxConnection.LongPolling.rawValue,
BayeuxConnection.Callback.rawValue,
BayeuxConnection.iFrame.rawValue,
BayeuxConnection.WebSocket.rawValue]

var dict = [String: AnyObject]()
dict[Bayeux.Channel.rawValue] = BayeuxChannel.Handshake.rawValue as AnyObject?
dict[Bayeux.Version.rawValue] = "1.0" as AnyObject?
dict[Bayeux.MinimumVersion.rawValue] = "1.0beta" as AnyObject?
dict[Bayeux.SupportedConnectionTypes.rawValue] = connTypes as AnyObject
dict[Bayeux.Extension.rawValue] = [ Bayeux.Token.rawValue : token ] as AnyObject
send(dict)
}
}

// Bayeux Connect
// "channel": "/meta/connect",
// "clientId": "Un1q31d3nt1f13r",
// "connectionType": "long-polling"
func connect() {
writeOperationQueue.sync { [unowned self] in
let dict:[String:AnyObject] = [
Bayeux.Channel.rawValue: BayeuxChannel.Connect.rawValue as AnyObject,
Bayeux.ClientId.rawValue: self.fayeClientId! as AnyObject,
Bayeux.ConnectionType.rawValue: BayeuxConnection.WebSocket.rawValue as AnyObject,
Bayeux.Advice.rawValue: ["timeout": self.timeOut] as AnyObject
]
send(dict)
}
}

// Bayeux Disconnect
// "channel": "/meta/disconnect",
// "clientId": "Un1q31d3nt1f13r"
func disconnect() {
writeOperationQueue.sync { [unowned self] in
guard let clientId = self.fayeClientId else { return }
let dict:[String:AnyObject] = [Bayeux.Channel.rawValue: BayeuxChannel.Disconnect.rawValue as AnyObject,
Bayeux.ClientId.rawValue: clientId as AnyObject,
Bayeux.ConnectionType.rawValue: BayeuxConnection.WebSocket.rawValue as AnyObject]

send(dict)
}
}

// Bayeux Subscribe
// "channel": "/meta/subscribe",
// "clientId": "Un1q31d3nt1f13r",
// "subscription": "/foo/**"
func subscribe(_ model:FayeSubscriptionModel) {
writeOperationQueue.sync { [unowned self] in
do {
var newModel = model
if newModel.clientId == nil { newModel.clientId = self.fayeClientId }
let json = try JSONEncoder().encode(newModel)
guard let string = String(data: json, encoding: .utf8) else { return }

self.transport?.writeString(string)
self.pendingSubscriptions.append(model)

} catch {
// TODO: catch this error
}
}
}

// Bayeux Unsubscribe
// {
// "channel": "/meta/unsubscribe",
// "clientId": "Un1q31d3nt1f13r",
// "subscription": "/foo/**"
// }
func unsubscribe(_ channel:String) {
writeOperationQueue.sync { [unowned self] in
guard let clientId = self.fayeClientId else { return }
let dict:[String:AnyObject] = [Bayeux.Channel.rawValue: BayeuxChannel.Unsubscibe.rawValue as AnyObject,
Bayeux.ClientId.rawValue: clientId as AnyObject,
Bayeux.Subscription.rawValue: channel as AnyObject]
send(dict)
}
}

// Bayeux Publish
// {
// "channel": "/some/channel",
// "clientId": "Un1q31d3nt1f13r",
// "data": "some application string or JSON encoded object",
// "id": "some unique message id"
// }
func publish(_ data:[String:AnyObject], channel:String) {
writeOperationQueue.sync { [weak self] in
if let clientId = self?.fayeClientId, let messageId = self?.nextMessageId(), self?.fayeConnected == true {
let dict:[String:AnyObject] = [Bayeux.Channel.rawValue: channel as AnyObject,
Bayeux.ClientId.rawValue: clientId as AnyObject,
Bayeux.Id.rawValue: messageId as AnyObject,
Bayeux.Data.rawValue: data as AnyObject]

send(dict)
}
}
}
}
43 changes: 43 additions & 0 deletions Sources/GitterFayeSwift/BayuexTypes.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//
// BayuexProtocol.swift
//
//
// Created by Nikhil John on 29/12/20.
//

import Foundation

// MARK: Bayuex Connection Type
public enum BayeuxConnection: String {
case LongPolling = "long-polling"
case Callback = "callback-polling"
case iFrame = "iframe"
case WebSocket = "websocket"
}

// MARK: BayuexChannel Messages
public enum BayeuxChannel: String, Encodable, Equatable{
case Handshake = "/meta/handshake"
case Connect = "/meta/connect"
case Disconnect = "/meta/disconnect"
case Subscribe = "/meta/subscribe"
case Unsubscibe = "/meta/unsubscribe"
}

// MARK: Bayuex Parameters
public enum Bayeux: String {
case Channel = "channel"
case Version = "version"
case ClientId = "clientId"
case ConnectionType = "connectionType"
case Data = "data"
case Subscription = "subscription"
case Id = "id"
case MinimumVersion = "minimumVersion"
case SupportedConnectionTypes = "supportedConnectionTypes"
case Successful = "successful"
case Error = "error"
case Advice = "advice"
case Extension = "ext"
case Token = "token"
}
Loading

0 comments on commit 3236cb9

Please sign in to comment.