Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for "Simulator device set" #25

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 2 additions & 14 deletions Sources/Mussel/MusselNotificationTester.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,6 @@
import Foundation

public class MusselNotificationTester: MusselTester {
var targetAppBundleId: String
var serverHost: String = "localhost"
var serverPort: in_port_t = 10004
var serverEndpoint: String = "simulatorPush"

public required init(targetAppBundleId: String) {
self.targetAppBundleId = targetAppBundleId
}

public func triggerSimulatorNotification(withMessage message: String, additionalKeys: [String: Any]? = nil) {
var innerAlert: [String: Any] = ["alert": message]
if let additionalKeys = additionalKeys {
Expand All @@ -22,14 +13,11 @@ public class MusselNotificationTester: MusselTester {
}

public func triggerSimulatorNotification(withFullPayload payload: [String: Any]) {
let endpoint = "http://\(serverHost):\(serverPort)/\(serverEndpoint)"

let json: [String: Any?] = [
"simulatorId": ProcessInfo.processInfo.environment["SIMULATOR_UDID"],
let options: [String: Any?] = [
"appBundleId": targetAppBundleId,
"pushPayload": payload,
]

serverRequest(endpoint: endpoint, json: json)
serverRequestTask("simulatorPush", options: options)
}
}
36 changes: 25 additions & 11 deletions Sources/Mussel/MusselTester.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,38 @@

import Foundation

protocol MusselTester: AnyObject {
var targetAppBundleId: String { get set }
var serverHost: String { get set }
var serverPort: in_port_t { get set }
var serverEndpoint: String { get set }
open class MusselTester {
var targetAppBundleId: String
private var simulatorId: String?
private var simulatorDeviceSet: String?
var serverHost: String = "localhost"
var serverPort: in_port_t = 10004

init(targetAppBundleId: String)
}
public init(targetAppBundleId: String) {
self.targetAppBundleId = targetAppBundleId

self.simulatorId = ProcessInfo.processInfo.environment["SIMULATOR_UDID"]

// Infer whether the "testing" set is in use.
// Instead of this, we could provide the path to the set, which is HOME truncated at the simulator ID.
self.simulatorDeviceSet = (ProcessInfo.processInfo.environment["HOME"]?.contains("XCTestDevices") ?? false) ? "testing" : nil
}

func serverRequestTask(_ task: String, options taskOptions: [String: Any?]) {
let endpoint = "http://\(serverHost):\(serverPort)/\(task)"

extension MusselTester {
func serverRequest(endpoint: String, json: [String: Any?]) {
guard let endpointUrl = URL(string: endpoint) else {
print("Invalid endpoint URL: \(endpoint)")
return
}

guard let data = try? JSONSerialization.data(withJSONObject: json, options: []) else {
print("Invalid JSON: \(json)")
let requestOptions = taskOptions.merging([
"simulatorId": self.simulatorId,
"simulatorDeviceSet": self.simulatorDeviceSet,
], uniquingKeysWith: { $1 })

guard let data = try? JSONSerialization.data(withJSONObject: requestOptions, options: []) else {
print("Invalid JSON: \(requestOptions)")
return
}

Expand Down
16 changes: 2 additions & 14 deletions Sources/Mussel/MusselUniversalLinkTester.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,11 @@
import Foundation

public class MusselUniversalLinkTester: MusselTester {
var targetAppBundleId: String
var serverHost: String = "localhost"
var serverPort: in_port_t = 10004
var serverEndpoint: String = "simulatorUniversalLink"

public required init(targetAppBundleId: String) {
self.targetAppBundleId = targetAppBundleId
}

public func open(_ link: String) {
let endpoint = "http://\(serverHost):\(serverPort)/\(serverEndpoint)"

let json: [String: Any?] = [
"simulatorId": ProcessInfo.processInfo.environment["SIMULATOR_UDID"],
let options: [String: Any?] = [
"link": link,
]

serverRequest(endpoint: endpoint, json: json)
serverRequestTask("simulatorUniversalLink", options: options)
}
}
26 changes: 21 additions & 5 deletions Sources/MusselServer/ServerManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class ServerManager {

private func setupPushEndpoint() {
let response: ((HttpRequest) -> HttpResponse) = { [weak self] request in
guard let self = self else { return .internalServerError }
guard let serializedObject = try? JSONSerialization.jsonObject(with: Data(request.body), options: []),
let json = serializedObject as? JSON,
let simId = json["simulatorId"] as? String,
Expand All @@ -33,9 +34,16 @@ class ServerManager {
return HttpResponse.badRequest(nil)
}

if let pushFileUrl = self?.createTemporaryPushFile(payload: payload) {
let command = "xcrun simctl push \(simId) \(appBundleId) \(pushFileUrl.path)"
self?.run(command: command)
let simctlOptions: String
if let simulatorDeviceSet = json["simulatorDeviceSet"] as? String {
simctlOptions = "--set \(simulatorDeviceSet) "
} else {
simctlOptions = ""
}

if let pushFileUrl = self.createTemporaryPushFile(payload: payload) {
let command = "xcrun simctl \(simctlOptions)push \(simId) \(appBundleId) \(pushFileUrl.path)"
self.run(command: command)

do {
try FileManager.default.removeItem(at: pushFileUrl)
Expand All @@ -54,6 +62,7 @@ class ServerManager {

private func setupUniversalLinkEndpoint() {
let response: ((HttpRequest) -> HttpResponse) = { [weak self] request in
guard let self = self else { return .internalServerError }
guard let serializedObject = try? JSONSerialization.jsonObject(with: Data(request.body), options: []),
let json = serializedObject as? JSON,
let simId = json["simulatorId"] as? String,
Expand All @@ -62,8 +71,15 @@ class ServerManager {
return HttpResponse.badRequest(nil)
}

let command = "xcrun simctl openurl \(simId) \(universalLink)"
self?.run(command: command)
let simctlOptions: String
if let simulatorDeviceSet = json["simulatorDeviceSet"] as? String {
simctlOptions = "--set \(simulatorDeviceSet) "
} else {
simctlOptions = ""
}

let command = "xcrun simctl \(simctlOptions)openurl \(simId) \(universalLink)"
self.run(command: command)
return .ok(.text("Ran command: \(command)"))
}

Expand Down