Skip to content

Commit

Permalink
Removed the Socket.IO dependency.
Browse files Browse the repository at this point in the history
Rewrote the EverLayoutBridge class so it uses custom, flaky network code.
  • Loading branch information
dalewebster48 committed May 25, 2017
1 parent 9b0e56c commit 2361dfa
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 79 deletions.
2 changes: 0 additions & 2 deletions EverLayout.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,4 @@ Pod::Spec.new do |s|
s.source = { :git => "https://github.com/acrocat/EverLayout.git", :tag => "#{s.version}" }

s.source_files = "EverLayout", "EverLayout/Classes/**/*.{swift}"

s.dependency "Socket.IO-Client-Swift" , "8.3.3"
end
134 changes: 99 additions & 35 deletions EverLayout/Classes/EverLayoutBridge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,53 +21,91 @@
// THE SOFTWARE.

import UIKit
import SocketIO

public class EverLayoutBridge: NSObject
{
static var socket : SocketIOClient?
// MARK: - A special function to easily read data from an InputStream
internal extension Data {
/// Read the data received in an input stream
///
/// - Parameter input: InputStream to read
init(reading input: InputStream) {
self.init()
input.open()

let bufferSize = 2048
let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: bufferSize)
while input.hasBytesAvailable {
let read = input.read(buffer, maxLength: bufferSize)
if (read == 0) {
break // added
}
self.append(buffer, count: read)
}
buffer.deallocate(capacity: bufferSize)
}
}

public class EverLayoutBridge: NSObject , StreamDelegate {
static let shared : EverLayoutBridge = EverLayoutBridge()

public static var connectedHost : CFString?
public static var connectedPort : UInt32?
public static var connected : Bool = false
private static var attemptingConnection : Bool = false

private static var inputStream : InputStream?
private static var outputStream : OutputStream?

private static let DEFAULT_IP : String = "http://localhost"
private static var connectionLoop : Timer?

private static let DEFAULT_IP : String = "192.168.1.118"
private static let DEFAULT_PORT : String = "3000"

static var readStream : Unmanaged<CFReadStream>?
static var writeStream : Unmanaged<CFWriteStream>?

/// Try to establish a socket connection with the EverLayout Bridge server app
///
/// - Parameters:
/// - IP: Address to connect to
/// - port: Port to connect on
public static func connectToLayoutServer (withIP IP : String? = nil , port : String? = nil)
{
let address = "\(IP ?? self.DEFAULT_IP):\(port ?? self.DEFAULT_PORT)"

self.socket = SocketIOClient(socketURL: URL(string: address)!)

self.socket?.on("connection") { (data, ack) in
print("Connected")
}
let address = (IP ?? self.DEFAULT_IP) as CFString
let port : UInt32 = UInt32(port ?? self.DEFAULT_PORT)!

self.socket?.on("layout-update") { (data, ack) in
let data = self.parseData(data)

if let layoutName = data.dictionary?["layoutName"]?.string , let layoutData = data.dictionary?["layout"]
{
let layoutName : NSString = layoutName as NSString

if let rawData = layoutData.rawData as? Data
{
self.postLayoutUpdate(layoutName: layoutName.deletingPathExtension, layoutData: rawData)
}
}
}
self.connectedHost = address
self.connectedPort = port

self.socket?.connect()
// Schedule the timer
self.connectionLoop?.invalidate()
self.connectionLoop = Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(attemptConnectionToLayoutServer), userInfo: nil, repeats: true)
}

/// Get useful info from the data received
///
/// - Parameter data: raw data
/// - Returns: JSON Data
private static func parseData (_ data : [Any]) -> JSON {
return JSON(data.first as Any)
@objc private static func attemptConnectionToLayoutServer () {
guard self.connected == false , self.attemptingConnection == false , let connectedHost = self.connectedHost , let connectedPort = self.connectedPort else { return }
print("Attempting connection")
self.attemptingConnection = true

self.inputStream?.close()
self.outputStream?.close()

self.inputStream = nil
self.outputStream = nil

// Attempt to link the streams to this server
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, connectedHost, connectedPort, &readStream, &writeStream)

self.inputStream = readStream!.takeRetainedValue()
self.outputStream = writeStream!.takeRetainedValue()

self.inputStream?.delegate = self.shared
self.outputStream?.delegate = self.shared

self.inputStream?.schedule(in: .current, forMode: .defaultRunLoopMode)
self.outputStream?.schedule(in: .current, forMode: .defaultRunLoopMode)

self.inputStream?.open()
self.outputStream?.open()
}

