Skip to content
Merged
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
8 changes: 8 additions & 0 deletions Blink/Blink.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
4F5F130D24B6612E00A7D9E7 /* Multipeer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F5F130C24B6612E00A7D9E7 /* Multipeer.swift */; };
4F5F130F24B661D700A7D9E7 /* MenuViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F5F130E24B661D700A7D9E7 /* MenuViewModel.swift */; };
4F5F131124B6659A00A7D9E7 /* BrainstormingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F5F131024B6659A00A7D9E7 /* BrainstormingViewModel.swift */; };
4F5F131324B78BCB00A7D9E7 /* VotingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F5F131224B78BCB00A7D9E7 /* VotingViewModel.swift */; };
4F5F131524B8DDB500A7D9E7 /* VotingViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F5F131424B8DDB500A7D9E7 /* VotingViewModelTests.swift */; };
A418231A24B39DDF0082962F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A418231924B39DDF0082962F /* AppDelegate.swift */; };
A418231C24B39DDF0082962F /* MenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A418231B24B39DDF0082962F /* MenuView.swift */; };
A418231E24B39DE10082962F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A418231D24B39DE10082962F /* Assets.xcassets */; };
Expand Down Expand Up @@ -70,6 +72,8 @@
4F5F130C24B6612E00A7D9E7 /* Multipeer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Multipeer.swift; sourceTree = "<group>"; };
4F5F130E24B661D700A7D9E7 /* MenuViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuViewModel.swift; sourceTree = "<group>"; };
4F5F131024B6659A00A7D9E7 /* BrainstormingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrainstormingViewModel.swift; sourceTree = "<group>"; };
4F5F131224B78BCB00A7D9E7 /* VotingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VotingViewModel.swift; sourceTree = "<group>"; };
4F5F131424B8DDB500A7D9E7 /* VotingViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VotingViewModelTests.swift; sourceTree = "<group>"; };
A418231624B39DDF0082962F /* Blink.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Blink.app; sourceTree = BUILT_PRODUCTS_DIR; };
A418231924B39DDF0082962F /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
A418231B24B39DDF0082962F /* MenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -289,6 +293,7 @@
4F5F130A24B6610F00A7D9E7 /* ViewModels */ = {
isa = PBXGroup;
children = (
4F5F131224B78BCB00A7D9E7 /* VotingViewModel.swift */,
);
path = ViewModels;
sourceTree = "<group>";
Expand Down Expand Up @@ -353,6 +358,7 @@
children = (
A418232E24B39DE10082962F /* BlinkTests.swift */,
A418233024B39DE10082962F /* Info.plist */,
4F5F131424B8DDB500A7D9E7 /* VotingViewModelTests.swift */,
);
path = BlinkTests;
sourceTree = "<group>";
Expand Down Expand Up @@ -534,6 +540,7 @@
4F5F12D424B639FA00A7D9E7 /* SceneDelegate.swift in Sources */,
4F5F130F24B661D700A7D9E7 /* MenuViewModel.swift in Sources */,
4F5F12D624B639FA00A7D9E7 /* ContentView.swift in Sources */,
4F5F131324B78BCB00A7D9E7 /* VotingViewModel.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -568,6 +575,7 @@
buildActionMask = 2147483647;
files = (
A418232F24B39DE10082962F /* BlinkTests.swift in Sources */,
4F5F131524B8DDB500A7D9E7 /* VotingViewModelTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import Foundation
import MultipeerConnectivity


class BrainstormingViewModel: NSObject, ObservableObject {

/// Shared instance of the Multipeer Class.
Expand Down
51 changes: 45 additions & 6 deletions Blink/Blink/Voting/ViewModel/VotingViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,52 @@
import Foundation
import MultipeerConnectivity

class VotingViewModel: NSObject, MCSessionDelegate {

class VotingViewModel: NSObject {
typealias Ranking = [(key: String, value: Int)]
let multipeerConnection = Multipeer.shared

var ideas: [String] = []
var votes: [String] = []
var rank: Ranking = []

override init() {
super.init()
multipeerConnection.delegate = self
}

func sendIdeas() {
let mcSession = multipeerConnection.mcSession
if mcSession.connectedPeers.count > 0 {
if let ideasData = try? NSKeyedArchiver.archivedData(withRootObject: ideas, requiringSecureCoding: false) {
do {
try mcSession.send(ideasData, toPeers: mcSession.connectedPeers, with: .reliable)
} catch let error as NSError {
let ac = UIAlertController(title: "Send error", message: error.localizedDescription, preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "Ok", style: .default))
// present(ac, animated: true)
}
}
}
}

func countVotes(votes: [String], ideas: [String]) -> Ranking {
let votedIdeas = Array(Set(votes))
var nonVotedIdeas = [String]()
for i in ideas {
if !votedIdeas.contains(i) {
nonVotedIdeas.append(i)
}
}
let votedIdeasArray = votes.map { ($0, 1) }
let ideasFrequency = Dictionary(votedIdeasArray, uniquingKeysWith: +)
let nonVotedIdeasArray = nonVotedIdeas.map { ($0, 0) }
let ideasNonFrequency = Dictionary(nonVotedIdeasArray, uniquingKeysWith: +)
let votingResult = ideasFrequency.merging(ideasNonFrequency) { (_, new) in new }
return votingResult.sorted(by: {($0.value > $1.value)})
}
}

extension VotingViewModel: MCSessionDelegate {
func session(_ session: MCSession, peer peerID: MCPeerID, didChange state: MCSessionState) {
switch state {
case MCSessionState.connected:
Expand All @@ -30,16 +67,18 @@ class VotingViewModel: NSObject, MCSessionDelegate {
multipeerConnection.connectionStatus = .unknown
}
}

func session(_ session: MCSession, didReceive data: Data, fromPeer peerID: MCPeerID) {
if let votesList:[String] = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? [String] {
votes += votesList }
}

func session(_ session: MCSession, didReceive stream: InputStream, withName streamName: String, fromPeer peerID: MCPeerID) {
}

func session(_ session: MCSession, didStartReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, with progress: Progress) {
}

func session(_ session: MCSession, didFinishReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, at localURL: URL?, withError error: Error?) {
}
}
30 changes: 30 additions & 0 deletions Blink/BlinkTests/VotingViewModelTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// VotingViewModelTests.swift
// BlinkTests
//
// Created by Edgar Sgroi on 10/07/20.
// Copyright © 2020 Artur Carneiro. All rights reserved.
//

import XCTest
@testable import Blink

class VotingViewModelTests: XCTestCase {

func testCountVotes() {
let viewModel = VotingViewModel()
let ideas = ["preved", "poka", "hola", "yo"]
let votes = ["preved", "hola", "poka", "hola", "poka", "hola"]

XCTAssertFalse(ideas.isEmpty)
XCTAssertFalse(votes.isEmpty)

let result = viewModel.countVotes(votes: votes, ideas: ideas)
XCTAssertFalse(result.isEmpty)
let expectedResult = [(key: "hola", value: 3), (key: "poka", value: 2), (key: "preved", value: 1), (key: "yo", value: 0)]
for index in 0..<expectedResult.count {
XCTAssertEqual(expectedResult[index].value, result[index].value)
}
}

}
70 changes: 70 additions & 0 deletions Blink/Blink_iOS/Voting/ViewModels/VotingViewModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//
// VotingViewModel.swift
// Blink_iOS
//
// Created by Edgar Sgroi on 09/07/20.
// Copyright © 2020 Artur Carneiro. All rights reserved.
//

import Foundation
import MultipeerConnectivity

class VotingViewModel: NSObject {

var multipeerConnection = Multipeer.shared

var ideas: [String] = []
var votes: [String] = []

override init() {
super.init()
multipeerConnection.delegate = self
}

func sendVotes() {
let mcSession = multipeerConnection.mcSession
if mcSession.connectedPeers.count > 0 {
if let votesData = try? NSKeyedArchiver.archivedData(withRootObject: votes, requiringSecureCoding: false) {
do {
try mcSession.send(votesData, toPeers: mcSession.connectedPeers, with: .reliable)
} catch let error as NSError {
let ac = UIAlertController(title: "Send error", message: error.localizedDescription, preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "Ok", style: .default))
// present(ac, animated: true)
}
}
}
}
}

extension VotingViewModel: MCSessionDelegate {
func session(_ session: MCSession, peer peerID: MCPeerID, didChange state: MCSessionState) {
switch state {
case MCSessionState.connected:
multipeerConnection.connectionStatus = .connected
case MCSessionState.connecting:
multipeerConnection.connectionStatus = .connecting
case MCSessionState.notConnected:
multipeerConnection.connectionStatus = .notConnected
@unknown default:
multipeerConnection.connectionStatus = .unknown
}
}

func session(_ session: MCSession, didReceive data: Data, fromPeer peerID: MCPeerID) {
if let ideasList:[String] = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? [String] {
ideas = ideasList
}
}

func session(_ session: MCSession, didReceive stream: InputStream, withName streamName: String, fromPeer peerID: MCPeerID) {
}

func session(_ session: MCSession, didStartReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, with progress: Progress) {
}

func session(_ session: MCSession, didFinishReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, at localURL: URL?, withError error: Error?) {
}


}