From 25375c899f0dc6175397de9b285df3ae25ec0837 Mon Sep 17 00:00:00 2001 From: Okechi Date: Wed, 2 Mar 2016 23:44:57 -0500 Subject: [PATCH] Finally working on multiplier part of app --- GetHip.xcodeproj/project.pbxproj | 13 +- GetHip/AppDelegate.swift | 24 ++- GetHip/BackToHomeScreenViewController.swift | 4 +- GetHip/CurrentlyPlayingViewController.swift | 40 +++- GetHip/FriendsListViewController.swift | 34 +++- GetHip/HomeScreenViewController.swift | 46 +++-- .../AppIcon.appiconset/Contents.json | 175 ++++++++++++++++++ .../AppIcon.appiconset/Icon-60@2x.png | Bin 0 -> 5389 bytes .../AppIcon.appiconset/Icon-60@3x.png | Bin 0 -> 7950 bytes .../AppIcon.appiconset/Icon-Small-1.png | Bin 0 -> 1078 bytes .../AppIcon.appiconset/Icon-Small.png | Bin 0 -> 1078 bytes .../AppIcon.appiconset/Icon-Small@2x-1.png | Bin 0 -> 2477 bytes .../AppIcon.appiconset/Icon-Small@2x.png | Bin 0 -> 2477 bytes .../AppIcon.appiconset/Icon-Small@3x.png | Bin 0 -> 3594 bytes .../AppIcon.appiconset/Icon-Spotlight-40.png | Bin 0 -> 1537 bytes .../Icon-Spotlight-40@2x-1.png | Bin 0 -> 3435 bytes .../Icon-Spotlight-40@2x.png | Bin 0 -> 3435 bytes .../Icon-Spotlight-40@3x.png | Bin 0 -> 5067 bytes .../AppIcon.appiconset/Icon.png | Bin 0 -> 2323 bytes .../AppIcon.appiconset/Icon@2x.png | Bin 0 -> 5111 bytes GetHip/Info.plist | 8 +- GetHip/InvitedToPartyViewController.swift | 76 +++++++- GetHip/JoiningPartyViewController.swift | 73 ++++++++ GetHip/LoadingPartyViewController.swift | 60 +++++- GetHip/LoginController.swift | 15 +- GetHip/Main.storyboard | 47 ++--- GetHip/PartyServiceManager.swift | 89 +++++---- GetHip/SettingsTableViewController.swift | 37 +++- GetHip/SongSelectionViewController.swift | 11 ++ GetHip/TestInviteFriendsController.swift | 77 +++++++- 30 files changed, 725 insertions(+), 104 deletions(-) create mode 100644 GetHip/Images-3.xcassets/AppIcon.appiconset/Contents.json create mode 100644 GetHip/Images-3.xcassets/AppIcon.appiconset/Icon-60@2x.png create mode 100644 GetHip/Images-3.xcassets/AppIcon.appiconset/Icon-60@3x.png create mode 100644 GetHip/Images-3.xcassets/AppIcon.appiconset/Icon-Small-1.png create mode 100644 GetHip/Images-3.xcassets/AppIcon.appiconset/Icon-Small.png create mode 100644 GetHip/Images-3.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png create mode 100644 GetHip/Images-3.xcassets/AppIcon.appiconset/Icon-Small@2x.png create mode 100644 GetHip/Images-3.xcassets/AppIcon.appiconset/Icon-Small@3x.png create mode 100644 GetHip/Images-3.xcassets/AppIcon.appiconset/Icon-Spotlight-40.png create mode 100644 GetHip/Images-3.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x-1.png create mode 100644 GetHip/Images-3.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x.png create mode 100644 GetHip/Images-3.xcassets/AppIcon.appiconset/Icon-Spotlight-40@3x.png create mode 100644 GetHip/Images-3.xcassets/AppIcon.appiconset/Icon.png create mode 100644 GetHip/Images-3.xcassets/AppIcon.appiconset/Icon@2x.png create mode 100644 GetHip/JoiningPartyViewController.swift diff --git a/GetHip.xcodeproj/project.pbxproj b/GetHip.xcodeproj/project.pbxproj index 3083304..8f8acc1 100644 --- a/GetHip.xcodeproj/project.pbxproj +++ b/GetHip.xcodeproj/project.pbxproj @@ -121,6 +121,7 @@ 3E7D37D71C75D80F002E682F /* Lower@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 3E7D37D61C75D80F002E682F /* Lower@2x.png */; }; 3E7D37D91C75D882002E682F /* B2P Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 3E7D37D81C75D882002E682F /* B2P Icon@2x.png */; }; 3E7D37DB1C75D899002E682F /* B2P Button@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 3E7D37DA1C75D899002E682F /* B2P Button@2x.png */; }; + 3EB6B39B1C87B8AE006B674D /* JoiningPartyViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EB6B39A1C87B8AE006B674D /* JoiningPartyViewController.swift */; }; 3EB8845D1C6C647700CCDCCE /* Add More@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 3EB8845B1C6C647700CCDCCE /* Add More@2x.png */; }; 3EB8845E1C6C647700CCDCCE /* Leave Party@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 3EB8845C1C6C647700CCDCCE /* Leave Party@2x.png */; }; 3EBE97661C53CEDA0079B54A /* Send Invites Button.png in Resources */ = {isa = PBXBuildFile; fileRef = 3EBE97651C53CEDA0079B54A /* Send Invites Button.png */; }; @@ -284,6 +285,7 @@ 3E7D37D61C75D80F002E682F /* Lower@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Lower@2x.png"; path = "../../../Dropbox/Gethip/For final/Volume/i5 Volume/Lower@2x.png"; sourceTree = ""; }; 3E7D37D81C75D882002E682F /* B2P Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "B2P Icon@2x.png"; path = "../../../Dropbox/Gethip/For final/Back To Party/i5/B2P Icon@2x.png"; sourceTree = ""; }; 3E7D37DA1C75D899002E682F /* B2P Button@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "B2P Button@2x.png"; path = "../../../Dropbox/Gethip/For final/Back To Party/i5/B2P Button@2x.png"; sourceTree = ""; }; + 3EB6B39A1C87B8AE006B674D /* JoiningPartyViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JoiningPartyViewController.swift; sourceTree = ""; }; 3EB8845B1C6C647700CCDCCE /* Add More@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Add More@2x.png"; path = "../../../Dropbox/Gethip/Screens/iPhone 5 Party Screens/Party Screen/Assets/Add More@2x.png"; sourceTree = ""; }; 3EB8845C1C6C647700CCDCCE /* Leave Party@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Leave Party@2x.png"; path = "../../../Dropbox/Gethip/Screens/iPhone 5 Party Screens/Party Screen/Assets/Leave Party@2x.png"; sourceTree = ""; }; 3EBE97651C53CEDA0079B54A /* Send Invites Button.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Send Invites Button.png"; path = "../../../Dropbox/Gethip/Screens/Friends + Invite Screens/i6/Invite Friends/Send Invites Button.png"; sourceTree = ""; }; @@ -698,6 +700,7 @@ isa = PBXGroup; children = ( 3E6D43881C7831B100CA805F /* InvitedToPartyViewController.swift */, + 3EB6B39A1C87B8AE006B674D /* JoiningPartyViewController.swift */, ); name = InvitedToParty; sourceTree = ""; @@ -773,7 +776,12 @@ TargetAttributes = { 3E1BDA4B1C37111D00EE3B84 = { CreatedOnToolsVersion = 6.3.2; - DevelopmentTeam = 24WJ762CQL; + DevelopmentTeam = VYHHTUJ5PS; + SystemCapabilities = { + com.apple.BackgroundModes = { + enabled = 1; + }; + }; }; 3E1BDA631C37111D00EE3B84 = { CreatedOnToolsVersion = 6.3.2; @@ -898,6 +906,7 @@ 3EDA82E31C4741C70081ED53 /* FriendDataSource.swift in Sources */, 3EDA82E11C473E900081ED53 /* FriendData.swift in Sources */, 3E627FF21C55AE35005C0372 /* TDAudioOutputStreamer.m in Sources */, + 3EB6B39B1C87B8AE006B674D /* JoiningPartyViewController.swift in Sources */, 3E379F051C3F982900F7BCCD /* FriendsCell.swift in Sources */, 3E1BDA571C37111D00EE3B84 /* ViewController.swift in Sources */, 3E1AAD141C3BD92600809367 /* FriendsListViewController.swift in Sources */, @@ -1056,6 +1065,7 @@ ); GCC_PRECOMPILE_PREFIX_HEADER = NO; INFOPLIST_FILE = GetHip/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", @@ -1081,6 +1091,7 @@ ); GCC_PRECOMPILE_PREFIX_HEADER = NO; INFOPLIST_FILE = GetHip/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", diff --git a/GetHip/AppDelegate.swift b/GetHip/AppDelegate.swift index 04b7719..15ee187 100644 --- a/GetHip/AppDelegate.swift +++ b/GetHip/AppDelegate.swift @@ -14,15 +14,16 @@ import CoreLocation class AppDelegate: UIResponder, UIApplicationDelegate , CLLocationManagerDelegate{ var window: UIWindow? - // var locationStarted = false - var locationManager: CLLocationManager! - // var app = UIApplication.sharedApplication() + // var locationStarted = false + var locationManager: CLLocationManager! + var backgroundMode:UIBackgroundTaskIdentifier! + var app = UIApplication.sharedApplication() func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { let userNotificationTypes = UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound - let settings = UIUserNotificationSettings(forTypes: userNotificationTypes, categories: nil) - application.registerUserNotificationSettings(settings) - application.registerForRemoteNotifications() + //let settings = UIUserNotificationSettings(forTypes: userNotificationTypes, categories: nil) + //application.registerUserNotificationSettings(settings) + //application.registerForRemoteNotifications() //create new CLLocaationManager /*var locationStarted = false @@ -76,7 +77,13 @@ class AppDelegate: UIResponder, UIApplicationDelegate , CLLocationManagerDelegat func applicationDidEnterBackground(application: UIApplication) { - // locationManager.startUpdatingLocation() + locationManager.startUpdatingLocation() + self.backgroundMode = self.app.beginBackgroundTaskWithExpirationHandler({ + //called 3 secs before time expires + //kill session and advertiser + self.app.endBackgroundTask(self.backgroundMode) + self.backgroundMode = UIBackgroundTaskInvalid + }) } func applicationWillEnterForeground(application: UIApplication) { @@ -85,6 +92,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate , CLLocationManagerDelegat func applicationDidBecomeActive(application: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + + //work on reinitializing session + self.backgroundMode = UIBackgroundTaskInvalid FBSDKAppEvents.activateApp() } diff --git a/GetHip/BackToHomeScreenViewController.swift b/GetHip/BackToHomeScreenViewController.swift index cb32ac7..afb9d99 100644 --- a/GetHip/BackToHomeScreenViewController.swift +++ b/GetHip/BackToHomeScreenViewController.swift @@ -44,14 +44,14 @@ class BackToHomeScreenViewController: UIViewController { let nav: UINavigationController = (segue.destinationViewController as? UINavigationController)! let vc: SettingsTableViewController = (nav.viewControllers[0] as? SettingsTableViewController)! - vc.setData(self.userData, prty: self.partyData) + vc.setData(self.userData, prty: self.partyData, frends: self.friendData, request: self.requestData) } if segue.identifier == "FromPartyFriendsSegue" { let nav: UINavigationController = (segue.destinationViewController as? UINavigationController)! let vc: FriendsListViewController = (nav.viewControllers[0] as? FriendsListViewController)! - vc.setData(self.friendData, requst: self.requestData, party: self.partyData) + vc.setData(self.friendData, requst: self.requestData, party: self.partyData, user: self.userData) } } diff --git a/GetHip/CurrentlyPlayingViewController.swift b/GetHip/CurrentlyPlayingViewController.swift index 9e55dc6..11d1633 100644 --- a/GetHip/CurrentlyPlayingViewController.swift +++ b/GetHip/CurrentlyPlayingViewController.swift @@ -8,13 +8,17 @@ import UIKit import MediaPlayer +import AVFoundation -class CurrentlyPlayingViewController: UIViewController { +class CurrentlyPlayingViewController: UIViewController{ //persistant data var party: PartyServiceManager! var usr: [UserParseData] = [] var frnds: [FriendData] = [] var requestData: [FriendData] = [] + var audioPlayer: AVPlayer! + var playing = true + var timer = NSTimer() //controller data @IBOutlet var songImg: UIImageView! @@ -27,8 +31,22 @@ class CurrentlyPlayingViewController: UIViewController { //Host buttons @IBOutlet var volCtrl: UISlider! @IBOutlet var ppfButton: UIButton! - @IBAction func playPauseFav(sender: UIButton){ + @IBAction func volChng(sender: UISlider){ + self.audioPlayer.volume = sender.value + } + @IBAction func playPauseFav(sender: UIButton){ + if(playing == true){ + self.audioPlayer.pause() + self.playing = false + self.ppfButton.setBackgroundImage(UIImage(named: "Play-52.png"), forState: UIControlState.Normal) + + }else{ + self.audioPlayer.play() + self.playing = true + self.ppfButton.setBackgroundImage(UIImage(named: "Pause-52.png"), forState: UIControlState.Normal) + + } } @@ -39,15 +57,29 @@ class CurrentlyPlayingViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - + self.audioPlayer = AVPlayer(URL: self.party.currentSong.valueForProperty(MPMediaItemPropertyAssetURL) as! NSURL) + // Do any additional setup after loading the view. self.songImg.image = self.party.currentSong.valueForProperty(MPMediaItemPropertyArtwork).imageWithSize(songImg.frame.size) self.titleLabel.text = (self.party.currentSong.valueForProperty(MPMediaItemPropertyTitle) as? String!)! self.artistAndAlbumLabel.text = (self.party.currentSong.valueForProperty(MPMediaItemPropertyArtist) as? String!)! + " - " + (self.party.currentSong.valueForProperty(MPMediaItemPropertyAlbumTitle) as? String!)! - + self.audioPlayer.volume = self.volCtrl.value + self.maxLabel.text = String(stringInterpolationSegment: self.audioPlayer.currentItem.duration.value) + self.audioPlayer.play() + self.timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("updateLabels"), userInfo: nil, repeats: true) } + func updateLabels(){ + var timeLeft = self.audioPlayer.currentItem.duration.value - self.audioPlayer.currentTime().value + var interval = timeLeft + var seconds = interval%60 + println(seconds) + var minutes = (interval/60)%60 + println(minutes) + //self.maxLabel.text + //self.minLabel.text + } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. diff --git a/GetHip/FriendsListViewController.swift b/GetHip/FriendsListViewController.swift index 1df14a2..615a635 100644 --- a/GetHip/FriendsListViewController.swift +++ b/GetHip/FriendsListViewController.swift @@ -7,11 +7,13 @@ // import UIKit +import MultipeerConnectivity -class FriendsListViewController: UIViewController, UITableViewDelegate, UITableViewDataSource/*PFQueryTableViewController*/ { +class FriendsListViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, PartyServiceManagerDelegate { //var manager = FriendDataSource() var friends = [] var request = [] + var user: [UserParseData]! var party: PartyServiceManager! @IBOutlet weak var table: UITableView! @@ -27,16 +29,18 @@ class FriendsListViewController: UIViewController, UITableViewDelegate, UITableV self.performSegueWithIdentifier("FriendRequestSegue", sender: nil) } - func setData(frnds:[FriendData], requst: [FriendData], party: PartyServiceManager){ + func setData(frnds:[FriendData], requst: [FriendData], party: PartyServiceManager, user: [UserParseData]){ self.friends = frnds self.request = requst self.party = party + self.user = user } override func viewDidLoad() { super.viewDidLoad() self.table.delegate = self self.table.dataSource = self + self.party.delegate = self self.title = "Friends" self.navigationController?.navigationBarHidden = false @@ -181,3 +185,29 @@ class FriendsListViewController: UIViewController, UITableViewDelegate, UITableV } } + +extension FriendsListViewController: PartyServiceManagerDelegate { + func foundPeer() { + + } + + func lostPeer() { + + } + + func invitationWasRecieved(peerID: MCPeerID, invitationHandler: ((Bool, MCSession!) -> Void)!) { + var storyboard = UIStoryboard(name: "Main", bundle: nil) + var vc: InvitedToPartyViewController = storyboard.instantiateViewControllerWithIdentifier("InvitedToPartyVC") as! InvitedToPartyViewController! + vc.setData(self.party, user: self.user, friends: (self.friends as! [FriendData]), request: (self.request as! [FriendData]), invHand: invitationHandler, fromPeer: peerID) + self.presentViewController(vc, animated: true, completion: nil) + } + + func connectedWithPeer(peerID: MCPeerID) { + + } + + func didRecieveInstruction(dictionary: Dictionary){ + + } +} + diff --git a/GetHip/HomeScreenViewController.swift b/GetHip/HomeScreenViewController.swift index 2908cbd..0d9a030 100644 --- a/GetHip/HomeScreenViewController.swift +++ b/GetHip/HomeScreenViewController.swift @@ -7,8 +7,9 @@ // import UIKit +import MultipeerConnectivity -class HomeScreenViewController: UIViewController { +class HomeScreenViewController: UIViewController, PartyServiceManagerDelegate { var usrDataManager: UserParseDataSource! var frndDataManager: FriendDataSource! var friendData: [FriendData] = [] @@ -40,10 +41,13 @@ class HomeScreenViewController: UIViewController { if(self.firstTime == true){ self.partyData.setPeerID((self.userData[0].displayName)) + self.partyData.initializeSession() + self.partyData.setAdvertiser() //start peer-to-peer advertising self.partyData.startListening() + self.partyData.delegate = self self.firstTime = false } @@ -54,14 +58,6 @@ class HomeScreenViewController: UIViewController { } - @IBAction func testGuest(sender: UIButton){ - var storyboard = UIStoryboard(name: "Main", bundle: nil) - var vc: InvitedToPartyViewController = storyboard.instantiateViewControllerWithIdentifier("InvitedToPartyVC") as! InvitedToPartyViewController! - vc.setData(self.partyData, user: self.userData, friends: self.friendData, request: self.requestData) - self.presentViewController(vc, animated: true, completion: nil) - } - - override func viewDidLoad() { super.viewDidLoad() @@ -116,14 +112,14 @@ class HomeScreenViewController: UIViewController { let nav: UINavigationController = (segue.destinationViewController as? UINavigationController)! let vc: SettingsTableViewController = (nav.viewControllers[0] as? SettingsTableViewController)! - vc.setData(self.userData, prty: self.partyData) + vc.setData(self.userData, prty: self.partyData, frends: self.friendData, request: self.requestData) } if segue.identifier == "FriendListSegue" { let nav: UINavigationController = (segue.destinationViewController as? UINavigationController)! let vc: FriendsListViewController = (nav.viewControllers[0] as? FriendsListViewController)! - vc.setData(self.friendData, requst: self.requestData, party: self.partyData) + vc.setData(self.friendData, requst: self.requestData, party: self.partyData, user: self.userData) } } @@ -138,3 +134,31 @@ class HomeScreenViewController: UIViewController { */ } + +extension HomeScreenViewController: PartyServiceManagerDelegate { + func foundPeer() { + + } + + func lostPeer() { + + } + + func invitationWasRecieved(peerID: MCPeerID, invitationHandler: ((Bool, MCSession!) -> Void)!) { + var storyboard = UIStoryboard(name: "Main", bundle: nil) + var vc: InvitedToPartyViewController = storyboard.instantiateViewControllerWithIdentifier("InvitedToPartyVC") as! InvitedToPartyViewController! + vc.setData(self.partyData, user: self.userData, friends: self.friendData, request: self.requestData, invHand: invitationHandler, fromPeer: peerID) + self.presentViewController(vc, animated: true, completion: nil) + } + + func connectedWithPeer(peerID: MCPeerID) { + + } + + func didRecieveInstruction(dictionary: Dictionary){ + + } +} + + + diff --git a/GetHip/Images-3.xcassets/AppIcon.appiconset/Contents.json b/GetHip/Images-3.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..a47b64c --- /dev/null +++ b/GetHip/Images-3.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,175 @@ +{ + "images" : [ + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-Small.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-Small@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-Small@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-Spotlight-40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-Spotlight-40@3x.png", + "scale" : "3x" + }, + { + "size" : "57x57", + "idiom" : "iphone", + "filename" : "Icon.png", + "scale" : "1x" + }, + { + "size" : "57x57", + "idiom" : "iphone", + "filename" : "Icon@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-60@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-Small-1.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-Small@2x-1.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-Spotlight-40.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-Spotlight-40@2x-1.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "50x50", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "50x50", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "72x72", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "72x72", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "car", + "size" : "120x120", + "scale" : "1x" + }, + { + "size" : "24x24", + "idiom" : "watch", + "scale" : "2x", + "role" : "notificationCenter", + "subtype" : "38mm" + }, + { + "size" : "27.5x27.5", + "idiom" : "watch", + "scale" : "2x", + "role" : "notificationCenter", + "subtype" : "42mm" + }, + { + "size" : "29x29", + "idiom" : "watch", + "role" : "companionSettings", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "watch", + "role" : "companionSettings", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "watch", + "scale" : "2x", + "role" : "appLauncher", + "subtype" : "38mm" + }, + { + "size" : "44x44", + "idiom" : "watch", + "scale" : "2x", + "role" : "longLook", + "subtype" : "42mm" + }, + { + "size" : "86x86", + "idiom" : "watch", + "scale" : "2x", + "role" : "quickLook", + "subtype" : "38mm" + }, + { + "size" : "98x98", + "idiom" : "watch", + "scale" : "2x", + "role" : "quickLook", + "subtype" : "42mm" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetHip/Images-3.xcassets/AppIcon.appiconset/Icon-60@2x.png b/GetHip/Images-3.xcassets/AppIcon.appiconset/Icon-60@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..5fd0f340c9bc43c611780dc377a3a7e4bb4b73f6 GIT binary patch literal 5389 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 Ef~WdGw*UYD literal 0 HcmV?d00001 diff --git a/GetHip/Images-3.xcassets/AppIcon.appiconset/Icon-Small-1.png b/GetHip/Images-3.xcassets/AppIcon.appiconset/Icon-Small-1.png new file mode 100644 index 0000000000000000000000000000000000000000..765c0230f07f6ab01009e93db4231186df678272 GIT binary patch literal 1078 zcmV-61j+k}P)Px&@JU2LR7ee_R!MIoMHH^3SKH&n3EnamG0A`gNOMFQE+a)^!~w2|8$$3O_!0a9 zj)()7IUq3ygb)HW2ZUI}g1*PJmSRqu8;nanI%LXcjL&T?xVVZd#Bk4SeQf{nq44(LU_q!kbz`y; zrabw^Y~R;bDXQJ$!Nr``;)^LREV+y;cca?t+AP8cQzORB#Q`T4(>!RU^G#KJ380J# zW)yhPV|=>1IQ-O7$I4n`N%&e`{A_f-5W~Y|Qar^)_0b8yjfQ;GW;)jPdfIJ^Q%x;+ z+P|FX(E8^iG2HiG{6O1fsUt2-&Xm^hpwY=_I>|Y@8X|Hfc#L(Vel!}EEPKte$j!O$p9R59*L9?9c^(iOxm?!s zSwHZ&x&yaIUjM63r{xX61&qdVe5YJ_qtVzO4nNu5-Ko`fYV}YlLx|rlFTdnF-*~Q2Fa+-fK~5SJJG`O@S)`O1yy4yy zf_P+!nBl_U;mJuq4Bu`xUtTRmO2OtC+o2Q_9H0S#Io_00%(2Ei^-5aFdx8rHFNzTU zhU?zCQ4HcZ)EY^E2DWaP$pHbcJb=Tc} z{J1+FlQz(8Ay+Jma2+AYA7V$7K!=v3JgXa`0GHNa@cBU-)obSSQiy&OUe(4NDD-4< zxcTY)4CeRh8(>ZH87@u>I`OT|=GVtZXiTI60Ya(jIHa8cWx+xMI8^2LUJuH5E7cq- zoSr&5$C)NWWzoOLDJa7R$thWuEyP%3|uB#aJq{@FOc$zq>w?WOtBUxV?n zva8xCYHJ-80kh@!av^)a%JUzXu%qPrlH4aWmf?%9jF#Q+#KkXhVVjA$kM|S$Z0ho9 wemM^>c|1~1ZT=W9nFkQIRy8YK%>dE)58O)5rb4e5)Bpeg07*qoM6N<$g63lq9{>OV literal 0 HcmV?d00001 diff --git a/GetHip/Images-3.xcassets/AppIcon.appiconset/Icon-Small.png b/GetHip/Images-3.xcassets/AppIcon.appiconset/Icon-Small.png new file mode 100644 index 0000000000000000000000000000000000000000..765c0230f07f6ab01009e93db4231186df678272 GIT binary patch literal 1078 zcmV-61j+k}P)Px&@JU2LR7ee_R!MIoMHH^3SKH&n3EnamG0A`gNOMFQE+a)^!~w2|8$$3O_!0a9 zj)()7IUq3ygb)HW2ZUI}g1*PJmSRqu8;nanI%LXcjL&T?xVVZd#Bk4SeQf{nq44(LU_q!kbz`y; zrabw^Y~R;bDXQJ$!Nr``;)^LREV+y;cca?t+AP8cQzORB#Q`T4(>!RU^G#KJ380J# zW)yhPV|=>1IQ-O7$I4n`N%&e`{A_f-5W~Y|Qar^)_0b8yjfQ;GW;)jPdfIJ^Q%x;+ z+P|FX(E8^iG2HiG{6O1fsUt2-&Xm^hpwY=_I>|Y@8X|Hfc#L(Vel!}EEPKte$j!O$p9R59*L9?9c^(iOxm?!s zSwHZ&x&yaIUjM63r{xX61&qdVe5YJ_qtVzO4nNu5-Ko`fYV}YlLx|rlFTdnF-*~Q2Fa+-fK~5SJJG`O@S)`O1yy4yy zf_P+!nBl_U;mJuq4Bu`xUtTRmO2OtC+o2Q_9H0S#Io_00%(2Ei^-5aFdx8rHFNzTU zhU?zCQ4HcZ)EY^E2DWaP$pHbcJb=Tc} z{J1+FlQz(8Ay+Jma2+AYA7V$7K!=v3JgXa`0GHNa@cBU-)obSSQiy&OUe(4NDD-4< zxcTY)4CeRh8(>ZH87@u>I`OT|=GVtZXiTI60Ya(jIHa8cWx+xMI8^2LUJuH5E7cq- zoSr&5$C)NWWzoOLDJa7R$thWuEyP%3|uB#aJq{@FOc$zq>w?WOtBUxV?n zva8xCYHJ-80kh@!av^)a%JUzXu%qPrlH4aWmf?%9jF#Q+#KkXhVVjA$kM|S$Z0ho9 wemM^>c|1~1ZT=W9nFkQIRy8YK%>dE)58O)5rb4e5)Bpeg07*qoM6N<$g63lq9{>OV literal 0 HcmV?d00001 diff --git a/GetHip/Images-3.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png b/GetHip/Images-3.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png new file mode 100644 index 0000000000000000000000000000000000000000..c3cc244a7ae55115f29d581e0209d3602da2823d GIT binary patch literal 2477 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 literal 0 HcmV?d00001 diff --git a/GetHip/Images-3.xcassets/AppIcon.appiconset/Icon-Small@2x.png b/GetHip/Images-3.xcassets/AppIcon.appiconset/Icon-Small@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..c3cc244a7ae55115f29d581e0209d3602da2823d GIT binary patch literal 2477 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 literal 0 HcmV?d00001 diff --git a/GetHip/Images-3.xcassets/AppIcon.appiconset/Icon-Small@3x.png b/GetHip/Images-3.xcassets/AppIcon.appiconset/Icon-Small@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..d5fccc6a1e96898442af9c1472796c94f4dde268 GIT binary patch literal 3594 zcmV+l4)yVgP)Px?#7RU!RCodHocnJhR~5(S&Wz)CoZW1k-6Z?yX1DKF0u>5UX}3tUh=M94exrz= zfq#d;03`T*CtLJJGSS+=gy7CV|!-oba&I(tz{)M zcg{WcobP$u$J}eNzP_$~?mznH9svo!7bx5f3c}RH@E~X&IwH_tbM?KO#@gF%vS>}c zq`CH?nH;kUhe5&DfBjvf^dHTtx~WNP@_9{9fy*(|>u}=qhk`KRs_)%0*8eK?w`-bi zYDQ8tw)OoLCp)XT*5R5xX4Jh;1~G6RlEWU_<}IA+R|&Hvfz$AKBOqP zj+4Kvt-U27@cKe0d(kdFXBQrmvEVc`r{*Td-H}sz`I5@DPE2RgfU z{<3lBAEJK8O`aOupokp>3&Y7>((JNS4;Sd}4_({MoMkAj@6Bo6m|{R3A{GULA~!1< zWxcu-uB7X@BV$hLjK2HvfaqaQ?_LWT8ZoD&v*6>pqP8ja*CUZS_SnQ^#{=2vFB6Neb`Fh%AsQvUbk*4TP+`O@ z!_J-`(D`LA6i5x(3+N^)^X}La2fctW^zx0w+^(T#*ih5SG`Kgtv0sOM9V!{Cd*PKPYES{?JGW*UXU) zn#wV`wCGJdM4Dv-^*Q3=qD0ijlQdeBK*V43zdw zVWabc%zxW@=>wJ(^xaS7Qo`PCJ9S!V&RSdT(ogitf)_HUngd7QJDThV1VLhTEh67jk{xRsdUf8_lWuy3 zg$6J9Tlo)#4RjaUzHRR|8as{po@Lc-2MR-olwo8|b2O32ndXRLfQ8)-2h~fBM%^Ky zNa)ZdZJK%0Y&Fm=tfs+ayIv2{6cULMUH3~Y*DVDIV4F)MGKS$3gmH~ocSP*uxSc9` z;{x(uYporrOh)jVxY2MOiJa#?KfLe&oE5|nlxnqK+_>%| z4!0Mlrk*}E5yKWfkrClF;tdDnRqKOpDE$7$#y>YV)@wC1r-Tm@@NLm~S2f33u2ygF z?JZTRKc1cKc&Z#k)j{q6h8=`$w@~u+QSfnBLPJVFsD@!IN#-Nd5MRUx743zfY$ zmzGeB_SDy>IuHnl@ZdlWzR);AoX=&c+ieg<0|zCv&no6ZRf(dfIg9}kih#cf@>&c# z@6jPpK#i;0TYp$wtlBo$K4&Zg$I)oS%-xxC$| zPo`23N62vRioNiZff?{e6N!2?-4_a=OA35_aRK%G;K$mh)9L3XPtWG_xB!pP^1$FY zfR>m@YM1hPGSjYAC;#7n3?!P$7ii0m2=ksq1nexw{nPSN#jCr%b=iB z|1d5`1_4Nu1CY~)925FthlzGj);n{c=lgdyrH^|b8ps;P3sX}n3SwA)CXa%?AVKkx zr4LG!NIg&>Bdk=b^!a|`B^I7Mak7|7A4Rr{k~+Fv8oy~UsDhwGSBf7sd0dDE+`;b} z8LmEBDBKSxM`FK~P>CVv>E8HkFd`V?`}PavsS11a5on7e_~3Foo=lFXQlThd2S0E^ zn+&a`DA5q7dv|S>ad>E53SrJvh4E|@fu!m51vzZ%nVNf`ASWk{Izs@}FlqnfNRrt> zcQ`=7vi&YR+&`N8<@3<+OHIW8ZXdO!4`bI z2}e6!`&}Fg)MosLZd|Ajd^0A)5YdeS!hN{4^~T~tsMF#F#Z>A?7iXnqn%p}6!`73y zqxg`wgjHaGKy!S1vWP>0%1F;Q$R>s<7&UOdF#m%IZq-woyC*6DyY+g z_<0_(?!bv^jt=;-u@lb}i!m;PjZ5_ga~Uk*o;mr`hcZg20kh53GjfCFu@BE))3%wW_*xfY|pk|daz@QZuk z3ve7yC2y2>RXRWpx{S5`{d3Lb9o4W>gT5n`JlF~b3Y+!AZSw&Ld?&_zAc%59UkonL z95O!ql@Z~sy95ckuX~IgY4~g=8-yQQeXzY9YGEZMZL2SGbhmc|CHNF`{QSY!3<@9B zdXMbLVj^aTW2M<&;vH8@+h00)@=Q7%6T?yM-S2XY^iZL2F`rir;R`X&woz$zT15(VGaz{>u2NbYL-CX1;Ry z)%n{UOK<(OcfV;c61E|8snq~X*N>@sL`5C&ZZ4ky5f>lZxkdDj`Q`2;%Zd_90UT$ ze=~QB?(I^3lr(`8GPocoA_4DdAU;y{jgNR&dSOZ!g`@nQ48|`q}-1rLgJ*>5xWDO;?3PMEpwrCMxc|ozG^Gh1W_s^aGMsbpDOr&C;DGez7(Ht+}t56FuamKI)!#BaJU= z6q9~YpgurA{mnCHUb#5?=-3!af(4pWu9^XV^@W%c%F$fWutLd#eMh2FG?1xpPg#`? zKE1jKDh7v{Oxt@v-sMeaGYseAnfDbDeoOGe+erjJICq|;aD8`|SlF!BSe~XFJAen? z2v~GcXihK7gql|sQ<)5}RjD47hT#na%4Glx`ruQ)(clF*G9t3H)*Ct%m5K%#9xfEV zd~*C>TX(<+lbp-so|!26X*4L355e;axMHLV0E?|w2;^eP`<8|FT|F29h=Aw#g0P_~~Q1)rUa zf@V76TB*ff9HXV8PaU{W5(f&}JSA8jyzZzK+5~`NB$~I0wqWIm>%&DvC=;b{=%e_; ze&p-s&`&M$(V>!Y4-f1XVxUTdJnq-Wk%b{ffr(VbTz*}z+}7kCy^cs~v*z%kK<=(C zn@hhRx%TtK;%_y#5wm4~h*97K&kbpD*EUw)O3eM*+nN^c5yOjuYq4=(p}?+nW9xl$ z?VYHd+Cz#09c6u+L$7Y?wA`S})-+)l8-J4<7Xv%{{oF9DD3BBu^!k=vc)Wh;r`E(3 z0z+===46vR&C&T8QWP*fM;REivT^DPdCJ2~Rkrgk_4xbLv|f?VHX6BFAEIO}vv*flRH z=xrcGN9z!vAT{Tw4@7lIu=Jar;#V<M~T=0H2qxqX5p{fT82N?x9I$Ae3 z-}8Py%1`smorRO{JdqMmIpor>9P(@sig@MHJ}7qT{5*)Ae>n7@Ta-qFi~{S+$q8%X zSvf)C47fZ7?l4TQUwB31CzSf^9z0;~!Ag7-z(-O}2ca=>(kt^a5Ykh!YhcASY?vG) z&!D5AOxgUgNuopQA2~XT0%DM}qpuT7NrzV4uPiSHIWM#+a#uHBpdjJ07*qoM6N<$f-dXjOaK4? literal 0 HcmV?d00001 diff --git a/GetHip/Images-3.xcassets/AppIcon.appiconset/Icon-Spotlight-40.png b/GetHip/Images-3.xcassets/AppIcon.appiconset/Icon-Spotlight-40.png new file mode 100644 index 0000000000000000000000000000000000000000..dbce28ef42565aacd7344014fba9b4326cf66b73 GIT binary patch literal 1537 zcmV+c2LAbpP)Px)yGcYrR9FecS4)o+RTRFDs_L%lC*AWN2N(tgAs9q3BuFAr7p{zniAxvm{4d5o z;7&KVaN))nU;&95H71fsK$KxXr)PS4hM9g=cRlX)yItKy-5w?}+8rzXxQ}zrci#6F zt<`Ge|9IH5K`A55B!oVDcO0w6s1QI>gZg#8{T&HA!Qwkaicy+z%ynSOY0zR%ellv` zQui;JnhIy%lH4Xljsr`RkpQL!Yu+;-e?hw&gqq^eIcXLYeC{NXfyOkBNfMaS(51ba z$ej#ku886p+F9p~dm{hh1Pmq#U>OQ~F)Uy755KQ6O9V1iqCtZQZxUIS$Z9F1StLeA zAqn_a60?8+Q*VbL?_4r~6#I+e)-qja1l>Q*FA@x5QH`=0qgEv+dMw57e^9sj8B zWI2f*lC)T&d!T~D;u*p$B129YqewX^DMj;Sl%kIWV$jG8ETRCVB1rmvWPM~BQ_{pC zq3RfIQd(uMB#J-V?bTLmyVv!Ez)IdUmz>OrLcwIL7X&xAwmL!Za_P`=HV1e}gdW`> zxV2SvgYayrbS#@|1^%sS)eXbb#lnevAtH;gHH%euG#rDHt*(2mva#A~_QDW`0#y*{ z3t6@r$8)(9V}X=+_I7tYZ^?01a`{*y2EXp^?)m;w#sQ_8*7xe3H)p3ICnf`S5*Sm- z3E6brt7~gJy|Frta2X}~aKt8&99-a<>zV6h&nfB}@tnu@aF`*51g zIebvGtPfU>1NH05I>O&KV88@zE|kl!PEY&&t^&rE?|=IHeegyU5i!(_9Ijy{Cm5qe zK+UG_-)}T5u4({^EZFv<q$pNY z{Zu*)K{vNHSDQ@)40!=nl7waIW{jj|ai{U63jmI2TD&mR{e3JymBwmN3(5sOyq3U{WlI$745jKkWImbawqf8a2 zlxfD1W%IVZ;5eR;=tM{>bpKh~PGTc27s^vzq1I6j^R{zoW(K|X;`B_C3@FLdNz(~d zq6Scd$|9HrW7WTEnURfAPr!6UVsd?u9IBQW9FznYb#=T4>1bh3L#n$JWKjvl^zk6M z4j~~_?(M1@V|FEZq0q8AW*+AN?+J~&*1eC7>J37lo>7wrmV$L2iQ-Gf=5^Y|g>`^E zX<&-$6!jY3u@A%2`Q%Ocz!;Cm+qk^A>(a~+?gZ19DBcr>@17F{rf@84JrvGiRS>D^ zet`_z_;@VaFGa;t;Fb=HMP?ay*8XXZ`Wifwu~-@Uz*zr^22H%{%Jf|9;UVt6mKksS zw*lqV>%4JSQWhRMM|isb%BhK*jK%Qm%oW0HY0n4KuMxdxMfeA{OijIiF+q%@<0N|H n-6vr}79)$penRa794`C~=3CMHszei)00000NkvXXu0mjfH;3QE literal 0 HcmV?d00001 diff --git a/GetHip/Images-3.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x-1.png b/GetHip/Images-3.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x-1.png new file mode 100644 index 0000000000000000000000000000000000000000..30dc15bec8d42a05b412e729eda1fbde7d351b14 GIT binary patch literal 3435 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 literal 0 HcmV?d00001 diff --git a/GetHip/Images-3.xcassets/AppIcon.appiconset/Icon.png b/GetHip/Images-3.xcassets/AppIcon.appiconset/Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..036a9eab99bca68c25d97c481d78091dde873cd3 GIT binary patch literal 2323 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 Z{vTb&Ou<8dHDUk&002ovPDHLkV1j77)s_GN literal 0 HcmV?d00001 diff --git a/GetHip/Info.plist b/GetHip/Info.plist index ceed721..e93260b 100644 --- a/GetHip/Info.plist +++ b/GetHip/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - oonyeje.Kroleo.$(PRODUCT_NAME:rfc1034identifier) + com.Kroleo.$(PRODUCT_NAME:rfc1034identifier) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -37,6 +37,12 @@ Get Hip! LSRequiresIPhoneOS + UIBackgroundModes + + audio + location + remote-notification + UILaunchStoryboardName LaunchScreen UIMainStoryboardFile diff --git a/GetHip/InvitedToPartyViewController.swift b/GetHip/InvitedToPartyViewController.swift index c6a8265..c24d125 100644 --- a/GetHip/InvitedToPartyViewController.swift +++ b/GetHip/InvitedToPartyViewController.swift @@ -7,27 +7,60 @@ // import UIKit +import MultipeerConnectivity -class InvitedToPartyViewController: UIViewController { +class InvitedToPartyViewController: UIViewController , PartyServiceManagerDelegate{ var friendData: [FriendData] = [] var requestData: [FriendData] = [] var userData: [UserParseData] = [] var partyData: PartyServiceManager! + var inviteHandle: ((Bool, MCSession!) -> Void)! + private var fromPeer: MCPeerID! @IBOutlet var img: UIImageView! + @IBOutlet var inviteTxt: UITextView! @IBAction func declineInvite(sender: UIButton){ + self.inviteHandle(false, self.partyData.session) self.dismissViewControllerAnimated(true, completion: nil) } @IBAction func acceptInvite(sender: UIButton){ - + self.inviteHandle(true, self.partyData.session) + self.performSegueWithIdentifier("JoiningPartySegue", sender: self) } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. + var query = PFQuery(className: "_User") + query.whereKey("username", equalTo: self.fromPeer.displayName) + + dispatch_async(dispatch_get_main_queue(), {() -> Void in + query.getFirstObjectInBackgroundWithBlock({ + (object: PFObject?, error: NSError?) -> Void in + if(error == nil){ + self.inviteTxt.text = "You have been invited by " + (object?.objectForKey("username")! as? String)! + " to join a Party!" + + //download profile imge + var img = object!.objectForKey("profilePicture")! as? PFFile + + dispatch_async(dispatch_get_main_queue(), { + img!.getDataInBackgroundWithBlock({ + (imgData, error) -> Void in + + var downloadedImg = UIImage(data: imgData!) + self.img.image = downloadedImg + self.img.layer.cornerRadius = self.img.frame.size.width/2 + self.img.clipsToBounds = true + }) + }) + } + }) + }) + + } override func didReceiveMemoryWarning() { @@ -35,11 +68,13 @@ class InvitedToPartyViewController: UIViewController { // Dispose of any resources that can be recreated. } - func setData(prty:PartyServiceManager, user: [UserParseData], friends: [FriendData], request: [FriendData]){ + func setData(prty:PartyServiceManager, user: [UserParseData], friends: [FriendData], request: [FriendData], invHand: ((Bool, MCSession!) -> Void)!, fromPeer: MCPeerID){ self.partyData = prty self.userData = user self.friendData = friends self.requestData = request + self.inviteHandle = invHand + self.fromPeer = fromPeer } // MARK: - Navigation @@ -50,17 +85,48 @@ class InvitedToPartyViewController: UIViewController { let nav: UINavigationController = (segue.destinationViewController as? UINavigationController)! let vc: SettingsTableViewController = (nav.viewControllers[0] as? SettingsTableViewController)! - vc.setData(self.userData, prty: self.partyData) + vc.setData(self.userData, prty: self.partyData, frends: self.friendData, request: self.requestData) } if segue.identifier == "InvitedToPartyFriendsSegue" { let nav: UINavigationController = (segue.destinationViewController as? UINavigationController)! let vc: FriendsListViewController = (nav.viewControllers[0] as? FriendsListViewController)! - vc.setData(self.friendData, requst: self.requestData, party: self.partyData) + vc.setData(self.friendData, requst: self.requestData, party: self.partyData, user: self.userData) + } + + if segue.identifier == "JoiningPartySegue" { + let vc: JoiningPartyViewController = (segue.destinationViewController as? JoiningPartyViewController)! + + vc.setData(self.friendData, requst: self.requestData, party: self.partyData, user: self.userData) } } +} + +extension InvitedToPartyViewController: PartyServiceManagerDelegate { + + func foundPeer() { + + } + + func lostPeer() { + + } + + func invitationWasRecieved(peerID: MCPeerID, invitationHandler: ((Bool, MCSession!) -> Void)!) { + + } + + func connectedWithPeer(peerID: MCPeerID) { + println("mark 0") + } + + func didRecieveInstruction(dictionary: Dictionary){ + + } + + } \ No newline at end of file diff --git a/GetHip/JoiningPartyViewController.swift b/GetHip/JoiningPartyViewController.swift new file mode 100644 index 0000000..8f34643 --- /dev/null +++ b/GetHip/JoiningPartyViewController.swift @@ -0,0 +1,73 @@ +// +// JoiningPartyViewController.swift +// GetHip +// +// Created by Okechi on 3/2/16. +// Copyright (c) 2016 Kroleo. All rights reserved. +// + +import UIKit +import MultipeerConnectivity + +class JoiningPartyViewController: UIViewController ,PartyServiceManagerDelegate{ + var friends = [] + var request = [] + var user: [UserParseData]! + var party: PartyServiceManager! + + override func viewDidLoad() { + super.viewDidLoad() + + // Do any additional setup after loading the view. + self.party.delegate = self + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + func setData(frnds:[FriendData], requst: [FriendData], party: PartyServiceManager, user: [UserParseData]){ + self.friends = frnds + self.request = requst + self.party = party + self.user = user + } + + /* + // MARK: - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { + // Get the new view controller using segue.destinationViewController. + // Pass the selected object to the new view controller. + } + */ + +} + +extension JoiningPartyViewController: PartyServiceManagerDelegate { + + func foundPeer() { + + } + + func lostPeer() { + + } + + func invitationWasRecieved(peerID: MCPeerID, invitationHandler: ((Bool, MCSession!) -> Void)!) { + + } + + func connectedWithPeer(peerID: MCPeerID) { + println("mark 2") + var dictionary: [String: String] = ["sender": self.party.myPeerID.displayName, "instruction": "joined_party"] + self.party.sendInstruction(dictionary, toPeer: peerID) + } + + func didRecieveInstruction(dictionary: Dictionary){ + + } + +} diff --git a/GetHip/LoadingPartyViewController.swift b/GetHip/LoadingPartyViewController.swift index 448314f..42c8ea7 100644 --- a/GetHip/LoadingPartyViewController.swift +++ b/GetHip/LoadingPartyViewController.swift @@ -8,8 +8,9 @@ import UIKit import MediaPlayer +import MultipeerConnectivity -class LoadingPartyViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate{ +class LoadingPartyViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, PartyServiceManagerDelegate{ //persistant data var party: PartyServiceManager! var usr: [UserParseData] = [] @@ -22,7 +23,7 @@ class LoadingPartyViewController: UIViewController, UICollectionViewDataSource, @IBOutlet var songLabel: UILabel! @IBOutlet var timerLabel: UILabel! var timer = NSTimer() - var counter = 30 + var counter = 60 @IBAction func cancelInvites(sender: UIButton){ self.dismissViewControllerAnimated(true, completion: nil) @@ -47,6 +48,7 @@ class LoadingPartyViewController: UIViewController, UICollectionViewDataSource, self.songLabel.text = (self.party.currentSong.valueForProperty(MPMediaItemPropertyTitle) as? String!)! + " by " + (self.party.currentSong.valueForProperty(MPMediaItemPropertyArtist) as? String!)! //sets up timer label and starts countdown to next screen + //NSNotificationCenter.defaultCenter().addObserver(self, selector: "updateThumbnail:", name: "peerConnected", object: nil) self.timerLabel.text = String(counter) self.timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("updateCounter"), userInfo: nil, repeats: true) } @@ -56,9 +58,13 @@ class LoadingPartyViewController: UIViewController, UICollectionViewDataSource, // Dispose of any resources that can be recreated. } + func updateThumbnil(notification: NSNotification){ + + } + func updateCounter(){ self.timerLabel.text = String(counter--) - if(self.counter == -2){ + if(self.counter == -1){ self.timer.invalidate() self.performSegueWithIdentifier("CurrentlyPlayingSegue", sender: nil) } @@ -112,3 +118,51 @@ class LoadingPartyViewController: UIViewController, UICollectionViewDataSource, } + +extension LoadingPartyViewController: PartyServiceManagerDelegate { + + func foundPeer() { + + } + + func lostPeer() { + + } + + func invitationWasRecieved(peerID: MCPeerID, invitationHandler: ((Bool, MCSession!) -> Void)!) { + + } + + func connectedWithPeer(peerID: MCPeerID) { + println(self.party.myPeerID.displayName + " connected to " + peerID.displayName) + var i = 0 + for(index, aFriend) in enumerate(self.party.invitedFriends) { + if aFriend.displayName == peerID.displayName { + i = index + break + } + } + + let cell: InvitedCollectionViewCell = self.invitedFriends.dequeueReusableCellWithReuseIdentifier("InvitedCollectionCell", forIndexPath: NSIndexPath(index: i)) as! InvitedCollectionViewCell + + cell.alpha = 1.0 + + + } + + func didRecieveInstruction(dictionary: Dictionary){ + //extract data from dictionary + println("mark 3") + let data = dictionary["data"] as? NSData + let fromPeer = dictionary["fromPeer"] as! MCPeerID + + //convert data to dictionary object with instruction + let dataDictionary = NSKeyedUnarchiver.unarchiveObjectWithData(data!) as! Dictionary + + //check if this is an instruction being sent + if let instruction = dataDictionary["instruction"] { + println(instruction) + } + } + +} \ No newline at end of file diff --git a/GetHip/LoginController.swift b/GetHip/LoginController.swift index 003538a..d7e9027 100644 --- a/GetHip/LoginController.swift +++ b/GetHip/LoginController.swift @@ -47,14 +47,23 @@ class LoginController: UIViewController, PFLogInViewControllerDelegate, UITextFi PFUser.logInWithUsernameInBackground(userEmailField.text!, password: password.text!, block: { (user, error) -> Void in - if(user != nil){ - self.performSegueWithIdentifier("LoginToHomeSegue", sender: self) + if(error == nil){ + if(user != nil){ + self.performSegueWithIdentifier("LoginToHomeSegue", sender: self) + }else{ + + var alert = UIAlertController(title: "Invalid Login", message: "Your username/email or password is incorrect!", preferredStyle: .Alert) + alert.addAction(UIAlertAction(title: "OK", style: .Default, handler:{(action: UIAlertAction!) in alert.dismissViewControllerAnimated(true, completion: nil)})) + + self.presentViewController(alert, animated: true, completion: nil) + } }else{ - var alert = UIAlertController(title: "Invalid Login", message: "Your username/email or password is incorrect!", preferredStyle: .Alert) + let alert = UIAlertController(title: "Network Error", message: error?.description, preferredStyle: .Alert) alert.addAction(UIAlertAction(title: "OK", style: .Default, handler:{(action: UIAlertAction!) in alert.dismissViewControllerAnimated(true, completion: nil)})) self.presentViewController(alert, animated: true, completion: nil) } + }) } diff --git a/GetHip/Main.storyboard b/GetHip/Main.storyboard index 0e1a7a8..8d19132 100644 --- a/GetHip/Main.storyboard +++ b/GetHip/Main.storyboard @@ -1,6 +1,7 @@ + @@ -191,10 +192,10 @@ - + - + @@ -239,12 +240,6 @@ - - - - - - + + + + + + + @@ -623,9 +625,6 @@ - - - + + @@ -1646,9 +1647,9 @@ - - - + + + diff --git a/GetHip/PartyServiceManager.swift b/GetHip/PartyServiceManager.swift index 75b7476..3dc809c 100644 --- a/GetHip/PartyServiceManager.swift +++ b/GetHip/PartyServiceManager.swift @@ -16,10 +16,12 @@ protocol PartyServiceManagerDelegate { func lostPeer() - func invitationWasRecieved(fromPeer: String) + func invitationWasRecieved(peerID: MCPeerID, invitationHandler: ((Bool, MCSession!) -> Void)!) func connectedWithPeer(peerID: MCPeerID) + func didRecieveInstruction(dictionary: Dictionary) + } @@ -52,30 +54,13 @@ class PartyServiceManager: NSObject { var role: PeerType! = nil var currentHost: String! - var connectingPeersDictionary = NSMutableDictionary() + var connectedPeersDictionary = NSMutableDictionary() var disconnectedPeersDictionary = NSMutableDictionary() //party variables var currentSong: MPMediaItem! = nil - /*init(){ - - //self.serviceAdvertiser = MCNearbyServiceAdvertiser(peer: self.myPeerID, discoveryInfo: nil, serviceType: self.PartyServiceType) - //super.init() - //self.serviceAdvertiser.delegate = self - - }*/ - /*deinit { - //stop all session services - self.serviceAdvertiser.stopAdvertisingPeer() - self.serviceBrowser.stopBrowsingForPeers() - }*/ - - /*lazy var session: MCSession = { - let session = MCSession(peer: self.myPeerID, securityIdentity: nil, encryptionPreference: MCEncryptionPreference.Required) - - }()*/ //Peer Initializer func setPeerID(dispName: String){ @@ -99,6 +84,30 @@ class PartyServiceManager: NSObject { } } + func isPeerFound(peer: MCPeerID) -> Bool { + for i in 0.., toPeer: MCPeerID) -> Bool { + + let dataToSend = NSKeyedArchiver.archivedDataWithRootObject(dictionary) + let peersArray = NSArray(object: toPeer) + var error: NSError? + + if !(self.session.sendData(dataToSend, toPeers: peersArray as [AnyObject], withMode: MCSessionSendDataMode.Reliable, error: &error)){ + println(error?.localizedDescription) + return false + } + + return true + } + //Listening methods func setAdvertiser(){ self.serviceAdvertiser = MCNearbyServiceAdvertiser(peer: self.myPeerID, discoveryInfo: nil, serviceType: self.PartyServiceType) @@ -208,28 +217,36 @@ extension PartyServiceManager: MCNearbyServiceBrowserDelegate{ func browser(browser: MCNearbyServiceBrowser!, foundPeer peerID: MCPeerID!, withDiscoveryInfo info: [NSObject : AnyObject]!) { - if(peerID.displayName != self.myPeerID.displayName) { - NSLog("%@", "foundPeer: \(peerID)") - self.foundPeers.append(peerID) - self.delegate?.foundPeer() - //self.serviceBrowser.invitePeer(peerID, toSession: self.session, withContext: nil, timeout: NSTimeInterval(10.00)) + if(!isPeerFound(peerID)){ + if(peerID.displayName != self.myPeerID.displayName) { + NSLog("%@", "foundPeer: \(peerID)") + self.foundPeers.append(peerID) + self.delegate?.foundPeer() + //self.serviceBrowser.invitePeer(peerID, toSession: self.session, withContext: nil, timeout: NSTimeInterval(60.00)) + + } + } - //implement way of picking which friends from friend list are invited + } func browser(browser: MCNearbyServiceBrowser!, lostPeer peerID: MCPeerID!) { NSLog("%@", "lostPeer: \(peerID)") - for(index, aPeer) in enumerate(foundPeers) { - if aPeer == peerID{ - foundPeers.removeAtIndex(index) - break + if(isPeerFound(peerID)){ + for(index, aPeer) in enumerate(foundPeers) { + if aPeer == peerID{ + foundPeers.removeAtIndex(index) + break + } } + + delegate?.lostPeer() } - delegate?.lostPeer() + } } @@ -242,7 +259,7 @@ extension PartyServiceManager: MCNearbyServiceAdvertiserDelegate{ func advertiser(advertiser: MCNearbyServiceAdvertiser!, didReceiveInvitationFromPeer peerID: MCPeerID!, withContext context: NSData!, invitationHandler: ((Bool, MCSession!) -> Void)!) { NSLog("%@", "invitingPeer: \(peerID)") self.setRole(PeerType(rawValue: 3)!) - invitationHandler(true, self.session) + delegate?.invitationWasRecieved(peerID, invitationHandler: invitationHandler) } } @@ -250,10 +267,20 @@ extension PartyServiceManager: MCSessionDelegate{ func session(session: MCSession!, peer peerID: MCPeerID!, didChangeState state: MCSessionState) { NSLog("%@", "peer \(peerID) didChangeState: \(state.stringValue())") + if(state == MCSessionState.Connected){ + println(self.myPeerID.displayName + " connected to " + peerID.displayName) + println("mark 1") + self.delegate?.connectedWithPeer(peerID) + + } } func session(session: MCSession!, didReceiveData data: NSData!, fromPeer peerID: MCPeerID!) { NSLog("%@", "didRecieveData: \(data)") + + let dictionary: [String: AnyObject] = ["data": data, "fromPeer": peerID] + self.delegate?.didRecieveInstruction(dictionary) + } func session(session: MCSession!, didReceiveStream stream: NSInputStream!, withName streamName: String!, fromPeer peerID: MCPeerID!) { diff --git a/GetHip/SettingsTableViewController.swift b/GetHip/SettingsTableViewController.swift index 7f82ab0..08f1985 100644 --- a/GetHip/SettingsTableViewController.swift +++ b/GetHip/SettingsTableViewController.swift @@ -7,11 +7,14 @@ // import UIKit +import MultipeerConnectivity -class SettingsTableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { +class SettingsTableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, PartyServiceManagerDelegate { // var manager = UserParseDataSource() var user = [] var party: PartyServiceManager! + var friendData: [FriendData] = [] + var requestData: [FriendData] = [] @IBOutlet weak var logOutBtn: UIButton! @IBOutlet weak var table: UITableView! @@ -38,9 +41,11 @@ class SettingsTableViewController: UIViewController, UITableViewDataSource, UITa } - func setData(usr:[UserParseData], prty: PartyServiceManager){ + func setData(usr:[UserParseData], prty: PartyServiceManager, frends: [FriendData], request: [FriendData]){ self.user = usr self.party = prty + self.friendData = frends + self.requestData = request } override func viewDidLoad() { @@ -54,6 +59,7 @@ class SettingsTableViewController: UIViewController, UITableViewDataSource, UITa self.table.delegate = self self.navigationController?.navigationBarHidden = false self.table.tableFooterView = UIView(frame: CGRectZero) + self.party.delegate = self //NSNotificationCenter.defaultCenter().addObserver(self, selector: "refreshTable:", name: "refreshSettingsView", object: nil) self.table.reloadData() @@ -288,3 +294,30 @@ class SettingsTableViewController: UIViewController, UITableViewDataSource, UITa */ } + +extension SettingsTableViewController: PartyServiceManagerDelegate { + func foundPeer() { + + } + + func lostPeer() { + + } + + func invitationWasRecieved(peerID: MCPeerID, invitationHandler: ((Bool, MCSession!) -> Void)!) { + var storyboard = UIStoryboard(name: "Main", bundle: nil) + var vc: InvitedToPartyViewController = storyboard.instantiateViewControllerWithIdentifier("InvitedToPartyVC") as! InvitedToPartyViewController! + vc.setData(self.party, user: self.user as! [UserParseData], friends: self.friendData, request: self.requestData, invHand: invitationHandler, fromPeer: peerID) + self.presentViewController(vc, animated: true, completion: nil) + } + + func connectedWithPeer(peerID: MCPeerID) { + + } + + func didRecieveInstruction(dictionary: Dictionary){ + + } + + +} diff --git a/GetHip/SongSelectionViewController.swift b/GetHip/SongSelectionViewController.swift index 6cfea02..9190af5 100644 --- a/GetHip/SongSelectionViewController.swift +++ b/GetHip/SongSelectionViewController.swift @@ -276,6 +276,17 @@ class SongSelectionViewController: UIViewController, UITableViewDelegate, UITabl let vc: LoadingPartyViewController = (segue.destinationViewController as? LoadingPartyViewController)! vc.setData(self.party, user: self.usr, friends: self.frnds, request: self.requestData) + for i_peer in self.party.invitedFriends{ + for peer in self.party.foundPeers { + if (peer.displayName == i_peer.displayName){ + self.party.serviceBrowser.invitePeer(peer, toSession: self.party.session, withContext: nil, timeout: 1000.0) + + break + } + } + + + } } } diff --git a/GetHip/TestInviteFriendsController.swift b/GetHip/TestInviteFriendsController.swift index 1df1ba2..70e72c8 100644 --- a/GetHip/TestInviteFriendsController.swift +++ b/GetHip/TestInviteFriendsController.swift @@ -15,6 +15,7 @@ class TestInviteFriendsController: UIViewController, UITableViewDelegate, UITabl var requestData: [FriendData] = [] var isFriendSelected: [Bool] = [] var isInvitable: [Bool] = [] + var invitableCount = 0 var partyData: PartyServiceManager! = nil @IBOutlet weak var table: UITableView! @@ -29,6 +30,24 @@ class TestInviteFriendsController: UIViewController, UITableViewDelegate, UITabl @IBAction func sendInvites(sender: UIButton) { var numSelected = 0 + var data = NSData() + for(index, bool) in enumerate(self.isFriendSelected) { + if bool == true { + + //search for foundpeer in array + /*for peer in self.partyData.foundPeers { + if (peer.displayName == self.frnds[index].displayName){ + self.partyData.serviceBrowser.invitePeer(peer, toSession: self.partyData.session, withContext: data, timeout: 3600.0) + + break + } + + }*/ + } + + } + + self.partyData.serviceBrowser.stopBrowsingForPeers() for booli in self.isFriendSelected { if booli == true { @@ -64,24 +83,22 @@ class TestInviteFriendsController: UIViewController, UITableViewDelegate, UITabl self.table.dataSource = self self.table.delegate = self self.partyData.delegate = self - //start browsing for peers - self.partyData.setBrowser() - self.partyData.startBrowser() - self.partyData.initializeSession() self.navigationController?.navigationBarHidden = false - + /* for foundPeer in self.partyData.foundPeers { for friend in self.frnds { if foundPeer.displayName == friend.displayName { for(index, aFriend) in enumerate(self.frnds) { if aFriend.displayName == friend.displayName { self.isInvitable[index] = true + self.invitableCount++ break } } } } } + */ @@ -92,6 +109,12 @@ class TestInviteFriendsController: UIViewController, UITableViewDelegate, UITabl // self.navigationItem.rightBarButtonItem = self.editButtonItem() } + override func viewWillAppear(animated: Bool) { + //start browsing for peers + self.partyData.setBrowser() + self.partyData.startBrowser() + } + override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. @@ -108,12 +131,25 @@ class TestInviteFriendsController: UIViewController, UITableViewDelegate, UITabl func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // #warning Incomplete method implementation. // Return the number of rows in the section. - return self.frnds.count + + return self.invitableCount + //return self.frnds.count } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { - let friend = self.frnds[indexPath.row] + + //iterate through the currently found peers and display only friends who are available + var friend: FriendData! + + for i in 0.. Void)!) { } func connectedWithPeer(peerID: MCPeerID) { } + + func didRecieveInstruction(dictionary: Dictionary){ + + } + + }