/// Uses NotificationCenter to send update messages to loaded layouts in the app
Expand All @@ -85,8 +123,34 @@ public class EverLayoutBridge: NSObject
///
/// - Parameter message: message to report
public static func sendReport (message : String) {
self.socket?.emit("report", [
"message":message
])
// self.socket?.emit("report", [
// "message":message
// ])
}

public func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
EverLayoutBridge.attemptingConnection = false

if eventCode == Stream.Event.endEncountered {
EverLayoutBridge.connected = false
print("Lost connection to the bridge, attemping reconnection...")
} else if eventCode == Stream.Event.openCompleted {
if EverLayoutBridge.connected == false {
EverLayoutBridge.connected = true
print("Connected to layout server")
}
} else if eventCode == Stream.Event.hasBytesAvailable {
// Data has been received
if let aStream = aStream as? InputStream {
let data = Data(reading: aStream)
let jsonData = JSON(data: data)

if let layoutName = jsonData.dictionary?["name"]?.string {
print(layoutName)

EverLayoutBridge.postLayoutUpdate(layoutName: layoutName, layoutData: data)
}
}
}
}
}
2 changes: 1 addition & 1 deletion Example/EverLayout/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {

self.window?.rootViewController = UINavigationController(rootViewController: ViewController())

EverLayoutBridge.connectToLayoutServer()
EverLayoutBridge.connectToLayoutServer(withIP: nil, port: "3333")

return true
}
Expand Down
27 changes: 2 additions & 25 deletions Example/EverLayout/Layouts/ViewController.json
Original file line number Diff line number Diff line change
@@ -1,29 +1,6 @@
{
"name":"ViewController",
"root":{
"views":{
"!redSquare":{
"properties":{
"backgroundColor":"red"
},
"constraints":{
"center":"@super",
"width height":"+90"
}
}
}
},
"controllerTitle":"Okay",
"templates":{
"squareColor":{
"properties":{
"backgroundColor":"green"
}
}
},
"navigationBar":{
"backgroundColor":"#333333",
"textColor":"white",
"translucent":"false"

}
}
}
11 changes: 0 additions & 11 deletions Example/EverLayout/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,21 @@ import EverLayout
class ViewController: UIViewController , EverLayoutDelegate {
var layout : EverLayout!

let purpleSquare : UIView = UIView()

override func viewDidLoad() {
super.viewDidLoad()

let layoutData = NSData(contentsOfFile: Bundle.main.path(forResource: "ViewController", ofType: "json", inDirectory: "Layouts")!)! as Data
self.layout = EverLayout(layoutData: layoutData)
self.layout.delegate = self
self.layout.build(onView: self.view, viewEnvironment: self)

self.purpleSquare.backgroundColor = .purple
}

override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
super.willTransition(to: newCollection, with: coordinator)

self.layout.updateConstraints(withTraitColelction: newCollection)
}

func layout(_ layout: EverLayout, didLoadOnView view: UIView) {
let template = self.layout.getTemplate("squareColor")
let redSquare = self.layout.viewIndex.viewModel(forKey: "redSquare")
redSquare?.appliedTemplates.append(template!)

// Refresh the layout
self.layout.refresh()
}
}

7 changes: 2 additions & 5 deletions Example/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
PODS:
- EverLayout (0.8.2):
- Socket.IO-Client-Swift (= 8.3.3)
- Socket.IO-Client-Swift (8.3.3)
- EverLayout (0.8.3)

DEPENDENCIES:
- EverLayout (from `../`)
Expand All @@ -11,8 +9,7 @@ EXTERNAL SOURCES:
:path: "../"

SPEC CHECKSUMS:
EverLayout: 88bf2c50aab06857cfebd25df5fcacaf899005b0
Socket.IO-Client-Swift: a2faffdbde89c63aebc5d631041530c1068b02b8
EverLayout: 7c58a5587b72772801963085a11da4cba51451b8

PODFILE CHECKSUM: 3ad4d29e3ae7babd77c018b416f6c4731d8e4c44

Expand Down

0 comments on commit 2361dfa

Please sign in to comment.