From 9b79a326cee407fb7d3b041d9801b0452a5e9e6f Mon Sep 17 00:00:00 2001 From: Maria Ines Casadei Date: Thu, 11 Dec 2014 12:54:28 -0300 Subject: [PATCH 01/24] Model with Core Data --- EyeTypeChat.xcodeproj/project.pbxproj | 25 +++++++++++++++ EyeTypeChat/Account.swift | 18 +++++++++++ .../EyeTypeChat.xcdatamodel/contents | 31 +++++++++++++++++-- EyeTypeChat/model/Account.swift | 18 +++++++++++ EyeTypeChat/model/Contact.swift | 18 +++++++++++ EyeTypeChat/model/Conversation.swift | 19 ++++++++++++ EyeTypeChat/model/Message.swift | 19 ++++++++++++ TelegraphKit/TelegraphKit-Bridging-Header.h | 4 +++ 8 files changed, 150 insertions(+), 2 deletions(-) create mode 100644 EyeTypeChat/Account.swift create mode 100644 EyeTypeChat/model/Account.swift create mode 100644 EyeTypeChat/model/Contact.swift create mode 100644 EyeTypeChat/model/Conversation.swift create mode 100644 EyeTypeChat/model/Message.swift create mode 100644 TelegraphKit/TelegraphKit-Bridging-Header.h diff --git a/EyeTypeChat.xcodeproj/project.pbxproj b/EyeTypeChat.xcodeproj/project.pbxproj index 919804e..28ccc49 100644 --- a/EyeTypeChat.xcodeproj/project.pbxproj +++ b/EyeTypeChat.xcodeproj/project.pbxproj @@ -7,6 +7,10 @@ objects = { /* Begin PBXBuildFile section */ + 2395D1561A39F53900F784EC /* Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2395D1551A39F53900F784EC /* Account.swift */; }; + 23BA3E271A38EC2000C5AD4B /* Contact.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23BA3E261A38EC2000C5AD4B /* Contact.swift */; }; + 23BA3E291A38EC2100C5AD4B /* Message.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23BA3E281A38EC2100C5AD4B /* Message.swift */; }; + 23BA3E2B1A38EC2100C5AD4B /* Conversation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23BA3E2A1A38EC2100C5AD4B /* Conversation.swift */; }; 5E9B341BA996967017148759 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A49492BC4CA902EDA58BC35 /* libPods.a */; }; 8823D7AE1A30E3D200271406 /* ConversationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8823D7AD1A30E3D200271406 /* ConversationViewController.swift */; }; 8823D7B11A30E8B500271406 /* UIViewController+EyeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8823D7B01A30E8B500271406 /* UIViewController+EyeType.swift */; }; @@ -61,6 +65,10 @@ 8823D7AD1A30E3D200271406 /* ConversationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConversationViewController.swift; sourceTree = ""; }; 8823D7B01A30E8B500271406 /* UIViewController+EyeType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+EyeType.swift"; sourceTree = ""; }; 8823D7B21A30F65E00271406 /* BaseMenuViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseMenuViewController.swift; sourceTree = ""; }; + 2395D1551A39F53900F784EC /* Account.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Account.swift; sourceTree = ""; }; + 23BA3E261A38EC2000C5AD4B /* Contact.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Contact.swift; path = model/Contact.swift; sourceTree = ""; }; + 23BA3E281A38EC2100C5AD4B /* Message.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Message.swift; path = model/Message.swift; sourceTree = ""; }; + 23BA3E2A1A38EC2100C5AD4B /* Conversation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Conversation.swift; path = model/Conversation.swift; sourceTree = ""; }; 883793181A278BDB00AA856D /* libstdc++.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libstdc++.dylib"; path = "usr/lib/libstdc++.dylib"; sourceTree = SDKROOT; }; 8856809E1A374B2D005F2BB0 /* fixedMenus.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = fixedMenus.plist; sourceTree = ""; }; 885680A11A374BB8005F2BB0 /* FixedMenuViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FixedMenuViewController.swift; sourceTree = ""; }; @@ -134,6 +142,17 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 23BA3E251A38EB1500C5AD4B /* model */ = { + isa = PBXGroup; + children = ( + 2395D1551A39F53900F784EC /* Account.swift */, + 23BA3E2A1A38EC2100C5AD4B /* Conversation.swift */, + 23BA3E281A38EC2100C5AD4B /* Message.swift */, + 23BA3E261A38EC2000C5AD4B /* Contact.swift */, + ); + name = model; + sourceTree = ""; + }; 887A2CB61A0BDB4400094E3C = { isa = PBXGroup; children = ( @@ -158,6 +177,7 @@ 887A2CC11A0BDB4500094E3C /* EyeTypeChat */ = { isa = PBXGroup; children = ( + 23BA3E251A38EB1500C5AD4B /* model */, 887A2CC41A0BDB4500094E3C /* AppDelegate.swift */, 887A2CC91A0BDB4500094E3C /* MainViewController.swift */, 88A759A01A2F7B070005B04C /* MainViewModel.swift */, @@ -410,9 +430,11 @@ buildActionMask = 2147483647; files = ( 8823D7AE1A30E3D200271406 /* ConversationViewController.swift in Sources */, + 2395D1561A39F53900F784EC /* Account.swift in Sources */, 887A2CCA1A0BDB4500094E3C /* MainViewController.swift in Sources */, 88A759B11A2F9FC10005B04C /* KeyboardViewController.swift in Sources */, 887A2CC51A0BDB4500094E3C /* AppDelegate.swift in Sources */, + 23BA3E2B1A38EC2100C5AD4B /* Conversation.swift in Sources */, 887A2CC81A0BDB4500094E3C /* EyeTypeChat.xcdatamodeld in Sources */, 88A759A11A2F7B070005B04C /* MainViewModel.swift in Sources */, 8823D7B11A30E8B500271406 /* UIViewController+EyeType.swift in Sources */, @@ -421,6 +443,9 @@ 88A759AC1A2F9D4D0005B04C /* EyeControllable.swift in Sources */, 885680A71A378E55005F2BB0 /* FixedMenuViewController+Commands.swift in Sources */, 8823D7B31A30F65E00271406 /* BaseMenuViewController.swift in Sources */, + 23BA3E291A38EC2100C5AD4B /* Message.swift in Sources */, + 88A759AC1A2F9D4D0005B04C /* EyeControllable.swift in Sources */, + 23BA3E271A38EC2000C5AD4B /* Contact.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/EyeTypeChat/Account.swift b/EyeTypeChat/Account.swift new file mode 100644 index 0000000..91ca97f --- /dev/null +++ b/EyeTypeChat/Account.swift @@ -0,0 +1,18 @@ +// +// ETAccount.swift +// EyeTypeChat +// +// Created by Maria Ines Casadei on 12/11/14. +// Copyright (c) 2014 SCV Soft. All rights reserved. +// + +import Foundation +import CoreData + +class Account: NSManagedObject { + + @NSManaged var userIdentifier: String + @NSManaged var contacts: NSSet + @NSManaged var conversations: NSSet + +} diff --git a/EyeTypeChat/EyeTypeChat.xcdatamodeld/EyeTypeChat.xcdatamodel/contents b/EyeTypeChat/EyeTypeChat.xcdatamodeld/EyeTypeChat.xcdatamodel/contents index 193f33c..0518533 100644 --- a/EyeTypeChat/EyeTypeChat.xcdatamodeld/EyeTypeChat.xcdatamodel/contents +++ b/EyeTypeChat/EyeTypeChat.xcdatamodeld/EyeTypeChat.xcdatamodel/contents @@ -1,4 +1,31 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/EyeTypeChat/model/Account.swift b/EyeTypeChat/model/Account.swift new file mode 100644 index 0000000..91ca97f --- /dev/null +++ b/EyeTypeChat/model/Account.swift @@ -0,0 +1,18 @@ +// +// ETAccount.swift +// EyeTypeChat +// +// Created by Maria Ines Casadei on 12/11/14. +// Copyright (c) 2014 SCV Soft. All rights reserved. +// + +import Foundation +import CoreData + +class Account: NSManagedObject { + + @NSManaged var userIdentifier: String + @NSManaged var contacts: NSSet + @NSManaged var conversations: NSSet + +} diff --git a/EyeTypeChat/model/Contact.swift b/EyeTypeChat/model/Contact.swift new file mode 100644 index 0000000..c2ed420 --- /dev/null +++ b/EyeTypeChat/model/Contact.swift @@ -0,0 +1,18 @@ +// +// Contact.swift +// EyeTypeChat +// +// Created by Maria Ines Casadei on 12/10/14. +// Copyright (c) 2014 SCV Soft. All rights reserved. +// + +import Foundation +import CoreData + +class Contact: NSManagedObject { + + @NSManaged var name: String + @NSManaged var phoneNumber: NSNumber + @NSManaged var account: Account + +} diff --git a/EyeTypeChat/model/Conversation.swift b/EyeTypeChat/model/Conversation.swift new file mode 100644 index 0000000..0c64040 --- /dev/null +++ b/EyeTypeChat/model/Conversation.swift @@ -0,0 +1,19 @@ +// +// Conversation.swift +// EyeTypeChat +// +// Created by Maria Ines Casadei on 12/10/14. +// Copyright (c) 2014 SCV Soft. All rights reserved. +// + +import Foundation +import CoreData + +class Conversation: NSManagedObject { + + @NSManaged var title: String + @NSManaged var messages: NSSet + @NSManaged var betweenContacts: NSSet + @NSManaged var account: Account + +} diff --git a/EyeTypeChat/model/Message.swift b/EyeTypeChat/model/Message.swift new file mode 100644 index 0000000..fcbb58f --- /dev/null +++ b/EyeTypeChat/model/Message.swift @@ -0,0 +1,19 @@ +// +// Message.swift +// EyeTypeChat +// +// Created by Maria Ines Casadei on 12/10/14. +// Copyright (c) 2014 SCV Soft. All rights reserved. +// + +import Foundation +import CoreData + +class Message: NSManagedObject { + + @NSManaged var text: String + @NSManaged var sentDateTime: NSDate + @NSManaged var conversation: NSManagedObject + @NSManaged var fromContact: Contact + +} diff --git a/TelegraphKit/TelegraphKit-Bridging-Header.h b/TelegraphKit/TelegraphKit-Bridging-Header.h new file mode 100644 index 0000000..1b2cb5d --- /dev/null +++ b/TelegraphKit/TelegraphKit-Bridging-Header.h @@ -0,0 +1,4 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + From bbb025b8f18524a7a30deb7924c775123e98b1e6 Mon Sep 17 00:00:00 2001 From: Maria Ines Casadei Date: Mon, 15 Dec 2014 11:08:47 -0300 Subject: [PATCH 02/24] Added telegram account and some contacts associated --- EyeTypeChat.xcodeproj/project.pbxproj | 30 ++++++--- EyeTypeChat/Account.swift | 18 ------ .../EyeTypeChat.xcdatamodel/contents | 16 ++--- EyeTypeChat/MainViewController.swift | 63 +++++++++++++++++++ EyeTypeChat/model/Account.swift | 4 +- EyeTypeChat/model/Contact.swift | 6 +- EyeTypeChat/model/Conversation.swift | 8 +-- EyeTypeChat/model/Message.swift | 10 +-- EyeTypeChat/model/TelegramAccount.swift | 15 +++++ 9 files changed, 121 insertions(+), 49 deletions(-) delete mode 100644 EyeTypeChat/Account.swift create mode 100644 EyeTypeChat/model/TelegramAccount.swift diff --git a/EyeTypeChat.xcodeproj/project.pbxproj b/EyeTypeChat.xcodeproj/project.pbxproj index 28ccc49..420a2ef 100644 --- a/EyeTypeChat.xcodeproj/project.pbxproj +++ b/EyeTypeChat.xcodeproj/project.pbxproj @@ -7,10 +7,11 @@ objects = { /* Begin PBXBuildFile section */ - 2395D1561A39F53900F784EC /* Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2395D1551A39F53900F784EC /* Account.swift */; }; - 23BA3E271A38EC2000C5AD4B /* Contact.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23BA3E261A38EC2000C5AD4B /* Contact.swift */; }; - 23BA3E291A38EC2100C5AD4B /* Message.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23BA3E281A38EC2100C5AD4B /* Message.swift */; }; - 23BA3E2B1A38EC2100C5AD4B /* Conversation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23BA3E2A1A38EC2100C5AD4B /* Conversation.swift */; }; + 232CE5321A3A3D6100C94EE8 /* Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = 232CE5311A3A3D6100C94EE8 /* Account.swift */; }; + 232CE5341A3A3D9300C94EE8 /* TelegramAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 232CE5331A3A3D9300C94EE8 /* TelegramAccount.swift */; }; + 232CE5361A3A3DCF00C94EE8 /* Conversation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 232CE5351A3A3DCF00C94EE8 /* Conversation.swift */; }; + 232CE5381A3A3E4D00C94EE8 /* Message.swift in Sources */ = {isa = PBXBuildFile; fileRef = 232CE5371A3A3E4D00C94EE8 /* Message.swift */; }; + 232CE53A1A3A3E9C00C94EE8 /* Contact.swift in Sources */ = {isa = PBXBuildFile; fileRef = 232CE5391A3A3E9C00C94EE8 /* Contact.swift */; }; 5E9B341BA996967017148759 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A49492BC4CA902EDA58BC35 /* libPods.a */; }; 8823D7AE1A30E3D200271406 /* ConversationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8823D7AD1A30E3D200271406 /* ConversationViewController.swift */; }; 8823D7B11A30E8B500271406 /* UIViewController+EyeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8823D7B01A30E8B500271406 /* UIViewController+EyeType.swift */; }; @@ -69,6 +70,11 @@ 23BA3E261A38EC2000C5AD4B /* Contact.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Contact.swift; path = model/Contact.swift; sourceTree = ""; }; 23BA3E281A38EC2100C5AD4B /* Message.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Message.swift; path = model/Message.swift; sourceTree = ""; }; 23BA3E2A1A38EC2100C5AD4B /* Conversation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Conversation.swift; path = model/Conversation.swift; sourceTree = ""; }; + 232CE5311A3A3D6100C94EE8 /* Account.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Account.swift; path = model/Account.swift; sourceTree = ""; }; + 232CE5331A3A3D9300C94EE8 /* TelegramAccount.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TelegramAccount.swift; path = model/TelegramAccount.swift; sourceTree = ""; }; + 232CE5351A3A3DCF00C94EE8 /* Conversation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Conversation.swift; path = model/Conversation.swift; sourceTree = ""; }; + 232CE5371A3A3E4D00C94EE8 /* Message.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Message.swift; path = model/Message.swift; sourceTree = ""; }; + 232CE5391A3A3E9C00C94EE8 /* Contact.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Contact.swift; path = model/Contact.swift; sourceTree = ""; }; 883793181A278BDB00AA856D /* libstdc++.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libstdc++.dylib"; path = "usr/lib/libstdc++.dylib"; sourceTree = SDKROOT; }; 8856809E1A374B2D005F2BB0 /* fixedMenus.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = fixedMenus.plist; sourceTree = ""; }; 885680A11A374BB8005F2BB0 /* FixedMenuViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FixedMenuViewController.swift; sourceTree = ""; }; @@ -145,10 +151,11 @@ 23BA3E251A38EB1500C5AD4B /* model */ = { isa = PBXGroup; children = ( - 2395D1551A39F53900F784EC /* Account.swift */, - 23BA3E2A1A38EC2100C5AD4B /* Conversation.swift */, - 23BA3E281A38EC2100C5AD4B /* Message.swift */, - 23BA3E261A38EC2000C5AD4B /* Contact.swift */, + 232CE5391A3A3E9C00C94EE8 /* Contact.swift */, + 232CE5371A3A3E4D00C94EE8 /* Message.swift */, + 232CE5351A3A3DCF00C94EE8 /* Conversation.swift */, + 232CE5331A3A3D9300C94EE8 /* TelegramAccount.swift */, + 232CE5311A3A3D6100C94EE8 /* Account.swift */, ); name = model; sourceTree = ""; @@ -431,10 +438,12 @@ files = ( 8823D7AE1A30E3D200271406 /* ConversationViewController.swift in Sources */, 2395D1561A39F53900F784EC /* Account.swift in Sources */, + 232CE5361A3A3DCF00C94EE8 /* Conversation.swift in Sources */, 887A2CCA1A0BDB4500094E3C /* MainViewController.swift in Sources */, + 232CE53A1A3A3E9C00C94EE8 /* Contact.swift in Sources */, + 232CE5341A3A3D9300C94EE8 /* TelegramAccount.swift in Sources */, 88A759B11A2F9FC10005B04C /* KeyboardViewController.swift in Sources */, 887A2CC51A0BDB4500094E3C /* AppDelegate.swift in Sources */, - 23BA3E2B1A38EC2100C5AD4B /* Conversation.swift in Sources */, 887A2CC81A0BDB4500094E3C /* EyeTypeChat.xcdatamodeld in Sources */, 88A759A11A2F7B070005B04C /* MainViewModel.swift in Sources */, 8823D7B11A30E8B500271406 /* UIViewController+EyeType.swift in Sources */, @@ -444,8 +453,9 @@ 885680A71A378E55005F2BB0 /* FixedMenuViewController+Commands.swift in Sources */, 8823D7B31A30F65E00271406 /* BaseMenuViewController.swift in Sources */, 23BA3E291A38EC2100C5AD4B /* Message.swift in Sources */, + 232CE5381A3A3E4D00C94EE8 /* Message.swift in Sources */, 88A759AC1A2F9D4D0005B04C /* EyeControllable.swift in Sources */, - 23BA3E271A38EC2000C5AD4B /* Contact.swift in Sources */, + 232CE5321A3A3D6100C94EE8 /* Account.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/EyeTypeChat/Account.swift b/EyeTypeChat/Account.swift deleted file mode 100644 index 91ca97f..0000000 --- a/EyeTypeChat/Account.swift +++ /dev/null @@ -1,18 +0,0 @@ -// -// ETAccount.swift -// EyeTypeChat -// -// Created by Maria Ines Casadei on 12/11/14. -// Copyright (c) 2014 SCV Soft. All rights reserved. -// - -import Foundation -import CoreData - -class Account: NSManagedObject { - - @NSManaged var userIdentifier: String - @NSManaged var contacts: NSSet - @NSManaged var conversations: NSSet - -} diff --git a/EyeTypeChat/EyeTypeChat.xcdatamodeld/EyeTypeChat.xcdatamodel/contents b/EyeTypeChat/EyeTypeChat.xcdatamodeld/EyeTypeChat.xcdatamodel/contents index 0518533..017bc24 100644 --- a/EyeTypeChat/EyeTypeChat.xcdatamodeld/EyeTypeChat.xcdatamodel/contents +++ b/EyeTypeChat/EyeTypeChat.xcdatamodeld/EyeTypeChat.xcdatamodel/contents @@ -1,31 +1,33 @@ - + - + - + - + + - - + + + - + \ No newline at end of file diff --git a/EyeTypeChat/MainViewController.swift b/EyeTypeChat/MainViewController.swift index 9c3093e..da642c1 100644 --- a/EyeTypeChat/MainViewController.swift +++ b/EyeTypeChat/MainViewController.swift @@ -7,6 +7,7 @@ // import UIKit +import CoreData class MainViewController: ETVideoSourceViewController { @@ -21,11 +22,26 @@ class MainViewController: ETVideoSourceViewController { } } + lazy var managedObjectContext : NSManagedObjectContext? = { + let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate + if let managedObjectContext = appDelegate.managedObjectContext { + return managedObjectContext + } + else { + return nil + } + }() + required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder) self.model = MainViewModel() } + override func viewDidLoad() { + super.viewDidLoad() + createMockedData() + } + override func viewDidAppear(animated: Bool) { super.viewDidAppear(animated) startDetect() @@ -50,6 +66,53 @@ class MainViewController: ETVideoSourceViewController { self.videoSource.stopRunning() } + func createMockedData(){ + + // create Telegram account + var telegramAccount = NSEntityDescription.insertNewObjectForEntityForName("TelegramAccount", inManagedObjectContext: self.managedObjectContext!) as TelegramAccount + + // create contact list for the account + var firstContact = NSEntityDescription.insertNewObjectForEntityForName("Contact", inManagedObjectContext: self.managedObjectContext!) as Contact + firstContact.name = "Mary" + firstContact.phoneNumber = 263823827 + firstContact.account = telegramAccount + + var secondContact = NSEntityDescription.insertNewObjectForEntityForName("Contact", inManagedObjectContext: self.managedObjectContext!) as Contact + secondContact.name = "Anna" + secondContact.phoneNumber = 1161690000 + secondContact.account = telegramAccount + + var thirdContact = NSEntityDescription.insertNewObjectForEntityForName("Contact", inManagedObjectContext: self.managedObjectContext!) as Contact + thirdContact.name = "John" + thirdContact.phoneNumber = 328378738 + thirdContact.account = telegramAccount + + var contactSet = NSMutableSet() + contactSet.addObject(firstContact) + contactSet.addObject(secondContact) + contactSet.addObject(thirdContact) + + //asociate contact list with the Telegram account + telegramAccount.contacts = contactSet + + println(managedObjectContext!) + + printMockedData() + + } + + func printMockedData(){ + let fetchRequest = NSFetchRequest(entityName: "TelegramAccount") + if let fetchResults = managedObjectContext!.executeFetchRequest(fetchRequest, error: nil) as? [TelegramAccount] { + let contacts = fetchResults[0].contacts + for contact in contacts! { + if let eachContact = contact as? Contact { + println("Contact Name: \(eachContact.name). Phone Number: \(eachContact.phoneNumber)") + } + } + } + } + @IBAction func eyeDidAccept() { if let controllable = subNavigationController.topViewController as? EyeControllable { controllable.eyeDidAccept() diff --git a/EyeTypeChat/model/Account.swift b/EyeTypeChat/model/Account.swift index 91ca97f..266f7c2 100644 --- a/EyeTypeChat/model/Account.swift +++ b/EyeTypeChat/model/Account.swift @@ -1,5 +1,5 @@ // -// ETAccount.swift +// EyeTypeChat.swift // EyeTypeChat // // Created by Maria Ines Casadei on 12/11/14. @@ -12,7 +12,7 @@ import CoreData class Account: NSManagedObject { @NSManaged var userIdentifier: String - @NSManaged var contacts: NSSet + @NSManaged var contacts: NSSet? @NSManaged var conversations: NSSet } diff --git a/EyeTypeChat/model/Contact.swift b/EyeTypeChat/model/Contact.swift index c2ed420..a479e33 100644 --- a/EyeTypeChat/model/Contact.swift +++ b/EyeTypeChat/model/Contact.swift @@ -1,8 +1,8 @@ // -// Contact.swift +// EyeTypeChat.swift // EyeTypeChat // -// Created by Maria Ines Casadei on 12/10/14. +// Created by Maria Ines Casadei on 12/11/14. // Copyright (c) 2014 SCV Soft. All rights reserved. // @@ -13,6 +13,6 @@ class Contact: NSManagedObject { @NSManaged var name: String @NSManaged var phoneNumber: NSNumber - @NSManaged var account: Account + @NSManaged var account: EyeTypeChat.Account } diff --git a/EyeTypeChat/model/Conversation.swift b/EyeTypeChat/model/Conversation.swift index 0c64040..6e391e2 100644 --- a/EyeTypeChat/model/Conversation.swift +++ b/EyeTypeChat/model/Conversation.swift @@ -1,8 +1,8 @@ // -// Conversation.swift +// EyeTypeChat.swift // EyeTypeChat // -// Created by Maria Ines Casadei on 12/10/14. +// Created by Maria Ines Casadei on 12/11/14. // Copyright (c) 2014 SCV Soft. All rights reserved. // @@ -12,8 +12,8 @@ import CoreData class Conversation: NSManagedObject { @NSManaged var title: String - @NSManaged var messages: NSSet + @NSManaged var account: EyeTypeChat.Account @NSManaged var betweenContacts: NSSet - @NSManaged var account: Account + @NSManaged var messages: NSSet } diff --git a/EyeTypeChat/model/Message.swift b/EyeTypeChat/model/Message.swift index fcbb58f..312279e 100644 --- a/EyeTypeChat/model/Message.swift +++ b/EyeTypeChat/model/Message.swift @@ -1,8 +1,8 @@ // -// Message.swift +// EyeTypeChat.swift // EyeTypeChat // -// Created by Maria Ines Casadei on 12/10/14. +// Created by Maria Ines Casadei on 12/11/14. // Copyright (c) 2014 SCV Soft. All rights reserved. // @@ -11,9 +11,9 @@ import CoreData class Message: NSManagedObject { - @NSManaged var text: String @NSManaged var sentDateTime: NSDate - @NSManaged var conversation: NSManagedObject - @NSManaged var fromContact: Contact + @NSManaged var text: String + @NSManaged var conversation: EyeTypeChat.Conversation + @NSManaged var fromContact: EyeTypeChat.Contact } diff --git a/EyeTypeChat/model/TelegramAccount.swift b/EyeTypeChat/model/TelegramAccount.swift new file mode 100644 index 0000000..177fbb1 --- /dev/null +++ b/EyeTypeChat/model/TelegramAccount.swift @@ -0,0 +1,15 @@ +// +// EyeTypeChat.swift +// EyeTypeChat +// +// Created by Maria Ines Casadei on 12/11/14. +// Copyright (c) 2014 SCV Soft. All rights reserved. +// + +import Foundation +import CoreData + +class TelegramAccount: EyeTypeChat.Account { + + +} From 43d8e46905cc955b06a2f80e5c7f6159a7b348b1 Mon Sep 17 00:00:00 2001 From: Maria Ines Casadei Date: Mon, 15 Dec 2014 17:59:47 -0300 Subject: [PATCH 03/24] Added class methods to create account and contacts --- EyeTypeChat/MainViewController.swift | 40 ++++++++++++------------- EyeTypeChat/model/Account.swift | 2 +- EyeTypeChat/model/Contact.swift | 11 ++++++- EyeTypeChat/model/Conversation.swift | 15 ++++++++-- EyeTypeChat/model/Message.swift | 15 ++++++++-- EyeTypeChat/model/TelegramAccount.swift | 11 ++++++- 6 files changed, 66 insertions(+), 28 deletions(-) diff --git a/EyeTypeChat/MainViewController.swift b/EyeTypeChat/MainViewController.swift index da642c1..dc6fe3f 100644 --- a/EyeTypeChat/MainViewController.swift +++ b/EyeTypeChat/MainViewController.swift @@ -69,34 +69,19 @@ class MainViewController: ETVideoSourceViewController { func createMockedData(){ // create Telegram account - var telegramAccount = NSEntityDescription.insertNewObjectForEntityForName("TelegramAccount", inManagedObjectContext: self.managedObjectContext!) as TelegramAccount - - // create contact list for the account - var firstContact = NSEntityDescription.insertNewObjectForEntityForName("Contact", inManagedObjectContext: self.managedObjectContext!) as Contact - firstContact.name = "Mary" - firstContact.phoneNumber = 263823827 - firstContact.account = telegramAccount - - var secondContact = NSEntityDescription.insertNewObjectForEntityForName("Contact", inManagedObjectContext: self.managedObjectContext!) as Contact - secondContact.name = "Anna" - secondContact.phoneNumber = 1161690000 - secondContact.account = telegramAccount - - var thirdContact = NSEntityDescription.insertNewObjectForEntityForName("Contact", inManagedObjectContext: self.managedObjectContext!) as Contact - thirdContact.name = "John" - thirdContact.phoneNumber = 328378738 - thirdContact.account = telegramAccount + var telegramAccount = TelegramAccount.createTelegramAccount("XYZ123", entity: "TelegramAccount", context: self.managedObjectContext!) + // create contact list + var firstContact = Contact.createContact("Mary", phoneNumber: 263823827, account: telegramAccount, entity: "Contact", context: self.managedObjectContext!) + var secondContact = Contact.createContact("Anna", phoneNumber: 1161690000, account: telegramAccount, entity: "Contact", context: self.managedObjectContext!) + var thirdContact = Contact.createContact("John", phoneNumber: 328378738, account: telegramAccount, entity: "Contact", context: self.managedObjectContext!) var contactSet = NSMutableSet() - contactSet.addObject(firstContact) - contactSet.addObject(secondContact) - contactSet.addObject(thirdContact) + contactSet.addObjectsFromArray([firstContact, secondContact, thirdContact]) //asociate contact list with the Telegram account telegramAccount.contacts = contactSet println(managedObjectContext!) - printMockedData() } @@ -110,7 +95,20 @@ class MainViewController: ETVideoSourceViewController { println("Contact Name: \(eachContact.name). Phone Number: \(eachContact.phoneNumber)") } } + +// let conversations = fetchResults[0].conversations +// for chat in conversations! { +// if let eachChat = chat as? Conversation { +// println("Chat: \(eachChat.title)") +// for text in eachChat.messages{ +// println("\(text)") +// +// } +// } +// } } + + } @IBAction func eyeDidAccept() { diff --git a/EyeTypeChat/model/Account.swift b/EyeTypeChat/model/Account.swift index 266f7c2..6d81760 100644 --- a/EyeTypeChat/model/Account.swift +++ b/EyeTypeChat/model/Account.swift @@ -13,6 +13,6 @@ class Account: NSManagedObject { @NSManaged var userIdentifier: String @NSManaged var contacts: NSSet? - @NSManaged var conversations: NSSet + @NSManaged var conversations: NSSet? } diff --git a/EyeTypeChat/model/Contact.swift b/EyeTypeChat/model/Contact.swift index a479e33..793d610 100644 --- a/EyeTypeChat/model/Contact.swift +++ b/EyeTypeChat/model/Contact.swift @@ -13,6 +13,15 @@ class Contact: NSManagedObject { @NSManaged var name: String @NSManaged var phoneNumber: NSNumber - @NSManaged var account: EyeTypeChat.Account + @NSManaged var account: EyeTypeChat.Account // TODO: mark as unowned to avoid strong reference cycles + class func createContact(name: String, phoneNumber: NSNumber, account: Account, entity: String, context: NSManagedObjectContext) -> Contact{ + + var contact = NSEntityDescription.insertNewObjectForEntityForName(entity, inManagedObjectContext: context) as Contact + contact.name = name + contact.phoneNumber = phoneNumber + contact.account = account + + return contact + } } diff --git a/EyeTypeChat/model/Conversation.swift b/EyeTypeChat/model/Conversation.swift index 6e391e2..10e0c13 100644 --- a/EyeTypeChat/model/Conversation.swift +++ b/EyeTypeChat/model/Conversation.swift @@ -12,8 +12,19 @@ import CoreData class Conversation: NSManagedObject { @NSManaged var title: String - @NSManaged var account: EyeTypeChat.Account + @NSManaged var account: EyeTypeChat.Account // TODO: mark as unowned to avoid strong reference cycles @NSManaged var betweenContacts: NSSet - @NSManaged var messages: NSSet + @NSManaged var messages: NSSet? + class func createConversation(title: String, account: Account, betweenContacts: NSSet, messages: NSSet?, entity: String, context: NSManagedObjectContext) -> Conversation{ + + var conversation = NSEntityDescription.insertNewObjectForEntityForName(entity, inManagedObjectContext: context) as Conversation + conversation.title = title + conversation.account = account + conversation.betweenContacts = betweenContacts; + conversation.messages = messages; + + return conversation + } + } diff --git a/EyeTypeChat/model/Message.swift b/EyeTypeChat/model/Message.swift index 312279e..e4ce596 100644 --- a/EyeTypeChat/model/Message.swift +++ b/EyeTypeChat/model/Message.swift @@ -13,7 +13,18 @@ class Message: NSManagedObject { @NSManaged var sentDateTime: NSDate @NSManaged var text: String - @NSManaged var conversation: EyeTypeChat.Conversation - @NSManaged var fromContact: EyeTypeChat.Contact + @NSManaged var conversation: EyeTypeChat.Conversation // TODO: mark as unowned to avoid strong reference cycles + @NSManaged var fromContact: EyeTypeChat.Contact? // fromContact is nil when the message was sent by the user himself + class func createMessage(text: String, sentDateTime: NSDate, conversation: Conversation, fromContact: Contact?, entity: String, context: NSManagedObjectContext) -> Message{ + + var message = NSEntityDescription.insertNewObjectForEntityForName(entity, inManagedObjectContext: context) as Message + message.text = text + message.sentDateTime = sentDateTime + message.conversation = conversation + message.fromContact = fromContact; + + return message + } + } diff --git a/EyeTypeChat/model/TelegramAccount.swift b/EyeTypeChat/model/TelegramAccount.swift index 177fbb1..c8c67f2 100644 --- a/EyeTypeChat/model/TelegramAccount.swift +++ b/EyeTypeChat/model/TelegramAccount.swift @@ -11,5 +11,14 @@ import CoreData class TelegramAccount: EyeTypeChat.Account { - + class func createTelegramAccount(userIdentifier: String, entity: String, context: NSManagedObjectContext) -> TelegramAccount{ + + var telegramAccount = NSEntityDescription.insertNewObjectForEntityForName(entity, inManagedObjectContext: context) as TelegramAccount + telegramAccount.userIdentifier = userIdentifier + + return telegramAccount + } + + + } From cfaaa11af4a956d42c1b45848d0b8b1e4f73fd6b Mon Sep 17 00:00:00 2001 From: Maria Ines Casadei Date: Thu, 18 Dec 2014 16:28:18 -0300 Subject: [PATCH 04/24] Mocked Data --- EyeTypeChat.xcodeproj/project.pbxproj | 4 + EyeTypeChat/MainViewController.swift | 60 +++------------ EyeTypeChat/MockedData.swift | 104 ++++++++++++++++++++++++++ 3 files changed, 119 insertions(+), 49 deletions(-) create mode 100644 EyeTypeChat/MockedData.swift diff --git a/EyeTypeChat.xcodeproj/project.pbxproj b/EyeTypeChat.xcodeproj/project.pbxproj index 420a2ef..4aa3570 100644 --- a/EyeTypeChat.xcodeproj/project.pbxproj +++ b/EyeTypeChat.xcodeproj/project.pbxproj @@ -12,6 +12,7 @@ 232CE5361A3A3DCF00C94EE8 /* Conversation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 232CE5351A3A3DCF00C94EE8 /* Conversation.swift */; }; 232CE5381A3A3E4D00C94EE8 /* Message.swift in Sources */ = {isa = PBXBuildFile; fileRef = 232CE5371A3A3E4D00C94EE8 /* Message.swift */; }; 232CE53A1A3A3E9C00C94EE8 /* Contact.swift in Sources */ = {isa = PBXBuildFile; fileRef = 232CE5391A3A3E9C00C94EE8 /* Contact.swift */; }; + 23C120CE1A4340F8004D7B5E /* MockedData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23C120CD1A4340F8004D7B5E /* MockedData.swift */; }; 5E9B341BA996967017148759 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A49492BC4CA902EDA58BC35 /* libPods.a */; }; 8823D7AE1A30E3D200271406 /* ConversationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8823D7AD1A30E3D200271406 /* ConversationViewController.swift */; }; 8823D7B11A30E8B500271406 /* UIViewController+EyeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8823D7B01A30E8B500271406 /* UIViewController+EyeType.swift */; }; @@ -75,6 +76,7 @@ 232CE5351A3A3DCF00C94EE8 /* Conversation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Conversation.swift; path = model/Conversation.swift; sourceTree = ""; }; 232CE5371A3A3E4D00C94EE8 /* Message.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Message.swift; path = model/Message.swift; sourceTree = ""; }; 232CE5391A3A3E9C00C94EE8 /* Contact.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Contact.swift; path = model/Contact.swift; sourceTree = ""; }; + 23C120CD1A4340F8004D7B5E /* MockedData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockedData.swift; sourceTree = ""; }; 883793181A278BDB00AA856D /* libstdc++.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libstdc++.dylib"; path = "usr/lib/libstdc++.dylib"; sourceTree = SDKROOT; }; 8856809E1A374B2D005F2BB0 /* fixedMenus.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = fixedMenus.plist; sourceTree = ""; }; 885680A11A374BB8005F2BB0 /* FixedMenuViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FixedMenuViewController.swift; sourceTree = ""; }; @@ -188,6 +190,7 @@ 887A2CC41A0BDB4500094E3C /* AppDelegate.swift */, 887A2CC91A0BDB4500094E3C /* MainViewController.swift */, 88A759A01A2F7B070005B04C /* MainViewModel.swift */, + 23C120CD1A4340F8004D7B5E /* MockedData.swift */, 88A759AB1A2F9D4D0005B04C /* EyeControllable.swift */, 8823D7B21A30F65E00271406 /* BaseMenuViewController.swift */, 885680A11A374BB8005F2BB0 /* FixedMenuViewController.swift */, @@ -453,6 +456,7 @@ 885680A71A378E55005F2BB0 /* FixedMenuViewController+Commands.swift in Sources */, 8823D7B31A30F65E00271406 /* BaseMenuViewController.swift in Sources */, 23BA3E291A38EC2100C5AD4B /* Message.swift in Sources */, + 23C120CE1A4340F8004D7B5E /* MockedData.swift in Sources */, 232CE5381A3A3E4D00C94EE8 /* Message.swift in Sources */, 88A759AC1A2F9D4D0005B04C /* EyeControllable.swift in Sources */, 232CE5321A3A3D6100C94EE8 /* Account.swift in Sources */, diff --git a/EyeTypeChat/MainViewController.swift b/EyeTypeChat/MainViewController.swift index dc6fe3f..51f1642 100644 --- a/EyeTypeChat/MainViewController.swift +++ b/EyeTypeChat/MainViewController.swift @@ -15,13 +15,7 @@ class MainViewController: ETVideoSourceViewController { var subNavigationController: UINavigationController! var conversationNavigationController: UINavigationController! var ignoreNextTick = false - - var myModel: MainViewModel { - get { - return self.model as MainViewModel - } - } - + lazy var managedObjectContext : NSManagedObjectContext? = { let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate if let managedObjectContext = appDelegate.managedObjectContext { @@ -39,7 +33,7 @@ class MainViewController: ETVideoSourceViewController { override func viewDidLoad() { super.viewDidLoad() - createMockedData() + createAndPrintMockedData() } override func viewDidAppear(animated: Bool) { @@ -66,51 +60,19 @@ class MainViewController: ETVideoSourceViewController { self.videoSource.stopRunning() } - func createMockedData(){ - - // create Telegram account - var telegramAccount = TelegramAccount.createTelegramAccount("XYZ123", entity: "TelegramAccount", context: self.managedObjectContext!) - - // create contact list - var firstContact = Contact.createContact("Mary", phoneNumber: 263823827, account: telegramAccount, entity: "Contact", context: self.managedObjectContext!) - var secondContact = Contact.createContact("Anna", phoneNumber: 1161690000, account: telegramAccount, entity: "Contact", context: self.managedObjectContext!) - var thirdContact = Contact.createContact("John", phoneNumber: 328378738, account: telegramAccount, entity: "Contact", context: self.managedObjectContext!) - var contactSet = NSMutableSet() - contactSet.addObjectsFromArray([firstContact, secondContact, thirdContact]) - - //asociate contact list with the Telegram account - telegramAccount.contacts = contactSet - - println(managedObjectContext!) - printMockedData() - - } - func printMockedData(){ - let fetchRequest = NSFetchRequest(entityName: "TelegramAccount") - if let fetchResults = managedObjectContext!.executeFetchRequest(fetchRequest, error: nil) as? [TelegramAccount] { - let contacts = fetchResults[0].contacts - for contact in contacts! { - if let eachContact = contact as? Contact { - println("Contact Name: \(eachContact.name). Phone Number: \(eachContact.phoneNumber)") - } - } - -// let conversations = fetchResults[0].conversations -// for chat in conversations! { -// if let eachChat = chat as? Conversation { -// println("Chat: \(eachChat.title)") -// for text in eachChat.messages{ -// println("\(text)") -// -// } -// } -// } + var myModel: MainViewModel { + get { + return self.model as MainViewModel } - - } + func createAndPrintMockedData(){ + MockedData.createMockedData(managedObjectContext!) + MockedData.printMockedData(managedObjectContext!) + } + + @IBAction func eyeDidAccept() { if let controllable = subNavigationController.topViewController as? EyeControllable { controllable.eyeDidAccept() diff --git a/EyeTypeChat/MockedData.swift b/EyeTypeChat/MockedData.swift new file mode 100644 index 0000000..47710f2 --- /dev/null +++ b/EyeTypeChat/MockedData.swift @@ -0,0 +1,104 @@ +// +// MockedData.swift +// EyeTypeChat +// +// Created by Maria Ines Casadei on 12/18/14. +// Copyright (c) 2014 SCV Soft. All rights reserved. +// + +import Foundation +import CoreData +import UIKit + +class MockedData { + + class func createMockedData(dataContext: NSManagedObjectContext){ + + // create Telegram account + var telegramAccount = TelegramAccount.createTelegramAccount("XYZ123", entity: "TelegramAccount", context: dataContext) + + // create contact list + var firstContact = Contact.createContact("Mary", phoneNumber: 263823827, account: telegramAccount, entity: "Contact", context: dataContext) + var secondContact = Contact.createContact("Anna", phoneNumber: 1161690000, account: telegramAccount, entity: "Contact", context: dataContext) + var thirdContact = Contact.createContact("John", phoneNumber: 328378738, account: telegramAccount, entity: "Contact", context: dataContext) + var contactSet = NSMutableSet() + contactSet.addObjectsFromArray([firstContact, secondContact, thirdContact]) + + // create conversation + var contactsInBffChat = NSMutableSet() + contactsInBffChat.addObject(firstContact) + var bffConversation = Conversation.createConversation("BBF", account: telegramAccount, betweenContacts: contactsInBffChat, messages: nil, entity: "Conversation", context: dataContext) + + // create some messages for bff conversation + var currentDate: NSDate? = NSDate(); + var msg1 = Message.createMessage("Hi Mary!", sentDateTime: currentDate!, conversation: bffConversation, fromContact: nil, entity: "Message", context: dataContext) + + var msg2 = Message.createMessage("How are you?", sentDateTime: currentDate!, conversation: bffConversation, fromContact: nil, entity: "Message", context: dataContext) + + currentDate = MockedData.dateByAddingMinutes(1, date: currentDate) + var msg3 = Message.createMessage("Great! and u?", sentDateTime: currentDate!, conversation: bffConversation, fromContact: firstContact, entity: "Message", context: dataContext) + + currentDate = MockedData.dateByAddingMinutes(2, date: currentDate) + var msg4 = Message.createMessage("How was San Francisco?", sentDateTime: currentDate!, conversation: bffConversation, fromContact: firstContact, entity: "Message", context: dataContext) + + currentDate = MockedData.dateByAddingMinutes(1, date: currentDate) + var msg5 = Message.createMessage("Fantastic! See u tomorrow?", sentDateTime: currentDate!, conversation: bffConversation, fromContact: nil, entity: "Message", context:dataContext) + + currentDate = MockedData.dateByAddingMinutes(3, date: currentDate) + var msg6 = Message.createMessage("Sure :)", sentDateTime: currentDate!, conversation: bffConversation, fromContact: firstContact, entity: "Message", context: dataContext) + + var messages = NSMutableSet() + messages.addObjectsFromArray([msg1, msg2, msg3, msg4, msg5, msg6]) + bffConversation.messages = messages + var conversationSet = NSMutableSet() + conversationSet.addObject(bffConversation) + + //associate contact list with the Telegram account + telegramAccount.contacts = contactSet + //associate conversation list with the Telegram account + telegramAccount.conversations = conversationSet + + + } + + class func dateByAddingMinutes(value: Int, date: NSDate?) -> NSDate?{ + return NSCalendar.currentCalendar().dateByAddingUnit(NSCalendarUnit.CalendarUnitMinute, value: value, toDate: date!, options: NSCalendarOptions.SearchBackwards) + } + + class func printMockedData(dataContext: NSManagedObjectContext){ + + println(dataContext) + let fetchRequest = NSFetchRequest(entityName: "TelegramAccount") + if let fetchResults = dataContext.executeFetchRequest(fetchRequest, error: nil) as? [TelegramAccount] { + + let contacts = fetchResults[0].contacts + for contact in contacts! { + if let eachContact = contact as? Contact { + println("Contact Name: \(eachContact.name). Phone Number: \(eachContact.phoneNumber)") + } + } + + let conversations = fetchResults[0].conversations + for chat in conversations! { + if let eachChat = chat as? Conversation { + println("Chat: \(eachChat.title)") + let messages = eachChat.messages + var msgsArray = messages?.allObjects as [Message] + + var sortedMsgs : [Message] = msgsArray + sortedMsgs.sort({$0.sentDateTime.timeIntervalSinceNow < $1.sentDateTime.timeIntervalSinceNow}) + + for msg in sortedMsgs{ + println("Message: \(msg.text) Sent: \(msg.sentDateTime)") + } + + } + } + + } + + } + + + +} \ No newline at end of file From fca43af6dff29274629bdec8725a120f1d3465e2 Mon Sep 17 00:00:00 2001 From: Maria Ines Casadei Date: Fri, 19 Dec 2014 11:51:52 -0300 Subject: [PATCH 05/24] Added group chat --- EyeTypeChat/MockedData.swift | 65 +++++++++++++++++++++++++++--------- 1 file changed, 50 insertions(+), 15 deletions(-) diff --git a/EyeTypeChat/MockedData.swift b/EyeTypeChat/MockedData.swift index 47710f2..82b43bf 100644 --- a/EyeTypeChat/MockedData.swift +++ b/EyeTypeChat/MockedData.swift @@ -18,44 +18,74 @@ class MockedData { var telegramAccount = TelegramAccount.createTelegramAccount("XYZ123", entity: "TelegramAccount", context: dataContext) // create contact list + var contactSet = NSMutableSet() var firstContact = Contact.createContact("Mary", phoneNumber: 263823827, account: telegramAccount, entity: "Contact", context: dataContext) var secondContact = Contact.createContact("Anna", phoneNumber: 1161690000, account: telegramAccount, entity: "Contact", context: dataContext) var thirdContact = Contact.createContact("John", phoneNumber: 328378738, account: telegramAccount, entity: "Contact", context: dataContext) - var contactSet = NSMutableSet() contactSet.addObjectsFromArray([firstContact, secondContact, thirdContact]) - // create conversation + // create conversations + var conversationSet = NSMutableSet() + + // create bff chat var contactsInBffChat = NSMutableSet() contactsInBffChat.addObject(firstContact) var bffConversation = Conversation.createConversation("BBF", account: telegramAccount, betweenContacts: contactsInBffChat, messages: nil, entity: "Conversation", context: dataContext) - // create some messages for bff conversation + // create some messages for bff chat var currentDate: NSDate? = NSDate(); - var msg1 = Message.createMessage("Hi Mary!", sentDateTime: currentDate!, conversation: bffConversation, fromContact: nil, entity: "Message", context: dataContext) + var msg01 = Message.createMessage("Hi Mary!", sentDateTime: currentDate!, conversation: bffConversation, fromContact: nil, entity: "Message", context: dataContext) - var msg2 = Message.createMessage("How are you?", sentDateTime: currentDate!, conversation: bffConversation, fromContact: nil, entity: "Message", context: dataContext) + var msg02 = Message.createMessage("How are you?", sentDateTime: currentDate!, conversation: bffConversation, fromContact: nil, entity: "Message", context: dataContext) currentDate = MockedData.dateByAddingMinutes(1, date: currentDate) - var msg3 = Message.createMessage("Great! and u?", sentDateTime: currentDate!, conversation: bffConversation, fromContact: firstContact, entity: "Message", context: dataContext) + var msg03 = Message.createMessage("Great! and u?", sentDateTime: currentDate!, conversation: bffConversation, fromContact: firstContact, entity: "Message", context: dataContext) currentDate = MockedData.dateByAddingMinutes(2, date: currentDate) - var msg4 = Message.createMessage("How was San Francisco?", sentDateTime: currentDate!, conversation: bffConversation, fromContact: firstContact, entity: "Message", context: dataContext) + var msg04 = Message.createMessage("How was San Francisco?", sentDateTime: currentDate!, conversation: bffConversation, fromContact: firstContact, entity: "Message", context: dataContext) currentDate = MockedData.dateByAddingMinutes(1, date: currentDate) - var msg5 = Message.createMessage("Fantastic! See u tomorrow?", sentDateTime: currentDate!, conversation: bffConversation, fromContact: nil, entity: "Message", context:dataContext) + var msg05 = Message.createMessage("Fantastic! See u tomorrow?", sentDateTime: currentDate!, conversation: bffConversation, fromContact: nil, entity: "Message", context:dataContext) currentDate = MockedData.dateByAddingMinutes(3, date: currentDate) - var msg6 = Message.createMessage("Sure :)", sentDateTime: currentDate!, conversation: bffConversation, fromContact: firstContact, entity: "Message", context: dataContext) + var msg06 = Message.createMessage("Sure :)", sentDateTime: currentDate!, conversation: bffConversation, fromContact: firstContact, entity: "Message", context: dataContext) var messages = NSMutableSet() - messages.addObjectsFromArray([msg1, msg2, msg3, msg4, msg5, msg6]) + messages.addObjectsFromArray([msg01, msg02, msg03, msg04, msg05, msg06]) bffConversation.messages = messages - var conversationSet = NSMutableSet() conversationSet.addObject(bffConversation) - //associate contact list with the Telegram account + // create group chat + var contactsInGroupChat = NSMutableSet() + contactsInGroupChat.addObjectsFromArray([secondContact, thirdContact]) + var groupConversation = Conversation.createConversation("Trip to NY", account: telegramAccount, betweenContacts: contactsInGroupChat, messages: nil, entity: "Conversation", context: dataContext) + + // create some messages for group chat + var msg11 = Message.createMessage("Hello everyone!", sentDateTime: currentDate!, conversation: bffConversation, fromContact: secondContact, entity: "Message", context: dataContext) + + currentDate = MockedData.dateByAddingMinutes(1, date: currentDate) + var msg12 = Message.createMessage("Hi!", sentDateTime: currentDate!, conversation: groupConversation, fromContact: nil, entity: "Message", context: dataContext) + + currentDate = MockedData.dateByAddingMinutes(1, date: currentDate) + var msg13 = Message.createMessage("Any news from Tom?", sentDateTime: currentDate!, conversation: groupConversation, fromContact: secondContact, entity: "Message", context: dataContext) + + currentDate = MockedData.dateByAddingMinutes(2, date: currentDate) + var msg14 = Message.createMessage("He sent a confirmation email", sentDateTime: currentDate!, conversation: groupConversation, fromContact: thirdContact, entity: "Message", context: dataContext) + + currentDate = MockedData.dateByAddingMinutes(1, date: currentDate) + var msg15 = Message.createMessage("January 16th?", sentDateTime: currentDate!, conversation: groupConversation, fromContact: nil, entity: "Message", context:dataContext) + + currentDate = MockedData.dateByAddingMinutes(3, date: currentDate) + var msg16 = Message.createMessage("Right", sentDateTime: currentDate!, conversation: groupConversation, fromContact: secondContact, entity: "Message", context: dataContext) + + var groupMessages = NSMutableSet() + groupMessages.addObjectsFromArray([msg11, msg12, msg13, msg14, msg15, msg16]) + groupConversation.messages = groupMessages + conversationSet.addObject(groupConversation) + + // associate contact list with the Telegram account telegramAccount.contacts = contactSet - //associate conversation list with the Telegram account + // associate conversation list with the Telegram account telegramAccount.conversations = conversationSet @@ -67,7 +97,6 @@ class MockedData { class func printMockedData(dataContext: NSManagedObjectContext){ - println(dataContext) let fetchRequest = NSFetchRequest(entityName: "TelegramAccount") if let fetchResults = dataContext.executeFetchRequest(fetchRequest, error: nil) as? [TelegramAccount] { @@ -89,7 +118,13 @@ class MockedData { sortedMsgs.sort({$0.sentDateTime.timeIntervalSinceNow < $1.sentDateTime.timeIntervalSinceNow}) for msg in sortedMsgs{ - println("Message: \(msg.text) Sent: \(msg.sentDateTime)") + var messageDetails: String + if let from = msg.fromContact{ + messageDetails = "Message: \(msg.text). From: \(msg.fromContact!.name). Sent: \(msg.sentDateTime)." + }else{ + messageDetails = "Message: \(msg.text). From: me. Sent: \(msg.sentDateTime)." + } + println(messageDetails) } } From e19589491db1a0a92455dbf03223352d6908969f Mon Sep 17 00:00:00 2001 From: Maria Ines Casadei Date: Fri, 19 Dec 2014 12:26:20 -0300 Subject: [PATCH 06/24] Date formatted --- EyeTypeChat/MockedData.swift | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/EyeTypeChat/MockedData.swift b/EyeTypeChat/MockedData.swift index 82b43bf..c9cd091 100644 --- a/EyeTypeChat/MockedData.swift +++ b/EyeTypeChat/MockedData.swift @@ -36,6 +36,7 @@ class MockedData { var currentDate: NSDate? = NSDate(); var msg01 = Message.createMessage("Hi Mary!", sentDateTime: currentDate!, conversation: bffConversation, fromContact: nil, entity: "Message", context: dataContext) + currentDate = MockedData.dateByAddingMinutes(1, date: currentDate) var msg02 = Message.createMessage("How are you?", sentDateTime: currentDate!, conversation: bffConversation, fromContact: nil, entity: "Message", context: dataContext) currentDate = MockedData.dateByAddingMinutes(1, date: currentDate) @@ -101,6 +102,7 @@ class MockedData { if let fetchResults = dataContext.executeFetchRequest(fetchRequest, error: nil) as? [TelegramAccount] { let contacts = fetchResults[0].contacts + println("Contact list") for contact in contacts! { if let eachContact = contact as? Contact { println("Contact Name: \(eachContact.name). Phone Number: \(eachContact.phoneNumber)") @@ -117,12 +119,16 @@ class MockedData { var sortedMsgs : [Message] = msgsArray sortedMsgs.sort({$0.sentDateTime.timeIntervalSinceNow < $1.sentDateTime.timeIntervalSinceNow}) + let dateStringFormatter = NSDateFormatter() + dateStringFormatter.dateFormat = "yyyy-MM-dd hh:mm" + for msg in sortedMsgs{ + let sentFormattedDate = dateStringFormatter.stringFromDate(msg.sentDateTime) var messageDetails: String if let from = msg.fromContact{ - messageDetails = "Message: \(msg.text). From: \(msg.fromContact!.name). Sent: \(msg.sentDateTime)." + messageDetails = "Message: \(msg.text). From: \(msg.fromContact!.name). Sent: \(sentFormattedDate)." }else{ - messageDetails = "Message: \(msg.text). From: me. Sent: \(msg.sentDateTime)." + messageDetails = "Message: \(msg.text). From: me. Sent: \(sentFormattedDate)." } println(messageDetails) } From 4dcca4e3f37daf7038266bc5f7044f5f240b6267 Mon Sep 17 00:00:00 2001 From: Maria Ines Casadei Date: Mon, 22 Dec 2014 14:59:43 -0300 Subject: [PATCH 07/24] Displaying conversation titles --- EyeTypeChat.xcodeproj/project.pbxproj | 49 ++++++------- EyeTypeChat/Base.lproj/Main.storyboard | 7 +- EyeTypeChat/ConversationViewController.swift | 72 +++++++++++++++++-- .../FixedMenuViewController+Commands.swift | 4 +- EyeTypeChat/MainViewController.swift | 2 +- EyeTypeChat/MockedData.swift | 20 +++++- 6 files changed, 116 insertions(+), 38 deletions(-) diff --git a/EyeTypeChat.xcodeproj/project.pbxproj b/EyeTypeChat.xcodeproj/project.pbxproj index 4aa3570..96e529c 100644 --- a/EyeTypeChat.xcodeproj/project.pbxproj +++ b/EyeTypeChat.xcodeproj/project.pbxproj @@ -12,6 +12,7 @@ 232CE5361A3A3DCF00C94EE8 /* Conversation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 232CE5351A3A3DCF00C94EE8 /* Conversation.swift */; }; 232CE5381A3A3E4D00C94EE8 /* Message.swift in Sources */ = {isa = PBXBuildFile; fileRef = 232CE5371A3A3E4D00C94EE8 /* Message.swift */; }; 232CE53A1A3A3E9C00C94EE8 /* Contact.swift in Sources */ = {isa = PBXBuildFile; fileRef = 232CE5391A3A3E9C00C94EE8 /* Contact.swift */; }; + 236ACA281A44B8B2003D1F53 /* EyeControllable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88A759AB1A2F9D4D0005B04C /* EyeControllable.swift */; }; 23C120CE1A4340F8004D7B5E /* MockedData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23C120CD1A4340F8004D7B5E /* MockedData.swift */; }; 5E9B341BA996967017148759 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A49492BC4CA902EDA58BC35 /* libPods.a */; }; 8823D7AE1A30E3D200271406 /* ConversationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8823D7AD1A30E3D200271406 /* ConversationViewController.swift */; }; @@ -32,7 +33,6 @@ 887A2CD21A0BDB4500094E3C /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 887A2CD01A0BDB4500094E3C /* LaunchScreen.xib */; }; 887A2CDE1A0BDB4500094E3C /* EyeTypeChatTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 887A2CDD1A0BDB4500094E3C /* EyeTypeChatTests.swift */; }; 88A759A11A2F7B070005B04C /* MainViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88A759A01A2F7B070005B04C /* MainViewModel.swift */; }; - 88A759AC1A2F9D4D0005B04C /* EyeControllable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88A759AB1A2F9D4D0005B04C /* EyeControllable.swift */; }; 88A759B11A2F9FC10005B04C /* KeyboardViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88A759B01A2F9FC10005B04C /* KeyboardViewController.swift */; }; 88BC6E7D1A12A6F600D3A54E /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 88BC6E7C1A12A6F600D3A54E /* CoreGraphics.framework */; }; 88BC6E801A12A78C00D3A54E /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 88BC6E7F1A12A78C00D3A54E /* MediaPlayer.framework */; }; @@ -64,19 +64,15 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 8823D7AD1A30E3D200271406 /* ConversationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConversationViewController.swift; sourceTree = ""; }; - 8823D7B01A30E8B500271406 /* UIViewController+EyeType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+EyeType.swift"; sourceTree = ""; }; - 8823D7B21A30F65E00271406 /* BaseMenuViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseMenuViewController.swift; sourceTree = ""; }; - 2395D1551A39F53900F784EC /* Account.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Account.swift; sourceTree = ""; }; - 23BA3E261A38EC2000C5AD4B /* Contact.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Contact.swift; path = model/Contact.swift; sourceTree = ""; }; - 23BA3E281A38EC2100C5AD4B /* Message.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Message.swift; path = model/Message.swift; sourceTree = ""; }; - 23BA3E2A1A38EC2100C5AD4B /* Conversation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Conversation.swift; path = model/Conversation.swift; sourceTree = ""; }; 232CE5311A3A3D6100C94EE8 /* Account.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Account.swift; path = model/Account.swift; sourceTree = ""; }; 232CE5331A3A3D9300C94EE8 /* TelegramAccount.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TelegramAccount.swift; path = model/TelegramAccount.swift; sourceTree = ""; }; 232CE5351A3A3DCF00C94EE8 /* Conversation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Conversation.swift; path = model/Conversation.swift; sourceTree = ""; }; 232CE5371A3A3E4D00C94EE8 /* Message.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Message.swift; path = model/Message.swift; sourceTree = ""; }; 232CE5391A3A3E9C00C94EE8 /* Contact.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Contact.swift; path = model/Contact.swift; sourceTree = ""; }; 23C120CD1A4340F8004D7B5E /* MockedData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockedData.swift; sourceTree = ""; }; + 8823D7AD1A30E3D200271406 /* ConversationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConversationViewController.swift; sourceTree = ""; }; + 8823D7B01A30E8B500271406 /* UIViewController+EyeType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+EyeType.swift"; sourceTree = ""; }; + 8823D7B21A30F65E00271406 /* BaseMenuViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseMenuViewController.swift; sourceTree = ""; }; 883793181A278BDB00AA856D /* libstdc++.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libstdc++.dylib"; path = "usr/lib/libstdc++.dylib"; sourceTree = SDKROOT; }; 8856809E1A374B2D005F2BB0 /* fixedMenus.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = fixedMenus.plist; sourceTree = ""; }; 885680A11A374BB8005F2BB0 /* FixedMenuViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FixedMenuViewController.swift; sourceTree = ""; }; @@ -150,6 +146,20 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 236ACA291A44BEFB003D1F53 /* controllers */ = { + isa = PBXGroup; + children = ( + 887A2CC91A0BDB4500094E3C /* MainViewController.swift */, + 8823D7B21A30F65E00271406 /* BaseMenuViewController.swift */, + 885680A11A374BB8005F2BB0 /* FixedMenuViewController.swift */, + 885680A61A378E55005F2BB0 /* FixedMenuViewController+Commands.swift */, + 88A759B01A2F9FC10005B04C /* KeyboardViewController.swift */, + 8823D7AD1A30E3D200271406 /* ConversationViewController.swift */, + 8823D7B01A30E8B500271406 /* UIViewController+EyeType.swift */, + ); + name = controllers; + sourceTree = ""; + }; 23BA3E251A38EB1500C5AD4B /* model */ = { isa = PBXGroup; children = ( @@ -187,27 +197,18 @@ isa = PBXGroup; children = ( 23BA3E251A38EB1500C5AD4B /* model */, - 887A2CC41A0BDB4500094E3C /* AppDelegate.swift */, - 887A2CC91A0BDB4500094E3C /* MainViewController.swift */, + 236ACA291A44BEFB003D1F53 /* controllers */, 88A759A01A2F7B070005B04C /* MainViewModel.swift */, + 887A2CC41A0BDB4500094E3C /* AppDelegate.swift */, 23C120CD1A4340F8004D7B5E /* MockedData.swift */, 88A759AB1A2F9D4D0005B04C /* EyeControllable.swift */, - 8823D7B21A30F65E00271406 /* BaseMenuViewController.swift */, - 885680A11A374BB8005F2BB0 /* FixedMenuViewController.swift */, - 885680A61A378E55005F2BB0 /* FixedMenuViewController+Commands.swift */, - 88A759B01A2F9FC10005B04C /* KeyboardViewController.swift */, - 8823D7AD1A30E3D200271406 /* ConversationViewController.swift */, - 8823D7B01A30E8B500271406 /* UIViewController+EyeType.swift */, 885ABDE41A13E1DD00552B16 /* MyPlayground.playground */, + 8856809E1A374B2D005F2BB0 /* fixedMenus.plist */, 887A2CCB1A0BDB4500094E3C /* Main.storyboard */, 887A2CCE1A0BDB4500094E3C /* Images.xcassets */, 887A2CD01A0BDB4500094E3C /* LaunchScreen.xib */, 887A2CC61A0BDB4500094E3C /* EyeTypeChat.xcdatamodeld */, 887A2CC21A0BDB4500094E3C /* Supporting Files */, - 88C5237B1A12933E005E0D71 /* EyeTypeChat-Bridging-Header.h */, - 8856809E1A374B2D005F2BB0 /* fixedMenus.plist */, - 885680A31A376E1F005F2BB0 /* SwiftBridge.h */, - 885680A41A376E47005F2BB0 /* SwiftBridge.m */, ); path = EyeTypeChat; sourceTree = ""; @@ -215,6 +216,9 @@ 887A2CC21A0BDB4500094E3C /* Supporting Files */ = { isa = PBXGroup; children = ( + 88C5237B1A12933E005E0D71 /* EyeTypeChat-Bridging-Header.h */, + 885680A31A376E1F005F2BB0 /* SwiftBridge.h */, + 885680A41A376E47005F2BB0 /* SwiftBridge.m */, 887A2CC31A0BDB4500094E3C /* Info.plist */, 885D57601A25062D00912290 /* Podfile */, ); @@ -439,8 +443,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 236ACA281A44B8B2003D1F53 /* EyeControllable.swift in Sources */, 8823D7AE1A30E3D200271406 /* ConversationViewController.swift in Sources */, - 2395D1561A39F53900F784EC /* Account.swift in Sources */, 232CE5361A3A3DCF00C94EE8 /* Conversation.swift in Sources */, 887A2CCA1A0BDB4500094E3C /* MainViewController.swift in Sources */, 232CE53A1A3A3E9C00C94EE8 /* Contact.swift in Sources */, @@ -452,13 +456,10 @@ 8823D7B11A30E8B500271406 /* UIViewController+EyeType.swift in Sources */, 885680A21A374BB8005F2BB0 /* FixedMenuViewController.swift in Sources */, 885680A51A376E47005F2BB0 /* SwiftBridge.m in Sources */, - 88A759AC1A2F9D4D0005B04C /* EyeControllable.swift in Sources */, 885680A71A378E55005F2BB0 /* FixedMenuViewController+Commands.swift in Sources */, 8823D7B31A30F65E00271406 /* BaseMenuViewController.swift in Sources */, - 23BA3E291A38EC2100C5AD4B /* Message.swift in Sources */, 23C120CE1A4340F8004D7B5E /* MockedData.swift in Sources */, 232CE5381A3A3E4D00C94EE8 /* Message.swift in Sources */, - 88A759AC1A2F9D4D0005B04C /* EyeControllable.swift in Sources */, 232CE5321A3A3D6100C94EE8 /* Account.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/EyeTypeChat/Base.lproj/Main.storyboard b/EyeTypeChat/Base.lproj/Main.storyboard index e06a97a..447e9af 100644 --- a/EyeTypeChat/Base.lproj/Main.storyboard +++ b/EyeTypeChat/Base.lproj/Main.storyboard @@ -212,10 +212,10 @@ - + - + @@ -226,9 +226,6 @@ - - - diff --git a/EyeTypeChat/ConversationViewController.swift b/EyeTypeChat/ConversationViewController.swift index fcb5377..3056a33 100644 --- a/EyeTypeChat/ConversationViewController.swift +++ b/EyeTypeChat/ConversationViewController.swift @@ -7,14 +7,76 @@ // import UIKit +import Foundation +import CoreData -class ConversationViewController: UITableViewController { - +class ConversationViewController: BaseMenuViewController { + + lazy var managedObjectContext : NSManagedObjectContext? = { + let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate + if let managedObjectContext = appDelegate.managedObjectContext { + return managedObjectContext + } + else { + return nil + } + }() + + var conversationItems = [ConversationItem]() + + override func viewDidLoad() { + loadConversationItems() + super.viewDidLoad() + } + + func loadConversationItems() { + // load dynamically the mocked conversations + let conversations = MockedData.getConversationList(managedObjectContext!) + for item in conversations! { + let chatItem = ConversationItem(item: item as Conversation) + conversationItems.append(chatItem) + } + } + override func numberOfSectionsInTableView(tableView: UITableView) -> Int { - return 1 + return showCancel ? 2 : 1 } - + override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return 0 + if section > 0 { + return 1 + } + return conversationItems.count + } + + override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { + let cell = self.cell() + if indexPath.section > 0 { + cell.textLabel?.text = "Cancel" + } + else { + cell.textLabel?.text = conversationItems[indexPath.row].title + } + return cell + } + + override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { + if indexPath.section > 0 { + eyeDidCancel() + } + else { + performSelectorInObject(self, conversationItems[indexPath.row].selector) + } + } + + class ConversationItem { + var title: String + var selector: Selector + + init (item: Conversation) { + title = item.title + selector = Selector("showKeyboard") + } } + } diff --git a/EyeTypeChat/FixedMenuViewController+Commands.swift b/EyeTypeChat/FixedMenuViewController+Commands.swift index c5e7a40..c6e5017 100644 --- a/EyeTypeChat/FixedMenuViewController+Commands.swift +++ b/EyeTypeChat/FixedMenuViewController+Commands.swift @@ -1,5 +1,5 @@ // -// FixedMenuViewController+Commands.swift +// ConversationViewController+Commands.swift // EyeTypeChat // // Created by Emanuel Andrada on 9/12/14. @@ -8,7 +8,7 @@ import Foundation -extension FixedMenuViewController { +extension ConversationViewController { func showKeyboard() { let viewController = self.storyboard!.instantiateViewControllerWithIdentifier("keyboard") as UIViewController! diff --git a/EyeTypeChat/MainViewController.swift b/EyeTypeChat/MainViewController.swift index 51f1642..fd76dc7 100644 --- a/EyeTypeChat/MainViewController.swift +++ b/EyeTypeChat/MainViewController.swift @@ -68,7 +68,7 @@ class MainViewController: ETVideoSourceViewController { } func createAndPrintMockedData(){ - MockedData.createMockedData(managedObjectContext!) + var mockedData = MockedData(dataContext: managedObjectContext!) MockedData.printMockedData(managedObjectContext!) } diff --git a/EyeTypeChat/MockedData.swift b/EyeTypeChat/MockedData.swift index c9cd091..40863e7 100644 --- a/EyeTypeChat/MockedData.swift +++ b/EyeTypeChat/MockedData.swift @@ -12,7 +12,7 @@ import UIKit class MockedData { - class func createMockedData(dataContext: NSManagedObjectContext){ + init(dataContext: NSManagedObjectContext){ // create Telegram account var telegramAccount = TelegramAccount.createTelegramAccount("XYZ123", entity: "TelegramAccount", context: dataContext) @@ -96,6 +96,24 @@ class MockedData { return NSCalendar.currentCalendar().dateByAddingUnit(NSCalendarUnit.CalendarUnitMinute, value: value, toDate: date!, options: NSCalendarOptions.SearchBackwards) } + class func getConversationList(dataContext: NSManagedObjectContext) -> NSSet?{ + let fetchRequest = NSFetchRequest(entityName: "TelegramAccount") + if let fetchResults = dataContext.executeFetchRequest(fetchRequest, error: nil) as? [TelegramAccount] { + + return fetchResults[0].conversations + } + return nil + } + + class func getContactList(dataContext: NSManagedObjectContext) -> NSSet?{ + let fetchRequest = NSFetchRequest(entityName: "TelegramAccount") + if let fetchResults = dataContext.executeFetchRequest(fetchRequest, error: nil) as? [TelegramAccount] { + + return fetchResults[0].contacts + } + return nil + } + class func printMockedData(dataContext: NSManagedObjectContext){ let fetchRequest = NSFetchRequest(entityName: "TelegramAccount") From 01882301bd5557a7b50318b670619e63bd7dd2dc Mon Sep 17 00:00:00 2001 From: Maria Ines Casadei Date: Tue, 30 Dec 2014 13:13:51 -0300 Subject: [PATCH 08/24] Messages in ChatViewController --- EyeTypeChat.xcodeproj/project.pbxproj | 42 ++++++--- EyeTypeChat/Base.lproj/Main.storyboard | 2 +- EyeTypeChat/BaseMenuViewController.swift | 8 ++ EyeTypeChat/ChatViewController.swift | 94 +++++++++++++++++++ EyeTypeChat/ChatViewModel.swift | 47 ++++++++++ ...ConversationViewController+Commands.swift} | 5 +- EyeTypeChat/ConversationViewController.swift | 6 +- EyeTypeChat/FixedMenuViewController.swift | 2 +- EyeTypeChat/KeyboardViewController.swift | 51 ++++++++-- EyeTypeChat/MainViewModel.swift | 1 + EyeTypeChat/MockedData.swift | 43 +++++++-- .../MyPlayground.playground/section-1.swift | 1 + EyeTypeChat/SwiftBridge.h | 3 +- EyeTypeChat/SwiftBridge.m | 4 +- EyeTypeChat/fixedMenus.plist | 2 +- 15 files changed, 275 insertions(+), 36 deletions(-) create mode 100644 EyeTypeChat/ChatViewController.swift create mode 100644 EyeTypeChat/ChatViewModel.swift rename EyeTypeChat/{FixedMenuViewController+Commands.swift => ConversationViewController+Commands.swift} (53%) diff --git a/EyeTypeChat.xcodeproj/project.pbxproj b/EyeTypeChat.xcodeproj/project.pbxproj index 96e529c..52ea511 100644 --- a/EyeTypeChat.xcodeproj/project.pbxproj +++ b/EyeTypeChat.xcodeproj/project.pbxproj @@ -12,8 +12,10 @@ 232CE5361A3A3DCF00C94EE8 /* Conversation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 232CE5351A3A3DCF00C94EE8 /* Conversation.swift */; }; 232CE5381A3A3E4D00C94EE8 /* Message.swift in Sources */ = {isa = PBXBuildFile; fileRef = 232CE5371A3A3E4D00C94EE8 /* Message.swift */; }; 232CE53A1A3A3E9C00C94EE8 /* Contact.swift in Sources */ = {isa = PBXBuildFile; fileRef = 232CE5391A3A3E9C00C94EE8 /* Contact.swift */; }; + 2333C0A21A51A0F900784BEA /* ChatViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2333C0A11A51A0F900784BEA /* ChatViewModel.swift */; }; 236ACA281A44B8B2003D1F53 /* EyeControllable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88A759AB1A2F9D4D0005B04C /* EyeControllable.swift */; }; 23C120CE1A4340F8004D7B5E /* MockedData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23C120CD1A4340F8004D7B5E /* MockedData.swift */; }; + 23FAF5451A52EDED00ADD423 /* ChatViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23FAF5441A52EDED00ADD423 /* ChatViewController.swift */; }; 5E9B341BA996967017148759 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A49492BC4CA902EDA58BC35 /* libPods.a */; }; 8823D7AE1A30E3D200271406 /* ConversationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8823D7AD1A30E3D200271406 /* ConversationViewController.swift */; }; 8823D7B11A30E8B500271406 /* UIViewController+EyeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8823D7B01A30E8B500271406 /* UIViewController+EyeType.swift */; }; @@ -21,7 +23,7 @@ 8856809F1A374B2D005F2BB0 /* fixedMenus.plist in Resources */ = {isa = PBXBuildFile; fileRef = 8856809E1A374B2D005F2BB0 /* fixedMenus.plist */; }; 885680A21A374BB8005F2BB0 /* FixedMenuViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 885680A11A374BB8005F2BB0 /* FixedMenuViewController.swift */; }; 885680A51A376E47005F2BB0 /* SwiftBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 885680A41A376E47005F2BB0 /* SwiftBridge.m */; }; - 885680A71A378E55005F2BB0 /* FixedMenuViewController+Commands.swift in Sources */ = {isa = PBXBuildFile; fileRef = 885680A61A378E55005F2BB0 /* FixedMenuViewController+Commands.swift */; }; + 885680A71A378E55005F2BB0 /* ConversationViewController+Commands.swift in Sources */ = {isa = PBXBuildFile; fileRef = 885680A61A378E55005F2BB0 /* ConversationViewController+Commands.swift */; }; 885D57611A25062D00912290 /* Podfile in Resources */ = {isa = PBXBuildFile; fileRef = 885D57601A25062D00912290 /* Podfile */; }; 885D576A1A2513FF00912290 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 885D57691A2513FF00912290 /* CoreLocation.framework */; }; 885D57701A25159000912290 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 885D576F1A25159000912290 /* SystemConfiguration.framework */; }; @@ -69,7 +71,9 @@ 232CE5351A3A3DCF00C94EE8 /* Conversation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Conversation.swift; path = model/Conversation.swift; sourceTree = ""; }; 232CE5371A3A3E4D00C94EE8 /* Message.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Message.swift; path = model/Message.swift; sourceTree = ""; }; 232CE5391A3A3E9C00C94EE8 /* Contact.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Contact.swift; path = model/Contact.swift; sourceTree = ""; }; + 2333C0A11A51A0F900784BEA /* ChatViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatViewModel.swift; sourceTree = ""; }; 23C120CD1A4340F8004D7B5E /* MockedData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockedData.swift; sourceTree = ""; }; + 23FAF5441A52EDED00ADD423 /* ChatViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatViewController.swift; sourceTree = ""; }; 8823D7AD1A30E3D200271406 /* ConversationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConversationViewController.swift; sourceTree = ""; }; 8823D7B01A30E8B500271406 /* UIViewController+EyeType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+EyeType.swift"; sourceTree = ""; }; 8823D7B21A30F65E00271406 /* BaseMenuViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseMenuViewController.swift; sourceTree = ""; }; @@ -78,7 +82,7 @@ 885680A11A374BB8005F2BB0 /* FixedMenuViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FixedMenuViewController.swift; sourceTree = ""; }; 885680A31A376E1F005F2BB0 /* SwiftBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SwiftBridge.h; sourceTree = ""; }; 885680A41A376E47005F2BB0 /* SwiftBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SwiftBridge.m; sourceTree = ""; }; - 885680A61A378E55005F2BB0 /* FixedMenuViewController+Commands.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "FixedMenuViewController+Commands.swift"; sourceTree = ""; }; + 885680A61A378E55005F2BB0 /* ConversationViewController+Commands.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ConversationViewController+Commands.swift"; sourceTree = ""; }; 885ABDE41A13E1DD00552B16 /* MyPlayground.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = MyPlayground.playground; sourceTree = ""; }; 885D57601A25062D00912290 /* Podfile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Podfile; sourceTree = SOURCE_ROOT; }; 885D57691A2513FF00912290 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; }; @@ -146,21 +150,31 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 236ACA291A44BEFB003D1F53 /* controllers */ = { + 2333C0A01A51A0EC00784BEA /* View Model */ = { + isa = PBXGroup; + children = ( + 2333C0A11A51A0F900784BEA /* ChatViewModel.swift */, + 88A759A01A2F7B070005B04C /* MainViewModel.swift */, + ); + name = "View Model"; + sourceTree = ""; + }; + 236ACA291A44BEFB003D1F53 /* Controllers */ = { isa = PBXGroup; children = ( 887A2CC91A0BDB4500094E3C /* MainViewController.swift */, 8823D7B21A30F65E00271406 /* BaseMenuViewController.swift */, 885680A11A374BB8005F2BB0 /* FixedMenuViewController.swift */, - 885680A61A378E55005F2BB0 /* FixedMenuViewController+Commands.swift */, + 885680A61A378E55005F2BB0 /* ConversationViewController+Commands.swift */, 88A759B01A2F9FC10005B04C /* KeyboardViewController.swift */, 8823D7AD1A30E3D200271406 /* ConversationViewController.swift */, 8823D7B01A30E8B500271406 /* UIViewController+EyeType.swift */, + 23FAF5441A52EDED00ADD423 /* ChatViewController.swift */, ); - name = controllers; + name = Controllers; sourceTree = ""; }; - 23BA3E251A38EB1500C5AD4B /* model */ = { + 23BA3E251A38EB1500C5AD4B /* Core Data Model */ = { isa = PBXGroup; children = ( 232CE5391A3A3E9C00C94EE8 /* Contact.swift */, @@ -169,7 +183,7 @@ 232CE5331A3A3D9300C94EE8 /* TelegramAccount.swift */, 232CE5311A3A3D6100C94EE8 /* Account.swift */, ); - name = model; + name = "Core Data Model"; sourceTree = ""; }; 887A2CB61A0BDB4400094E3C = { @@ -196,17 +210,15 @@ 887A2CC11A0BDB4500094E3C /* EyeTypeChat */ = { isa = PBXGroup; children = ( - 23BA3E251A38EB1500C5AD4B /* model */, - 236ACA291A44BEFB003D1F53 /* controllers */, - 88A759A01A2F7B070005B04C /* MainViewModel.swift */, + 2333C0A01A51A0EC00784BEA /* View Model */, + 23BA3E251A38EB1500C5AD4B /* Core Data Model */, + 236ACA291A44BEFB003D1F53 /* Controllers */, 887A2CC41A0BDB4500094E3C /* AppDelegate.swift */, 23C120CD1A4340F8004D7B5E /* MockedData.swift */, 88A759AB1A2F9D4D0005B04C /* EyeControllable.swift */, - 885ABDE41A13E1DD00552B16 /* MyPlayground.playground */, 8856809E1A374B2D005F2BB0 /* fixedMenus.plist */, 887A2CCB1A0BDB4500094E3C /* Main.storyboard */, 887A2CCE1A0BDB4500094E3C /* Images.xcassets */, - 887A2CD01A0BDB4500094E3C /* LaunchScreen.xib */, 887A2CC61A0BDB4500094E3C /* EyeTypeChat.xcdatamodeld */, 887A2CC21A0BDB4500094E3C /* Supporting Files */, ); @@ -216,6 +228,8 @@ 887A2CC21A0BDB4500094E3C /* Supporting Files */ = { isa = PBXGroup; children = ( + 885ABDE41A13E1DD00552B16 /* MyPlayground.playground */, + 887A2CD01A0BDB4500094E3C /* LaunchScreen.xib */, 88C5237B1A12933E005E0D71 /* EyeTypeChat-Bridging-Header.h */, 885680A31A376E1F005F2BB0 /* SwiftBridge.h */, 885680A41A376E47005F2BB0 /* SwiftBridge.m */, @@ -445,6 +459,7 @@ files = ( 236ACA281A44B8B2003D1F53 /* EyeControllable.swift in Sources */, 8823D7AE1A30E3D200271406 /* ConversationViewController.swift in Sources */, + 2333C0A21A51A0F900784BEA /* ChatViewModel.swift in Sources */, 232CE5361A3A3DCF00C94EE8 /* Conversation.swift in Sources */, 887A2CCA1A0BDB4500094E3C /* MainViewController.swift in Sources */, 232CE53A1A3A3E9C00C94EE8 /* Contact.swift in Sources */, @@ -456,10 +471,11 @@ 8823D7B11A30E8B500271406 /* UIViewController+EyeType.swift in Sources */, 885680A21A374BB8005F2BB0 /* FixedMenuViewController.swift in Sources */, 885680A51A376E47005F2BB0 /* SwiftBridge.m in Sources */, - 885680A71A378E55005F2BB0 /* FixedMenuViewController+Commands.swift in Sources */, + 885680A71A378E55005F2BB0 /* ConversationViewController+Commands.swift in Sources */, 8823D7B31A30F65E00271406 /* BaseMenuViewController.swift in Sources */, 23C120CE1A4340F8004D7B5E /* MockedData.swift in Sources */, 232CE5381A3A3E4D00C94EE8 /* Message.swift in Sources */, + 23FAF5451A52EDED00ADD423 /* ChatViewController.swift in Sources */, 232CE5321A3A3D6100C94EE8 /* Account.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/EyeTypeChat/Base.lproj/Main.storyboard b/EyeTypeChat/Base.lproj/Main.storyboard index 447e9af..faaa714 100644 --- a/EyeTypeChat/Base.lproj/Main.storyboard +++ b/EyeTypeChat/Base.lproj/Main.storyboard @@ -143,7 +143,7 @@ - + diff --git a/EyeTypeChat/BaseMenuViewController.swift b/EyeTypeChat/BaseMenuViewController.swift index 6024651..87cb3e2 100644 --- a/EyeTypeChat/BaseMenuViewController.swift +++ b/EyeTypeChat/BaseMenuViewController.swift @@ -34,6 +34,14 @@ class BaseMenuViewController: UITableViewController, EyeControllable { return cell! } + func chatCell() -> UITableViewCell { + var cell = tableView.dequeueReusableCellWithIdentifier(CellIdentifier) as UITableViewCell? + if cell == nil { + cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: CellIdentifier) + } + return cell! + } + func validRow(indexPath: NSIndexPath) -> NSIndexPath { if (indexPath.section >= numberOfSectionsInTableView(tableView)) { return NSIndexPath(forRow: 0, inSection: 0) diff --git a/EyeTypeChat/ChatViewController.swift b/EyeTypeChat/ChatViewController.swift new file mode 100644 index 0000000..f3b84c9 --- /dev/null +++ b/EyeTypeChat/ChatViewController.swift @@ -0,0 +1,94 @@ +// +// ChatViewController.swift +// EyeTypeChat +// +// Created by Maria Ines Casadei on 12/30/14. +// Copyright (c) 2014 SCV Soft. All rights reserved. +// + +import Foundation +import UIKit +import CoreData + +class ChatViewController: BaseMenuViewController { + + lazy var managedObjectContext : NSManagedObjectContext? = { + let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate + if let managedObjectContext = appDelegate.managedObjectContext { + return managedObjectContext + } + else { + return nil + } + }() + + var selectedConversation: Conversation? + + lazy var chatModel: ChatViewModel = ChatViewModel(currentConversation: self.selectedConversation!) + + var messageItems = [MessageItem]() + + + override func viewDidLoad() { + + let conversationList: NSSet? = MockedData.getConversationList(managedObjectContext!) + var chatItem: Conversation? = nil + for item in conversationList! { + chatItem = item as? Conversation + break + } + self.selectedConversation = chatItem + self.navigationItem.title = chatItem?.title + loadMessagesItems(forChat: self.selectedConversation!) + super.viewDidLoad() + } + + func loadMessagesItems(forChat chat: Conversation) { + // load dynamically the mocked conversations + let messages = MockedData.getMessages(managedObjectContext!, forConversation: chat) + for item in messages! { + let chatItem = MessageItem(item: item as Message) + messageItems.append(chatItem) + } + } + + override func numberOfSectionsInTableView(tableView: UITableView) -> Int { + return 1 + } + + override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + if section > 0 { + return 1 + } + return messageItems.count + } + + override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { + + let cell = self.chatCell() + var messageFrom:String + if let from = messageItems[indexPath.row].message.fromContact{ + messageFrom = "\(from.name)" + }else{ + messageFrom = "\(MockedData.getUserIdentifier(managedObjectContext!)!)" + } + + cell.textLabel?.text = messageFrom + ": " + messageItems[indexPath.row].message.text + cell.detailTextLabel?.text = MockedData.getFormattedDate(messageItems[indexPath.row].message.sentDateTime) + return cell + } + + override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { + // Do nothing + } + + class MessageItem { + + var message: Message + + init (item: Message) { + message = item + } + } + +} diff --git a/EyeTypeChat/ChatViewModel.swift b/EyeTypeChat/ChatViewModel.swift new file mode 100644 index 0000000..eadad1b --- /dev/null +++ b/EyeTypeChat/ChatViewModel.swift @@ -0,0 +1,47 @@ +// +// ChatViewModel.swift +// EyeTypeChat +// +// Created by Maria Ines Casadei on 12/29/14. +// Copyright (c) 2014 SCV Soft. All rights reserved. +// + +import Foundation + +class ChatViewModel { + + var currentConversation: Conversation + var currentMessageStatus: MessageStatus + var currentWritingText: String { + get { + return self.currentWritingText + } + set(text) { + if(self.currentMessageStatus==MessageStatus.InProgress){ + return + } + if(text.isEmpty){ + self.currentMessageStatus = MessageStatus.Empty + } + else{ + self.currentMessageStatus = MessageStatus.Ok + } + self.currentWritingText = text + } + } + + init(currentConversation conversation: Conversation){ + self.currentConversation = conversation + self.currentMessageStatus = MessageStatus.Empty + self.currentWritingText = "" + } + + func clearWrittenText(){ + currentWritingText = "" + } + + enum MessageStatus { + case Empty, Ok, InProgress, Created + } + +} \ No newline at end of file diff --git a/EyeTypeChat/FixedMenuViewController+Commands.swift b/EyeTypeChat/ConversationViewController+Commands.swift similarity index 53% rename from EyeTypeChat/FixedMenuViewController+Commands.swift rename to EyeTypeChat/ConversationViewController+Commands.swift index c6e5017..5e815d8 100644 --- a/EyeTypeChat/FixedMenuViewController+Commands.swift +++ b/EyeTypeChat/ConversationViewController+Commands.swift @@ -10,8 +10,9 @@ import Foundation extension ConversationViewController { - func showKeyboard() { - let viewController = self.storyboard!.instantiateViewControllerWithIdentifier("keyboard") as UIViewController! + func showKeyboardForConversation(conversation: Conversation) { + let viewController: KeyboardViewController = self.storyboard!.instantiateViewControllerWithIdentifier("keyboard") as KeyboardViewController! + viewController.selectedConversation = conversation self.navigationController!.pushViewController(viewController, animated: true) } } diff --git a/EyeTypeChat/ConversationViewController.swift b/EyeTypeChat/ConversationViewController.swift index 3056a33..abf998e 100644 --- a/EyeTypeChat/ConversationViewController.swift +++ b/EyeTypeChat/ConversationViewController.swift @@ -65,17 +65,19 @@ class ConversationViewController: BaseMenuViewController { eyeDidCancel() } else { - performSelectorInObject(self, conversationItems[indexPath.row].selector) + performSelectorInObject(self, conversationItems[indexPath.row].selector, conversationItems[indexPath.row].conversation) } } class ConversationItem { var title: String var selector: Selector + var conversation: Conversation init (item: Conversation) { title = item.title - selector = Selector("showKeyboard") + selector = Selector("showKeyboardForConversation:") + conversation = item } } diff --git a/EyeTypeChat/FixedMenuViewController.swift b/EyeTypeChat/FixedMenuViewController.swift index 3872721..a231e26 100644 --- a/EyeTypeChat/FixedMenuViewController.swift +++ b/EyeTypeChat/FixedMenuViewController.swift @@ -60,7 +60,7 @@ class FixedMenuViewController: BaseMenuViewController { eyeDidCancel() } else { - performSelectorInObject(self, menuItems[indexPath.row].selector) + performSelectorInObject(self, menuItems[indexPath.row].selector, nil) } } diff --git a/EyeTypeChat/KeyboardViewController.swift b/EyeTypeChat/KeyboardViewController.swift index 3e61382..c6fdd6b 100644 --- a/EyeTypeChat/KeyboardViewController.swift +++ b/EyeTypeChat/KeyboardViewController.swift @@ -14,16 +14,18 @@ class KeyboardViewController: UIViewController, EyeControllable { @IBOutlet var cancelButton: UIButton! var keyButtons = [[UIButton]]() var selectedButton: UIButton? + var selectedConversation: Conversation? + lazy var chatModel: ChatViewModel = ChatViewModel(currentConversation: self.selectedConversation!) let margin: CGFloat = 8 var keys = [ - ["A", "b", "c", "d", "1", "2"], - ["E", "f", "g", "h", "3", "4"], - ["I", "j", "k", "l", "m", "n"], - ["O", "p", "q", "r", "s", "t"], - ["U", "v", "w", "x", "y", "z"], + ["a", "b", "c", "d", "1", "2"], + ["e", "f", "g", "h", "3", "4"], + ["i", "j", "k", "l", "m", "n"], + ["o", "p", "q", "r", "s", "t"], + ["u", "v", "w", "x", "y", "z"], ["5", "6", "7", "8", "9", "0"], - ["space", "comma", "point"] + ["space", "comma", "point", "send"] ] var showCancel = false var currentLine = 0 @@ -32,6 +34,7 @@ class KeyboardViewController: UIViewController, EyeControllable { required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder) + selectedConversation = nil } override func viewDidLoad() { @@ -39,6 +42,7 @@ class KeyboardViewController: UIViewController, EyeControllable { createKeyboard() } + func createKeyboard() { self.keyboardContainer.removeConstraints(self.keyboardContainer.constraints()) var i = 0 @@ -92,7 +96,38 @@ class KeyboardViewController: UIViewController, EyeControllable { } selectedButton!.selected = true } + + func updateWritingText(letter:String) { + var newText:String = chatModel.currentWritingText + letter + chatModel.currentWritingText = newText + NSLog("Text: '%@'", chatModel.currentWritingText) + } + func sendWrittenText() { + //TODO: display written text as a row + chatModel.currentMessageStatus = ChatViewModel.MessageStatus.InProgress + NSLog("Message: '%@'", chatModel.currentWritingText) + } + + func clearWrittenText() { + chatModel.clearWrittenText() + } + + func executeActionAccordingToKeySelection(key: String){ + switch key{ + case "send": + sendWrittenText() + case "point": + updateWritingText(".") + case "comma": + updateWritingText(",") + case "space": + updateWritingText(" ") + default: + updateWritingText(key) + + } + } // MARK: EyeControllable func eyeDidAccept() { @@ -101,11 +136,13 @@ class KeyboardViewController: UIViewController, EyeControllable { eyeDidCancel() } else { - NSLog("key '%@'", selectedButton!.titleForState(UIControlState.Normal)!) + let keySelection = selectedButton!.titleForState(UIControlState.Normal)! + NSLog("key '%@'", keySelection) currentLine = 0 currentRow = 0 lineSelected = false updateSelection() + executeActionAccordingToKeySelection(keySelection) } } else { diff --git a/EyeTypeChat/MainViewModel.swift b/EyeTypeChat/MainViewModel.swift index bd352b3..6461b47 100644 --- a/EyeTypeChat/MainViewModel.swift +++ b/EyeTypeChat/MainViewModel.swift @@ -11,6 +11,7 @@ import UIKit class MainViewModel: ETVideoSourceViewModel { var tickInterval: NSTimeInterval = 1 + var inputMessage = "" override func executeOKAction() { } diff --git a/EyeTypeChat/MockedData.swift b/EyeTypeChat/MockedData.swift index 40863e7..5def670 100644 --- a/EyeTypeChat/MockedData.swift +++ b/EyeTypeChat/MockedData.swift @@ -15,7 +15,7 @@ class MockedData { init(dataContext: NSManagedObjectContext){ // create Telegram account - var telegramAccount = TelegramAccount.createTelegramAccount("XYZ123", entity: "TelegramAccount", context: dataContext) + var telegramAccount = TelegramAccount.createTelegramAccount("Me", entity: "TelegramAccount", context: dataContext) // create contact list var contactSet = NSMutableSet() @@ -92,6 +92,16 @@ class MockedData { } + + class func getUserIdentifier(dataContext: NSManagedObjectContext) -> String?{ + let fetchRequest = NSFetchRequest(entityName: "TelegramAccount") + if let fetchResults = dataContext.executeFetchRequest(fetchRequest, error: nil) as? [TelegramAccount] { + + return fetchResults[0].userIdentifier + } + return nil + } + class func dateByAddingMinutes(value: Int, date: NSDate?) -> NSDate?{ return NSCalendar.currentCalendar().dateByAddingUnit(NSCalendarUnit.CalendarUnitMinute, value: value, toDate: date!, options: NSCalendarOptions.SearchBackwards) } @@ -105,6 +115,23 @@ class MockedData { return nil } + class func getMessages(dataContext: NSManagedObjectContext, forConversation chat: Conversation?) -> NSArray?{ + + let fetchRequest = NSFetchRequest(entityName: "TelegramAccount") + if let fetchResults = dataContext.executeFetchRequest(fetchRequest, error: nil) as? [TelegramAccount] { + + println("Chat: \(chat?.title)") + let messages = chat?.messages + var msgsArray = messages?.allObjects as [Message] + + var sortedMsgs : [Message] = msgsArray + sortedMsgs.sort({$0.sentDateTime.timeIntervalSinceNow < $1.sentDateTime.timeIntervalSinceNow}) + + return sortedMsgs + } + return nil + } + class func getContactList(dataContext: NSManagedObjectContext) -> NSSet?{ let fetchRequest = NSFetchRequest(entityName: "TelegramAccount") if let fetchResults = dataContext.executeFetchRequest(fetchRequest, error: nil) as? [TelegramAccount] { @@ -137,17 +164,16 @@ class MockedData { var sortedMsgs : [Message] = msgsArray sortedMsgs.sort({$0.sentDateTime.timeIntervalSinceNow < $1.sentDateTime.timeIntervalSinceNow}) - let dateStringFormatter = NSDateFormatter() - dateStringFormatter.dateFormat = "yyyy-MM-dd hh:mm" - + for msg in sortedMsgs{ - let sentFormattedDate = dateStringFormatter.stringFromDate(msg.sentDateTime) + let sentFormattedDate = MockedData.getFormattedDate(msg.sentDateTime) var messageDetails: String if let from = msg.fromContact{ messageDetails = "Message: \(msg.text). From: \(msg.fromContact!.name). Sent: \(sentFormattedDate)." }else{ - messageDetails = "Message: \(msg.text). From: me. Sent: \(sentFormattedDate)." + messageDetails = "Message: \(msg.text). From: \(MockedData.getUserIdentifier(dataContext)!) Sent: \(sentFormattedDate)." } + println(messageDetails) } @@ -158,6 +184,11 @@ class MockedData { } + class func getFormattedDate(dateTime: NSDate)-> String{ + let dateStringFormatter = NSDateFormatter() + dateStringFormatter.dateFormat = "hh:mm"// MM-dd-yyyy + return dateStringFormatter.stringFromDate(dateTime) + } } \ No newline at end of file diff --git a/EyeTypeChat/MyPlayground.playground/section-1.swift b/EyeTypeChat/MyPlayground.playground/section-1.swift index 6266254..2843bed 100644 --- a/EyeTypeChat/MyPlayground.playground/section-1.swift +++ b/EyeTypeChat/MyPlayground.playground/section-1.swift @@ -3,3 +3,4 @@ import UIKit var str = "Hello, playground" +str + "hey" diff --git a/EyeTypeChat/SwiftBridge.h b/EyeTypeChat/SwiftBridge.h index f0ac703..83bfe01 100644 --- a/EyeTypeChat/SwiftBridge.h +++ b/EyeTypeChat/SwiftBridge.h @@ -8,4 +8,5 @@ #import -void performSelectorInObject(id target, SEL selector); +void performSelectorInObject(id target, SEL selector, id object); + diff --git a/EyeTypeChat/SwiftBridge.m b/EyeTypeChat/SwiftBridge.m index 8dff607..1de4977 100644 --- a/EyeTypeChat/SwiftBridge.m +++ b/EyeTypeChat/SwiftBridge.m @@ -8,9 +8,9 @@ #import -void performSelectorInObject(id target, SEL selector) { +void performSelectorInObject(id target, SEL selector, id object) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" - [target performSelector:selector]; + [target performSelector:selector withObject:(id)object]; #pragma clang diagnostic pop } diff --git a/EyeTypeChat/fixedMenus.plist b/EyeTypeChat/fixedMenus.plist index 9968bb0..7111f95 100644 --- a/EyeTypeChat/fixedMenus.plist +++ b/EyeTypeChat/fixedMenus.plist @@ -8,7 +8,7 @@ title Respond selector - showKeyboard + showKeyboardForConversation: From 80fbfbe555bc66c018776e20eeeccce730452d2f Mon Sep 17 00:00:00 2001 From: Maria Ines Casadei Date: Fri, 2 Jan 2015 16:28:47 -0300 Subject: [PATCH 09/24] Changes in ChatViewController --- EyeTypeChat.xcodeproj/project.pbxproj | 4 ++ EyeTypeChat/Base.lproj/LaunchScreen.xib | 5 ++- EyeTypeChat/Base.lproj/Main.storyboard | 9 +++-- EyeTypeChat/ChatControllable.swift | 17 +++++++++ EyeTypeChat/ChatViewController.swift | 38 ++++++++++++++----- EyeTypeChat/ChatViewModel.swift | 23 +---------- .../ConversationViewController+Commands.swift | 1 + EyeTypeChat/ConversationViewController.swift | 6 +-- EyeTypeChat/KeyboardViewController.swift | 4 +- EyeTypeChat/MockedData.swift | 16 ++++---- 10 files changed, 75 insertions(+), 48 deletions(-) create mode 100644 EyeTypeChat/ChatControllable.swift diff --git a/EyeTypeChat.xcodeproj/project.pbxproj b/EyeTypeChat.xcodeproj/project.pbxproj index 52ea511..3870906 100644 --- a/EyeTypeChat.xcodeproj/project.pbxproj +++ b/EyeTypeChat.xcodeproj/project.pbxproj @@ -14,6 +14,7 @@ 232CE53A1A3A3E9C00C94EE8 /* Contact.swift in Sources */ = {isa = PBXBuildFile; fileRef = 232CE5391A3A3E9C00C94EE8 /* Contact.swift */; }; 2333C0A21A51A0F900784BEA /* ChatViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2333C0A11A51A0F900784BEA /* ChatViewModel.swift */; }; 236ACA281A44B8B2003D1F53 /* EyeControllable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88A759AB1A2F9D4D0005B04C /* EyeControllable.swift */; }; + 237E24601A56E4E90031B30A /* ChatControllable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 237E245F1A56E4E90031B30A /* ChatControllable.swift */; }; 23C120CE1A4340F8004D7B5E /* MockedData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23C120CD1A4340F8004D7B5E /* MockedData.swift */; }; 23FAF5451A52EDED00ADD423 /* ChatViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23FAF5441A52EDED00ADD423 /* ChatViewController.swift */; }; 5E9B341BA996967017148759 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A49492BC4CA902EDA58BC35 /* libPods.a */; }; @@ -72,6 +73,7 @@ 232CE5371A3A3E4D00C94EE8 /* Message.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Message.swift; path = model/Message.swift; sourceTree = ""; }; 232CE5391A3A3E9C00C94EE8 /* Contact.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Contact.swift; path = model/Contact.swift; sourceTree = ""; }; 2333C0A11A51A0F900784BEA /* ChatViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatViewModel.swift; sourceTree = ""; }; + 237E245F1A56E4E90031B30A /* ChatControllable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatControllable.swift; sourceTree = ""; }; 23C120CD1A4340F8004D7B5E /* MockedData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockedData.swift; sourceTree = ""; }; 23FAF5441A52EDED00ADD423 /* ChatViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatViewController.swift; sourceTree = ""; }; 8823D7AD1A30E3D200271406 /* ConversationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConversationViewController.swift; sourceTree = ""; }; @@ -216,6 +218,7 @@ 887A2CC41A0BDB4500094E3C /* AppDelegate.swift */, 23C120CD1A4340F8004D7B5E /* MockedData.swift */, 88A759AB1A2F9D4D0005B04C /* EyeControllable.swift */, + 237E245F1A56E4E90031B30A /* ChatControllable.swift */, 8856809E1A374B2D005F2BB0 /* fixedMenus.plist */, 887A2CCB1A0BDB4500094E3C /* Main.storyboard */, 887A2CCE1A0BDB4500094E3C /* Images.xcassets */, @@ -464,6 +467,7 @@ 887A2CCA1A0BDB4500094E3C /* MainViewController.swift in Sources */, 232CE53A1A3A3E9C00C94EE8 /* Contact.swift in Sources */, 232CE5341A3A3D9300C94EE8 /* TelegramAccount.swift in Sources */, + 237E24601A56E4E90031B30A /* ChatControllable.swift in Sources */, 88A759B11A2F9FC10005B04C /* KeyboardViewController.swift in Sources */, 887A2CC51A0BDB4500094E3C /* AppDelegate.swift in Sources */, 887A2CC81A0BDB4500094E3C /* EyeTypeChat.xcdatamodeld in Sources */, diff --git a/EyeTypeChat/Base.lproj/LaunchScreen.xib b/EyeTypeChat/Base.lproj/LaunchScreen.xib index 5b94eee..b2230be 100644 --- a/EyeTypeChat/Base.lproj/LaunchScreen.xib +++ b/EyeTypeChat/Base.lproj/LaunchScreen.xib @@ -1,7 +1,8 @@ - + - + + diff --git a/EyeTypeChat/Base.lproj/Main.storyboard b/EyeTypeChat/Base.lproj/Main.storyboard index faaa714..91567ab 100644 --- a/EyeTypeChat/Base.lproj/Main.storyboard +++ b/EyeTypeChat/Base.lproj/Main.storyboard @@ -140,10 +140,10 @@ - + - + @@ -171,7 +171,10 @@ - + + + + diff --git a/EyeTypeChat/ChatControllable.swift b/EyeTypeChat/ChatControllable.swift new file mode 100644 index 0000000..94eecfd --- /dev/null +++ b/EyeTypeChat/ChatControllable.swift @@ -0,0 +1,17 @@ +// +// ChatControllable.swift +// EyeTypeChat +// +// Created by Maria Ines Casadei on 1/2/15. +// Copyright (c) 2015 SCV Soft. All rights reserved. +// + +import Foundation + +@objc +protocol ChatControllable { + + func chatDidType() + func chatDidSend() + +} \ No newline at end of file diff --git a/EyeTypeChat/ChatViewController.swift b/EyeTypeChat/ChatViewController.swift index f3b84c9..3aa3845 100644 --- a/EyeTypeChat/ChatViewController.swift +++ b/EyeTypeChat/ChatViewController.swift @@ -10,7 +10,9 @@ import Foundation import UIKit import CoreData -class ChatViewController: BaseMenuViewController { +class ChatViewController: BaseMenuViewController, ChatControllable { + + @IBOutlet weak var writingTextField: UITextField! lazy var managedObjectContext : NSManagedObjectContext? = { let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate @@ -45,13 +47,28 @@ class ChatViewController: BaseMenuViewController { func loadMessagesItems(forChat chat: Conversation) { // load dynamically the mocked conversations - let messages = MockedData.getMessages(managedObjectContext!, forConversation: chat) + let messages = MockedData.getOrderedMessages(managedObjectContext!, forConversation: chat) for item in messages! { let chatItem = MessageItem(item: item as Message) messageItems.append(chatItem) } } + func addNewMessage(){ + MockedData.addNewMessage(managedObjectContext!, message: self.writingTextField.text, conversation: self.chatModel.currentConversation) + } + + class MessageItem { + + var message: Message + + init (item: Message) { + message = item + } + } + + // MARK: UITableViewController + override func numberOfSectionsInTableView(tableView: UITableView) -> Int { return 1 } @@ -82,13 +99,16 @@ class ChatViewController: BaseMenuViewController { // Do nothing } - class MessageItem { - - var message: Message - - init (item: Message) { - message = item - } + + // MARK: ChatControllable + + func chatDidType() { + writingTextField.text = chatModel.currentWritingText + } + + func chatDidSend() { + addNewMessage() + loadMessagesItems(forChat: self.selectedConversation!) } } diff --git a/EyeTypeChat/ChatViewModel.swift b/EyeTypeChat/ChatViewModel.swift index eadad1b..58de96b 100644 --- a/EyeTypeChat/ChatViewModel.swift +++ b/EyeTypeChat/ChatViewModel.swift @@ -11,28 +11,10 @@ import Foundation class ChatViewModel { var currentConversation: Conversation - var currentMessageStatus: MessageStatus - var currentWritingText: String { - get { - return self.currentWritingText - } - set(text) { - if(self.currentMessageStatus==MessageStatus.InProgress){ - return - } - if(text.isEmpty){ - self.currentMessageStatus = MessageStatus.Empty - } - else{ - self.currentMessageStatus = MessageStatus.Ok - } - self.currentWritingText = text - } - } + var currentWritingText: String init(currentConversation conversation: Conversation){ self.currentConversation = conversation - self.currentMessageStatus = MessageStatus.Empty self.currentWritingText = "" } @@ -40,8 +22,5 @@ class ChatViewModel { currentWritingText = "" } - enum MessageStatus { - case Empty, Ok, InProgress, Created - } } \ No newline at end of file diff --git a/EyeTypeChat/ConversationViewController+Commands.swift b/EyeTypeChat/ConversationViewController+Commands.swift index 5e815d8..2e64955 100644 --- a/EyeTypeChat/ConversationViewController+Commands.swift +++ b/EyeTypeChat/ConversationViewController+Commands.swift @@ -15,4 +15,5 @@ extension ConversationViewController { viewController.selectedConversation = conversation self.navigationController!.pushViewController(viewController, animated: true) } + } diff --git a/EyeTypeChat/ConversationViewController.swift b/EyeTypeChat/ConversationViewController.swift index abf998e..070489f 100644 --- a/EyeTypeChat/ConversationViewController.swift +++ b/EyeTypeChat/ConversationViewController.swift @@ -65,18 +65,18 @@ class ConversationViewController: BaseMenuViewController { eyeDidCancel() } else { - performSelectorInObject(self, conversationItems[indexPath.row].selector, conversationItems[indexPath.row].conversation) + performSelectorInObject(self, conversationItems[indexPath.row].selectorForKeyboard, conversationItems[indexPath.row].conversation) } } class ConversationItem { var title: String - var selector: Selector + var selectorForKeyboard: Selector var conversation: Conversation init (item: Conversation) { title = item.title - selector = Selector("showKeyboardForConversation:") + selectorForKeyboard = Selector("showKeyboardForConversation:") conversation = item } } diff --git a/EyeTypeChat/KeyboardViewController.swift b/EyeTypeChat/KeyboardViewController.swift index c6fdd6b..6aa186f 100644 --- a/EyeTypeChat/KeyboardViewController.swift +++ b/EyeTypeChat/KeyboardViewController.swift @@ -12,6 +12,7 @@ class KeyboardViewController: UIViewController, EyeControllable { @IBOutlet var keyboardContainer: UIView! @IBOutlet var cancelButton: UIButton! + var chatControllable:ChatControllable! = nil var keyButtons = [[UIButton]]() var selectedButton: UIButton? var selectedConversation: Conversation? @@ -101,12 +102,13 @@ class KeyboardViewController: UIViewController, EyeControllable { var newText:String = chatModel.currentWritingText + letter chatModel.currentWritingText = newText NSLog("Text: '%@'", chatModel.currentWritingText) +// chatControllable.chatDidType() } func sendWrittenText() { //TODO: display written text as a row - chatModel.currentMessageStatus = ChatViewModel.MessageStatus.InProgress NSLog("Message: '%@'", chatModel.currentWritingText) +// chatControllable.chatDidSend() } func clearWrittenText() { diff --git a/EyeTypeChat/MockedData.swift b/EyeTypeChat/MockedData.swift index 5def670..3b03492 100644 --- a/EyeTypeChat/MockedData.swift +++ b/EyeTypeChat/MockedData.swift @@ -115,7 +115,7 @@ class MockedData { return nil } - class func getMessages(dataContext: NSManagedObjectContext, forConversation chat: Conversation?) -> NSArray?{ + class func getOrderedMessages(dataContext: NSManagedObjectContext, forConversation chat: Conversation?) -> NSArray?{ let fetchRequest = NSFetchRequest(entityName: "TelegramAccount") if let fetchResults = dataContext.executeFetchRequest(fetchRequest, error: nil) as? [TelegramAccount] { @@ -131,14 +131,14 @@ class MockedData { } return nil } + - class func getContactList(dataContext: NSManagedObjectContext) -> NSSet?{ - let fetchRequest = NSFetchRequest(entityName: "TelegramAccount") - if let fetchResults = dataContext.executeFetchRequest(fetchRequest, error: nil) as? [TelegramAccount] { - - return fetchResults[0].contacts - } - return nil + + class func addNewMessage(dataContext: NSManagedObjectContext, message: String, conversation: Conversation){ + var currentDate: NSDate? = NSDate(); + var msg = Message.createMessage(message, sentDateTime: currentDate!, conversation: conversation, fromContact: nil, entity: "Message", context: dataContext) + + } class func printMockedData(dataContext: NSManagedObjectContext){ From 9914a2bdb15cbbd9a3be749fd750d9438fd63004 Mon Sep 17 00:00:00 2001 From: Maria Ines Casadei Date: Mon, 5 Jan 2015 10:11:31 -0300 Subject: [PATCH 10/24] Navigation between controllers --- EyeTypeChat.xcodeproj/project.pbxproj | 8 +++--- EyeTypeChat/Base.lproj/Main.storyboard | 17 +++++++++++- ... => BaseMenuViewController+Commands.swift} | 5 ++-- EyeTypeChat/ChatViewController.swift | 8 +++--- EyeTypeChat/ConversationViewController.swift | 27 ++++++------------- EyeTypeChat/MainViewController.swift | 12 ++++++--- EyeTypeChat/MockedData.swift | 8 +++--- EyeTypeChat/fixedMenus.plist | 2 +- 8 files changed, 47 insertions(+), 40 deletions(-) rename EyeTypeChat/{ConversationViewController+Commands.swift => BaseMenuViewController+Commands.swift} (72%) diff --git a/EyeTypeChat.xcodeproj/project.pbxproj b/EyeTypeChat.xcodeproj/project.pbxproj index 3870906..32e9870 100644 --- a/EyeTypeChat.xcodeproj/project.pbxproj +++ b/EyeTypeChat.xcodeproj/project.pbxproj @@ -24,7 +24,7 @@ 8856809F1A374B2D005F2BB0 /* fixedMenus.plist in Resources */ = {isa = PBXBuildFile; fileRef = 8856809E1A374B2D005F2BB0 /* fixedMenus.plist */; }; 885680A21A374BB8005F2BB0 /* FixedMenuViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 885680A11A374BB8005F2BB0 /* FixedMenuViewController.swift */; }; 885680A51A376E47005F2BB0 /* SwiftBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 885680A41A376E47005F2BB0 /* SwiftBridge.m */; }; - 885680A71A378E55005F2BB0 /* ConversationViewController+Commands.swift in Sources */ = {isa = PBXBuildFile; fileRef = 885680A61A378E55005F2BB0 /* ConversationViewController+Commands.swift */; }; + 885680A71A378E55005F2BB0 /* BaseMenuViewController+Commands.swift in Sources */ = {isa = PBXBuildFile; fileRef = 885680A61A378E55005F2BB0 /* BaseMenuViewController+Commands.swift */; }; 885D57611A25062D00912290 /* Podfile in Resources */ = {isa = PBXBuildFile; fileRef = 885D57601A25062D00912290 /* Podfile */; }; 885D576A1A2513FF00912290 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 885D57691A2513FF00912290 /* CoreLocation.framework */; }; 885D57701A25159000912290 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 885D576F1A25159000912290 /* SystemConfiguration.framework */; }; @@ -84,7 +84,7 @@ 885680A11A374BB8005F2BB0 /* FixedMenuViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FixedMenuViewController.swift; sourceTree = ""; }; 885680A31A376E1F005F2BB0 /* SwiftBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SwiftBridge.h; sourceTree = ""; }; 885680A41A376E47005F2BB0 /* SwiftBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SwiftBridge.m; sourceTree = ""; }; - 885680A61A378E55005F2BB0 /* ConversationViewController+Commands.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ConversationViewController+Commands.swift"; sourceTree = ""; }; + 885680A61A378E55005F2BB0 /* BaseMenuViewController+Commands.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BaseMenuViewController+Commands.swift"; sourceTree = ""; }; 885ABDE41A13E1DD00552B16 /* MyPlayground.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = MyPlayground.playground; sourceTree = ""; }; 885D57601A25062D00912290 /* Podfile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Podfile; sourceTree = SOURCE_ROOT; }; 885D57691A2513FF00912290 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; }; @@ -167,7 +167,7 @@ 887A2CC91A0BDB4500094E3C /* MainViewController.swift */, 8823D7B21A30F65E00271406 /* BaseMenuViewController.swift */, 885680A11A374BB8005F2BB0 /* FixedMenuViewController.swift */, - 885680A61A378E55005F2BB0 /* ConversationViewController+Commands.swift */, + 885680A61A378E55005F2BB0 /* BaseMenuViewController+Commands.swift */, 88A759B01A2F9FC10005B04C /* KeyboardViewController.swift */, 8823D7AD1A30E3D200271406 /* ConversationViewController.swift */, 8823D7B01A30E8B500271406 /* UIViewController+EyeType.swift */, @@ -475,7 +475,7 @@ 8823D7B11A30E8B500271406 /* UIViewController+EyeType.swift in Sources */, 885680A21A374BB8005F2BB0 /* FixedMenuViewController.swift in Sources */, 885680A51A376E47005F2BB0 /* SwiftBridge.m in Sources */, - 885680A71A378E55005F2BB0 /* ConversationViewController+Commands.swift in Sources */, + 885680A71A378E55005F2BB0 /* BaseMenuViewController+Commands.swift in Sources */, 8823D7B31A30F65E00271406 /* BaseMenuViewController.swift in Sources */, 23C120CE1A4340F8004D7B5E /* MockedData.swift in Sources */, 232CE5381A3A3E4D00C94EE8 /* Message.swift in Sources */, diff --git a/EyeTypeChat/Base.lproj/Main.storyboard b/EyeTypeChat/Base.lproj/Main.storyboard index 91567ab..fdc940c 100644 --- a/EyeTypeChat/Base.lproj/Main.storyboard +++ b/EyeTypeChat/Base.lproj/Main.storyboard @@ -93,7 +93,7 @@ - + @@ -326,5 +326,20 @@ + + + + + + + + + + + + + + + diff --git a/EyeTypeChat/ConversationViewController+Commands.swift b/EyeTypeChat/BaseMenuViewController+Commands.swift similarity index 72% rename from EyeTypeChat/ConversationViewController+Commands.swift rename to EyeTypeChat/BaseMenuViewController+Commands.swift index 2e64955..e6b0b96 100644 --- a/EyeTypeChat/ConversationViewController+Commands.swift +++ b/EyeTypeChat/BaseMenuViewController+Commands.swift @@ -8,11 +8,10 @@ import Foundation -extension ConversationViewController { +extension BaseMenuViewController { - func showKeyboardForConversation(conversation: Conversation) { + func showKeyboard() { let viewController: KeyboardViewController = self.storyboard!.instantiateViewControllerWithIdentifier("keyboard") as KeyboardViewController! - viewController.selectedConversation = conversation self.navigationController!.pushViewController(viewController, animated: true) } diff --git a/EyeTypeChat/ChatViewController.swift b/EyeTypeChat/ChatViewController.swift index 3aa3845..c8e0aea 100644 --- a/EyeTypeChat/ChatViewController.swift +++ b/EyeTypeChat/ChatViewController.swift @@ -33,12 +33,9 @@ class ChatViewController: BaseMenuViewController, ChatControllable { override func viewDidLoad() { - let conversationList: NSSet? = MockedData.getConversationList(managedObjectContext!) + let conversationList = MockedData.getConversationList(managedObjectContext!) var chatItem: Conversation? = nil - for item in conversationList! { - chatItem = item as? Conversation - break - } + chatItem = conversationList[0] self.selectedConversation = chatItem self.navigationItem.title = chatItem?.title loadMessagesItems(forChat: self.selectedConversation!) @@ -52,6 +49,7 @@ class ChatViewController: BaseMenuViewController, ChatControllable { let chatItem = MessageItem(item: item as Message) messageItems.append(chatItem) } + self.tableView.reloadData() } func addNewMessage(){ diff --git a/EyeTypeChat/ConversationViewController.swift b/EyeTypeChat/ConversationViewController.swift index 070489f..0e44f12 100644 --- a/EyeTypeChat/ConversationViewController.swift +++ b/EyeTypeChat/ConversationViewController.swift @@ -22,7 +22,7 @@ class ConversationViewController: BaseMenuViewController { } }() - var conversationItems = [ConversationItem]() + var conversationItems = [Conversation]() override func viewDidLoad() { loadConversationItems() @@ -31,11 +31,8 @@ class ConversationViewController: BaseMenuViewController { func loadConversationItems() { // load dynamically the mocked conversations - let conversations = MockedData.getConversationList(managedObjectContext!) - for item in conversations! { - let chatItem = ConversationItem(item: item as Conversation) - conversationItems.append(chatItem) - } + conversationItems = MockedData.getConversationList(managedObjectContext!) + } override func numberOfSectionsInTableView(tableView: UITableView) -> Int { @@ -65,20 +62,12 @@ class ConversationViewController: BaseMenuViewController { eyeDidCancel() } else { - performSelectorInObject(self, conversationItems[indexPath.row].selectorForKeyboard, conversationItems[indexPath.row].conversation) - } - } - - class ConversationItem { - var title: String - var selectorForKeyboard: Selector - var conversation: Conversation - - init (item: Conversation) { - title = item.title - selectorForKeyboard = Selector("showKeyboardForConversation:") - conversation = item + self.mainViewController?.selectConversation(conversationItems[indexPath.row]) + let vc = storyboard!.instantiateViewControllerWithIdentifier("fixedMenu") as FixedMenuViewController + vc.menuName = "conversation" + navigationController?.pushViewController(vc, animated: true) } } + } diff --git a/EyeTypeChat/MainViewController.swift b/EyeTypeChat/MainViewController.swift index fd76dc7..548d061 100644 --- a/EyeTypeChat/MainViewController.swift +++ b/EyeTypeChat/MainViewController.swift @@ -13,7 +13,7 @@ class MainViewController: ETVideoSourceViewController { var timer: NSTimer? var subNavigationController: UINavigationController! - var conversationNavigationController: UINavigationController! + var chatNavigationController: UINavigationController! var ignoreNextTick = false lazy var managedObjectContext : NSManagedObjectContext? = { @@ -96,14 +96,20 @@ class MainViewController: ETVideoSourceViewController { else { ignoreNextTick = false } + } + func selectConversation(chat: Conversation){ + let c = self.chatNavigationController.topViewController as ChatViewController + c.loadMessagesItems(forChat: chat) + } + override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if (segue.identifier == "subNavigationController") { subNavigationController = segue.destinationViewController as UINavigationController } - else if (segue.identifier == "conversation") { - conversationNavigationController = segue.destinationViewController as UINavigationController + else if (segue.identifier == "chatSegue") { + chatNavigationController = segue.destinationViewController as UINavigationController } } diff --git a/EyeTypeChat/MockedData.swift b/EyeTypeChat/MockedData.swift index 3b03492..7ad6d74 100644 --- a/EyeTypeChat/MockedData.swift +++ b/EyeTypeChat/MockedData.swift @@ -106,13 +106,13 @@ class MockedData { return NSCalendar.currentCalendar().dateByAddingUnit(NSCalendarUnit.CalendarUnitMinute, value: value, toDate: date!, options: NSCalendarOptions.SearchBackwards) } - class func getConversationList(dataContext: NSManagedObjectContext) -> NSSet?{ + class func getConversationList(dataContext: NSManagedObjectContext) -> [Conversation]{ let fetchRequest = NSFetchRequest(entityName: "TelegramAccount") if let fetchResults = dataContext.executeFetchRequest(fetchRequest, error: nil) as? [TelegramAccount] { - - return fetchResults[0].conversations + // TODO: order by date + return fetchResults[0].conversations!.allObjects as [Conversation] } - return nil + return [] } class func getOrderedMessages(dataContext: NSManagedObjectContext, forConversation chat: Conversation?) -> NSArray?{ diff --git a/EyeTypeChat/fixedMenus.plist b/EyeTypeChat/fixedMenus.plist index 7111f95..9968bb0 100644 --- a/EyeTypeChat/fixedMenus.plist +++ b/EyeTypeChat/fixedMenus.plist @@ -8,7 +8,7 @@ title Respond selector - showKeyboardForConversation: + showKeyboard From 7be650e190b0816cb0bd9c19f81b6a4e35f92b37 Mon Sep 17 00:00:00 2001 From: Maria Ines Casadei Date: Mon, 5 Jan 2015 15:29:02 -0300 Subject: [PATCH 11/24] Type, send and clear a message --- EyeTypeChat.xcodeproj/project.pbxproj | 8 ++++---- EyeTypeChat/Base.lproj/Main.storyboard | 4 ++-- .../BaseMenuViewController+Commands.swift | 1 + EyeTypeChat/ChatControllable.swift | 3 ++- EyeTypeChat/ChatViewController.swift | 20 ++++++++++++++----- ...t => ConversationListViewController.swift} | 2 +- EyeTypeChat/KeyboardViewController.swift | 18 ++++++----------- EyeTypeChat/MainViewController.swift | 19 +++++++++++++++++- EyeTypeChat/MockedData.swift | 12 ++++++----- 9 files changed, 56 insertions(+), 31 deletions(-) rename EyeTypeChat/{ConversationViewController.swift => ConversationListViewController.swift} (97%) diff --git a/EyeTypeChat.xcodeproj/project.pbxproj b/EyeTypeChat.xcodeproj/project.pbxproj index 32e9870..1fb4954 100644 --- a/EyeTypeChat.xcodeproj/project.pbxproj +++ b/EyeTypeChat.xcodeproj/project.pbxproj @@ -18,7 +18,7 @@ 23C120CE1A4340F8004D7B5E /* MockedData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23C120CD1A4340F8004D7B5E /* MockedData.swift */; }; 23FAF5451A52EDED00ADD423 /* ChatViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23FAF5441A52EDED00ADD423 /* ChatViewController.swift */; }; 5E9B341BA996967017148759 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A49492BC4CA902EDA58BC35 /* libPods.a */; }; - 8823D7AE1A30E3D200271406 /* ConversationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8823D7AD1A30E3D200271406 /* ConversationViewController.swift */; }; + 8823D7AE1A30E3D200271406 /* ConversationListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8823D7AD1A30E3D200271406 /* ConversationListViewController.swift */; }; 8823D7B11A30E8B500271406 /* UIViewController+EyeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8823D7B01A30E8B500271406 /* UIViewController+EyeType.swift */; }; 8823D7B31A30F65E00271406 /* BaseMenuViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8823D7B21A30F65E00271406 /* BaseMenuViewController.swift */; }; 8856809F1A374B2D005F2BB0 /* fixedMenus.plist in Resources */ = {isa = PBXBuildFile; fileRef = 8856809E1A374B2D005F2BB0 /* fixedMenus.plist */; }; @@ -76,7 +76,7 @@ 237E245F1A56E4E90031B30A /* ChatControllable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatControllable.swift; sourceTree = ""; }; 23C120CD1A4340F8004D7B5E /* MockedData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockedData.swift; sourceTree = ""; }; 23FAF5441A52EDED00ADD423 /* ChatViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatViewController.swift; sourceTree = ""; }; - 8823D7AD1A30E3D200271406 /* ConversationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConversationViewController.swift; sourceTree = ""; }; + 8823D7AD1A30E3D200271406 /* ConversationListViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConversationListViewController.swift; sourceTree = ""; }; 8823D7B01A30E8B500271406 /* UIViewController+EyeType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+EyeType.swift"; sourceTree = ""; }; 8823D7B21A30F65E00271406 /* BaseMenuViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseMenuViewController.swift; sourceTree = ""; }; 883793181A278BDB00AA856D /* libstdc++.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libstdc++.dylib"; path = "usr/lib/libstdc++.dylib"; sourceTree = SDKROOT; }; @@ -169,7 +169,7 @@ 885680A11A374BB8005F2BB0 /* FixedMenuViewController.swift */, 885680A61A378E55005F2BB0 /* BaseMenuViewController+Commands.swift */, 88A759B01A2F9FC10005B04C /* KeyboardViewController.swift */, - 8823D7AD1A30E3D200271406 /* ConversationViewController.swift */, + 8823D7AD1A30E3D200271406 /* ConversationListViewController.swift */, 8823D7B01A30E8B500271406 /* UIViewController+EyeType.swift */, 23FAF5441A52EDED00ADD423 /* ChatViewController.swift */, ); @@ -461,7 +461,7 @@ buildActionMask = 2147483647; files = ( 236ACA281A44B8B2003D1F53 /* EyeControllable.swift in Sources */, - 8823D7AE1A30E3D200271406 /* ConversationViewController.swift in Sources */, + 8823D7AE1A30E3D200271406 /* ConversationListViewController.swift in Sources */, 2333C0A21A51A0F900784BEA /* ChatViewModel.swift in Sources */, 232CE5361A3A3DCF00C94EE8 /* Conversation.swift in Sources */, 887A2CCA1A0BDB4500094E3C /* MainViewController.swift in Sources */, diff --git a/EyeTypeChat/Base.lproj/Main.storyboard b/EyeTypeChat/Base.lproj/Main.storyboard index fdc940c..6966d42 100644 --- a/EyeTypeChat/Base.lproj/Main.storyboard +++ b/EyeTypeChat/Base.lproj/Main.storyboard @@ -215,10 +215,10 @@ - + - + diff --git a/EyeTypeChat/BaseMenuViewController+Commands.swift b/EyeTypeChat/BaseMenuViewController+Commands.swift index e6b0b96..7e62037 100644 --- a/EyeTypeChat/BaseMenuViewController+Commands.swift +++ b/EyeTypeChat/BaseMenuViewController+Commands.swift @@ -12,6 +12,7 @@ extension BaseMenuViewController { func showKeyboard() { let viewController: KeyboardViewController = self.storyboard!.instantiateViewControllerWithIdentifier("keyboard") as KeyboardViewController! + viewController.chatControllable = mainViewController? self.navigationController!.pushViewController(viewController, animated: true) } diff --git a/EyeTypeChat/ChatControllable.swift b/EyeTypeChat/ChatControllable.swift index 94eecfd..606141c 100644 --- a/EyeTypeChat/ChatControllable.swift +++ b/EyeTypeChat/ChatControllable.swift @@ -11,7 +11,8 @@ import Foundation @objc protocol ChatControllable { - func chatDidType() + func chatDidType(letter: String) func chatDidSend() + func chatDidClearAll() } \ No newline at end of file diff --git a/EyeTypeChat/ChatViewController.swift b/EyeTypeChat/ChatViewController.swift index c8e0aea..7c61418 100644 --- a/EyeTypeChat/ChatViewController.swift +++ b/EyeTypeChat/ChatViewController.swift @@ -10,7 +10,7 @@ import Foundation import UIKit import CoreData -class ChatViewController: BaseMenuViewController, ChatControllable { +class ChatViewController: BaseMenuViewController { @IBOutlet weak var writingTextField: UITextField! @@ -32,7 +32,6 @@ class ChatViewController: BaseMenuViewController, ChatControllable { override func viewDidLoad() { - let conversationList = MockedData.getConversationList(managedObjectContext!) var chatItem: Conversation? = nil chatItem = conversationList[0] @@ -43,6 +42,9 @@ class ChatViewController: BaseMenuViewController, ChatControllable { } func loadMessagesItems(forChat chat: Conversation) { + messageItems.removeAll(keepCapacity: true) + chatModel = ChatViewModel(currentConversation: chat) + self.selectedConversation = chatModel.currentConversation // load dynamically the mocked conversations let messages = MockedData.getOrderedMessages(managedObjectContext!, forConversation: chat) for item in messages! { @@ -98,15 +100,23 @@ class ChatViewController: BaseMenuViewController, ChatControllable { } - // MARK: ChatControllable + // MARK: Chat - func chatDidType() { + func type(letter: String) { + chatModel.currentWritingText = chatModel.currentWritingText + letter writingTextField.text = chatModel.currentWritingText } - func chatDidSend() { + func sendMessage() { addNewMessage() loadMessagesItems(forChat: self.selectedConversation!) + clearCurrentText() } + func clearCurrentText(){ + chatModel.currentWritingText = "" + writingTextField.text = chatModel.currentWritingText + } + + } diff --git a/EyeTypeChat/ConversationViewController.swift b/EyeTypeChat/ConversationListViewController.swift similarity index 97% rename from EyeTypeChat/ConversationViewController.swift rename to EyeTypeChat/ConversationListViewController.swift index 0e44f12..23a2f2e 100644 --- a/EyeTypeChat/ConversationViewController.swift +++ b/EyeTypeChat/ConversationListViewController.swift @@ -10,7 +10,7 @@ import UIKit import Foundation import CoreData -class ConversationViewController: BaseMenuViewController { +class ConversationListViewController: BaseMenuViewController { lazy var managedObjectContext : NSManagedObjectContext? = { let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate diff --git a/EyeTypeChat/KeyboardViewController.swift b/EyeTypeChat/KeyboardViewController.swift index 6aa186f..3d325fb 100644 --- a/EyeTypeChat/KeyboardViewController.swift +++ b/EyeTypeChat/KeyboardViewController.swift @@ -15,8 +15,6 @@ class KeyboardViewController: UIViewController, EyeControllable { var chatControllable:ChatControllable! = nil var keyButtons = [[UIButton]]() var selectedButton: UIButton? - var selectedConversation: Conversation? - lazy var chatModel: ChatViewModel = ChatViewModel(currentConversation: self.selectedConversation!) let margin: CGFloat = 8 var keys = [ @@ -26,7 +24,7 @@ class KeyboardViewController: UIViewController, EyeControllable { ["o", "p", "q", "r", "s", "t"], ["u", "v", "w", "x", "y", "z"], ["5", "6", "7", "8", "9", "0"], - ["space", "comma", "point", "send"] + ["space", "comma", "point", "clear", "send"] ] var showCancel = false var currentLine = 0 @@ -35,7 +33,6 @@ class KeyboardViewController: UIViewController, EyeControllable { required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder) - selectedConversation = nil } override func viewDidLoad() { @@ -99,26 +96,23 @@ class KeyboardViewController: UIViewController, EyeControllable { } func updateWritingText(letter:String) { - var newText:String = chatModel.currentWritingText + letter - chatModel.currentWritingText = newText - NSLog("Text: '%@'", chatModel.currentWritingText) -// chatControllable.chatDidType() + chatControllable.chatDidType(letter) } func sendWrittenText() { - //TODO: display written text as a row - NSLog("Message: '%@'", chatModel.currentWritingText) -// chatControllable.chatDidSend() + chatControllable.chatDidSend() } func clearWrittenText() { - chatModel.clearWrittenText() + chatControllable.chatDidClearAll() } func executeActionAccordingToKeySelection(key: String){ switch key{ case "send": sendWrittenText() + case "clear": + clearWrittenText() case "point": updateWritingText(".") case "comma": diff --git a/EyeTypeChat/MainViewController.swift b/EyeTypeChat/MainViewController.swift index 548d061..3b731a4 100644 --- a/EyeTypeChat/MainViewController.swift +++ b/EyeTypeChat/MainViewController.swift @@ -9,7 +9,7 @@ import UIKit import CoreData -class MainViewController: ETVideoSourceViewController { +class MainViewController: ETVideoSourceViewController , ChatControllable { var timer: NSTimer? var subNavigationController: UINavigationController! @@ -118,5 +118,22 @@ class MainViewController: ETVideoSourceViewController { return self } } + + // MARK: ChatControllable + + func chatDidType(letter: String) { + let c = self.chatNavigationController.topViewController as ChatViewController + c.type(letter) + } + + func chatDidSend() { + let c = self.chatNavigationController.topViewController as ChatViewController + c.sendMessage() + } + + func chatDidClearAll() { + let c = self.chatNavigationController.topViewController as ChatViewController + c.clearCurrentText() + } } diff --git a/EyeTypeChat/MockedData.swift b/EyeTypeChat/MockedData.swift index 7ad6d74..941ee7e 100644 --- a/EyeTypeChat/MockedData.swift +++ b/EyeTypeChat/MockedData.swift @@ -34,21 +34,22 @@ class MockedData { // create some messages for bff chat var currentDate: NSDate? = NSDate(); + currentDate = MockedData.dateByAddingMinutes(-30, date: currentDate) var msg01 = Message.createMessage("Hi Mary!", sentDateTime: currentDate!, conversation: bffConversation, fromContact: nil, entity: "Message", context: dataContext) currentDate = MockedData.dateByAddingMinutes(1, date: currentDate) var msg02 = Message.createMessage("How are you?", sentDateTime: currentDate!, conversation: bffConversation, fromContact: nil, entity: "Message", context: dataContext) - currentDate = MockedData.dateByAddingMinutes(1, date: currentDate) + currentDate = MockedData.dateByAddingMinutes(2, date: currentDate) var msg03 = Message.createMessage("Great! and u?", sentDateTime: currentDate!, conversation: bffConversation, fromContact: firstContact, entity: "Message", context: dataContext) - currentDate = MockedData.dateByAddingMinutes(2, date: currentDate) + currentDate = MockedData.dateByAddingMinutes(1, date: currentDate) var msg04 = Message.createMessage("How was San Francisco?", sentDateTime: currentDate!, conversation: bffConversation, fromContact: firstContact, entity: "Message", context: dataContext) currentDate = MockedData.dateByAddingMinutes(1, date: currentDate) var msg05 = Message.createMessage("Fantastic! See u tomorrow?", sentDateTime: currentDate!, conversation: bffConversation, fromContact: nil, entity: "Message", context:dataContext) - currentDate = MockedData.dateByAddingMinutes(3, date: currentDate) + currentDate = MockedData.dateByAddingMinutes(2, date: currentDate) var msg06 = Message.createMessage("Sure :)", sentDateTime: currentDate!, conversation: bffConversation, fromContact: firstContact, entity: "Message", context: dataContext) var messages = NSMutableSet() @@ -62,12 +63,13 @@ class MockedData { var groupConversation = Conversation.createConversation("Trip to NY", account: telegramAccount, betweenContacts: contactsInGroupChat, messages: nil, entity: "Conversation", context: dataContext) // create some messages for group chat + currentDate = MockedData.dateByAddingMinutes(-15, date: NSDate()) var msg11 = Message.createMessage("Hello everyone!", sentDateTime: currentDate!, conversation: bffConversation, fromContact: secondContact, entity: "Message", context: dataContext) currentDate = MockedData.dateByAddingMinutes(1, date: currentDate) var msg12 = Message.createMessage("Hi!", sentDateTime: currentDate!, conversation: groupConversation, fromContact: nil, entity: "Message", context: dataContext) - currentDate = MockedData.dateByAddingMinutes(1, date: currentDate) + currentDate = MockedData.dateByAddingMinutes(0, date: currentDate) var msg13 = Message.createMessage("Any news from Tom?", sentDateTime: currentDate!, conversation: groupConversation, fromContact: secondContact, entity: "Message", context: dataContext) currentDate = MockedData.dateByAddingMinutes(2, date: currentDate) @@ -76,7 +78,7 @@ class MockedData { currentDate = MockedData.dateByAddingMinutes(1, date: currentDate) var msg15 = Message.createMessage("January 16th?", sentDateTime: currentDate!, conversation: groupConversation, fromContact: nil, entity: "Message", context:dataContext) - currentDate = MockedData.dateByAddingMinutes(3, date: currentDate) + currentDate = MockedData.dateByAddingMinutes(1, date: currentDate) var msg16 = Message.createMessage("Right", sentDateTime: currentDate!, conversation: groupConversation, fromContact: secondContact, entity: "Message", context: dataContext) var groupMessages = NSMutableSet() From a9db1353c79c7190c1a9ff6431f4717d53cc3b90 Mon Sep 17 00:00:00 2001 From: Maria Ines Casadei Date: Fri, 16 Jan 2015 15:22:33 -0300 Subject: [PATCH 12/24] Predicates and sort descriptors added --- EyeTypeChat/ChatViewController.swift | 11 +++-- EyeTypeChat/MainViewController.swift | 2 +- EyeTypeChat/MockedData.swift | 61 +++++++++++++++++----------- 3 files changed, 47 insertions(+), 27 deletions(-) diff --git a/EyeTypeChat/ChatViewController.swift b/EyeTypeChat/ChatViewController.swift index 7c61418..677ca4e 100644 --- a/EyeTypeChat/ChatViewController.swift +++ b/EyeTypeChat/ChatViewController.swift @@ -35,15 +35,20 @@ class ChatViewController: BaseMenuViewController { let conversationList = MockedData.getConversationList(managedObjectContext!) var chatItem: Conversation? = nil chatItem = conversationList[0] - self.selectedConversation = chatItem - self.navigationItem.title = chatItem?.title - loadMessagesItems(forChat: self.selectedConversation!) + loadConversation(chatItem!) super.viewDidLoad() } + func loadConversation(chat: Conversation){ + self.selectedConversation = chat + self.navigationItem.title = chat.title + loadMessagesItems(forChat: self.selectedConversation!) + } + func loadMessagesItems(forChat chat: Conversation) { messageItems.removeAll(keepCapacity: true) chatModel = ChatViewModel(currentConversation: chat) + writingTextField.text = chatModel.currentWritingText self.selectedConversation = chatModel.currentConversation // load dynamically the mocked conversations let messages = MockedData.getOrderedMessages(managedObjectContext!, forConversation: chat) diff --git a/EyeTypeChat/MainViewController.swift b/EyeTypeChat/MainViewController.swift index 3b731a4..c5725f6 100644 --- a/EyeTypeChat/MainViewController.swift +++ b/EyeTypeChat/MainViewController.swift @@ -101,7 +101,7 @@ class MainViewController: ETVideoSourceViewController , ChatControllable { func selectConversation(chat: Conversation){ let c = self.chatNavigationController.topViewController as ChatViewController - c.loadMessagesItems(forChat: chat) + c.loadConversation(chat) } override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { diff --git a/EyeTypeChat/MockedData.swift b/EyeTypeChat/MockedData.swift index 941ee7e..06ae696 100644 --- a/EyeTypeChat/MockedData.swift +++ b/EyeTypeChat/MockedData.swift @@ -63,7 +63,7 @@ class MockedData { var groupConversation = Conversation.createConversation("Trip to NY", account: telegramAccount, betweenContacts: contactsInGroupChat, messages: nil, entity: "Conversation", context: dataContext) // create some messages for group chat - currentDate = MockedData.dateByAddingMinutes(-15, date: NSDate()) + currentDate = MockedData.dateByAddingMinutes(-50, date: NSDate()) var msg11 = Message.createMessage("Hello everyone!", sentDateTime: currentDate!, conversation: bffConversation, fromContact: secondContact, entity: "Message", context: dataContext) currentDate = MockedData.dateByAddingMinutes(1, date: currentDate) @@ -76,10 +76,10 @@ class MockedData { var msg14 = Message.createMessage("He sent a confirmation email", sentDateTime: currentDate!, conversation: groupConversation, fromContact: thirdContact, entity: "Message", context: dataContext) currentDate = MockedData.dateByAddingMinutes(1, date: currentDate) - var msg15 = Message.createMessage("January 16th?", sentDateTime: currentDate!, conversation: groupConversation, fromContact: nil, entity: "Message", context:dataContext) + var msg15 = Message.createMessage("The plane arrives to NY at 10pm", sentDateTime: currentDate!, conversation: groupConversation, fromContact: nil, entity: "Message", context:dataContext) currentDate = MockedData.dateByAddingMinutes(1, date: currentDate) - var msg16 = Message.createMessage("Right", sentDateTime: currentDate!, conversation: groupConversation, fromContact: secondContact, entity: "Message", context: dataContext) + var msg16 = Message.createMessage("Perfect", sentDateTime: currentDate!, conversation: groupConversation, fromContact: secondContact, entity: "Message", context: dataContext) var groupMessages = NSMutableSet() groupMessages.addObjectsFromArray([msg11, msg12, msg13, msg14, msg15, msg16]) @@ -109,38 +109,53 @@ class MockedData { } class func getConversationList(dataContext: NSManagedObjectContext) -> [Conversation]{ - let fetchRequest = NSFetchRequest(entityName: "TelegramAccount") - if let fetchResults = dataContext.executeFetchRequest(fetchRequest, error: nil) as? [TelegramAccount] { - // TODO: order by date - return fetchResults[0].conversations!.allObjects as [Conversation] + let fetchRequest = NSFetchRequest(entityName: "Conversation") + if let fetchResults = dataContext.executeFetchRequest(fetchRequest, error: nil) as? [Conversation] + { + var lastMessageInConversations = NSMutableSet() + for conversation in fetchResults{ + if let lastMessage = MockedData.getLastMessage(dataContext, forConversation: conversation){ + lastMessageInConversations.addObject(lastMessage) + } + } + var orderedConversations = NSMutableSet() + for sms in lastMessageInConversations { + let msg = sms as Message + var chat = msg.conversation as Conversation + println(chat.title) + orderedConversations.addObject(chat) + } + return orderedConversations.allObjects as [Conversation] } - return [] + + return [] + } + + + class func getLastMessage(dataContext: NSManagedObjectContext, forConversation chat: Conversation?) -> Message?{ + let orderedMsgs = MockedData.getOrderedMessages(dataContext, forConversation: chat) + return orderedMsgs?.lastObject as Message? + } class func getOrderedMessages(dataContext: NSManagedObjectContext, forConversation chat: Conversation?) -> NSArray?{ - let fetchRequest = NSFetchRequest(entityName: "TelegramAccount") - if let fetchResults = dataContext.executeFetchRequest(fetchRequest, error: nil) as? [TelegramAccount] { - - println("Chat: \(chat?.title)") - let messages = chat?.messages - var msgsArray = messages?.allObjects as [Message] - - var sortedMsgs : [Message] = msgsArray - sortedMsgs.sort({$0.sentDateTime.timeIntervalSinceNow < $1.sentDateTime.timeIntervalSinceNow}) - - return sortedMsgs + let fetchRequest = NSFetchRequest(entityName: "Message") + var chatText = chat!.title + let chatPredicate = NSPredicate(format: "SELF.conversation.title = %@", chatText) + fetchRequest.predicate = chatPredicate + var dateDescriptor = NSSortDescriptor(key: "sentDateTime", ascending: true) + fetchRequest.sortDescriptors = [dateDescriptor] + if let fetchResults = dataContext.executeFetchRequest(fetchRequest, error: nil) as? [Message] + { + return fetchResults } return nil } - - class func addNewMessage(dataContext: NSManagedObjectContext, message: String, conversation: Conversation){ var currentDate: NSDate? = NSDate(); var msg = Message.createMessage(message, sentDateTime: currentDate!, conversation: conversation, fromContact: nil, entity: "Message", context: dataContext) - - } class func printMockedData(dataContext: NSManagedObjectContext){ From 32839598ba830885a8b0b4677fb09f33df9d3d11 Mon Sep 17 00:00:00 2001 From: Maria Ines Casadei Date: Tue, 20 Jan 2015 10:52:29 -0300 Subject: [PATCH 13/24] Ordered chats --- EyeTypeChat/ChatViewController.swift | 12 ++++++---- .../ConversationListViewController.swift | 10 ++++++-- EyeTypeChat/MockedData.swift | 24 +++++++++---------- 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/EyeTypeChat/ChatViewController.swift b/EyeTypeChat/ChatViewController.swift index 677ca4e..f3935ea 100644 --- a/EyeTypeChat/ChatViewController.swift +++ b/EyeTypeChat/ChatViewController.swift @@ -32,13 +32,15 @@ class ChatViewController: BaseMenuViewController { override func viewDidLoad() { - let conversationList = MockedData.getConversationList(managedObjectContext!) - var chatItem: Conversation? = nil - chatItem = conversationList[0] - loadConversation(chatItem!) + loadConversations() super.viewDidLoad() } + func loadConversations(){ + let conversationList = MockedData.getConversationList(managedObjectContext!) + loadConversation(conversationList[0] as Conversation) + } + func loadConversation(chat: Conversation){ self.selectedConversation = chat self.navigationItem.title = chat.title @@ -114,7 +116,7 @@ class ChatViewController: BaseMenuViewController { func sendMessage() { addNewMessage() - loadMessagesItems(forChat: self.selectedConversation!) + loadConversations() clearCurrentText() } diff --git a/EyeTypeChat/ConversationListViewController.swift b/EyeTypeChat/ConversationListViewController.swift index 23a2f2e..c2134e3 100644 --- a/EyeTypeChat/ConversationListViewController.swift +++ b/EyeTypeChat/ConversationListViewController.swift @@ -22,13 +22,19 @@ class ConversationListViewController: BaseMenuViewController { } }() - var conversationItems = [Conversation]() + var conversationItems = NSOrderedSet() override func viewDidLoad() { loadConversationItems() super.viewDidLoad() } + override func viewWillAppear(animated: Bool) { + loadConversationItems() + self.tableView.reloadData() + super.viewWillAppear(animated) + } + func loadConversationItems() { // load dynamically the mocked conversations conversationItems = MockedData.getConversationList(managedObjectContext!) @@ -62,7 +68,7 @@ class ConversationListViewController: BaseMenuViewController { eyeDidCancel() } else { - self.mainViewController?.selectConversation(conversationItems[indexPath.row]) + self.mainViewController?.selectConversation(conversationItems[indexPath.row] as Conversation) let vc = storyboard!.instantiateViewControllerWithIdentifier("fixedMenu") as FixedMenuViewController vc.menuName = "conversation" navigationController?.pushViewController(vc, animated: true) diff --git a/EyeTypeChat/MockedData.swift b/EyeTypeChat/MockedData.swift index 06ae696..92e008e 100644 --- a/EyeTypeChat/MockedData.swift +++ b/EyeTypeChat/MockedData.swift @@ -91,9 +91,7 @@ class MockedData { // associate conversation list with the Telegram account telegramAccount.conversations = conversationSet - } - class func getUserIdentifier(dataContext: NSManagedObjectContext) -> String?{ let fetchRequest = NSFetchRequest(entityName: "TelegramAccount") @@ -108,27 +106,28 @@ class MockedData { return NSCalendar.currentCalendar().dateByAddingUnit(NSCalendarUnit.CalendarUnitMinute, value: value, toDate: date!, options: NSCalendarOptions.SearchBackwards) } - class func getConversationList(dataContext: NSManagedObjectContext) -> [Conversation]{ + class func getConversationList(dataContext: NSManagedObjectContext) -> NSOrderedSet{ let fetchRequest = NSFetchRequest(entityName: "Conversation") + var orderedConversation = NSMutableOrderedSet() if let fetchResults = dataContext.executeFetchRequest(fetchRequest, error: nil) as? [Conversation] { - var lastMessageInConversations = NSMutableSet() + var lastMessageInConversations = NSMutableOrderedSet() for conversation in fetchResults{ if let lastMessage = MockedData.getLastMessage(dataContext, forConversation: conversation){ lastMessageInConversations.addObject(lastMessage) } } - var orderedConversations = NSMutableSet() - for sms in lastMessageInConversations { - let msg = sms as Message - var chat = msg.conversation as Conversation - println(chat.title) - orderedConversations.addObject(chat) + + let sortDateDescriptor = NSSortDescriptor(key: "sentDateTime", ascending: false) + lastMessageInConversations.sortUsingDescriptors([sortDateDescriptor]) + lastMessageInConversations.enumerateObjectsUsingBlock { (elem, idx, stop) -> Void in + let sms = elem as Message + let chat = sms.conversation as Conversation + orderedConversation.addObject(chat) } - return orderedConversations.allObjects as [Conversation] } - return [] + return orderedConversation } @@ -139,7 +138,6 @@ class MockedData { } class func getOrderedMessages(dataContext: NSManagedObjectContext, forConversation chat: Conversation?) -> NSArray?{ - let fetchRequest = NSFetchRequest(entityName: "Message") var chatText = chat!.title let chatPredicate = NSPredicate(format: "SELF.conversation.title = %@", chatText) From cb9986003caec3aa004ae9aa0968136a6dd1f4d2 Mon Sep 17 00:00:00 2001 From: Maria Ines Casadei Date: Thu, 22 Jan 2015 15:05:15 -0300 Subject: [PATCH 14/24] Optional chat title. Changes in chat vc --- EyeTypeChat/ChatViewController.swift | 2 ++ EyeTypeChat/MockedData.swift | 35 +++++++++++++++++++++++++--- EyeTypeChat/model/Conversation.swift | 23 +++++++++++++++--- 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/EyeTypeChat/ChatViewController.swift b/EyeTypeChat/ChatViewController.swift index f3935ea..d8945c8 100644 --- a/EyeTypeChat/ChatViewController.swift +++ b/EyeTypeChat/ChatViewController.swift @@ -99,6 +99,8 @@ class ChatViewController: BaseMenuViewController { cell.textLabel?.text = messageFrom + ": " + messageItems[indexPath.row].message.text cell.detailTextLabel?.text = MockedData.getFormattedDate(messageItems[indexPath.row].message.sentDateTime) + cell.selectionStyle = .None + cell.userInteractionEnabled = false return cell } diff --git a/EyeTypeChat/MockedData.swift b/EyeTypeChat/MockedData.swift index 92e008e..ddf68ef 100644 --- a/EyeTypeChat/MockedData.swift +++ b/EyeTypeChat/MockedData.swift @@ -30,7 +30,7 @@ class MockedData { // create bff chat var contactsInBffChat = NSMutableSet() contactsInBffChat.addObject(firstContact) - var bffConversation = Conversation.createConversation("BBF", account: telegramAccount, betweenContacts: contactsInBffChat, messages: nil, entity: "Conversation", context: dataContext) + var bffConversation = Conversation.createConversation(nil, account: telegramAccount, betweenContacts: contactsInBffChat, messages: nil, entity: "Conversation", context: dataContext) // create some messages for bff chat var currentDate: NSDate? = NSDate(); @@ -60,11 +60,11 @@ class MockedData { // create group chat var contactsInGroupChat = NSMutableSet() contactsInGroupChat.addObjectsFromArray([secondContact, thirdContact]) - var groupConversation = Conversation.createConversation("Trip to NY", account: telegramAccount, betweenContacts: contactsInGroupChat, messages: nil, entity: "Conversation", context: dataContext) + var groupConversation = Conversation.createConversation(nil, account: telegramAccount, betweenContacts: contactsInGroupChat, messages: nil, entity: "Conversation", context: dataContext) // create some messages for group chat currentDate = MockedData.dateByAddingMinutes(-50, date: NSDate()) - var msg11 = Message.createMessage("Hello everyone!", sentDateTime: currentDate!, conversation: bffConversation, fromContact: secondContact, entity: "Message", context: dataContext) + var msg11 = Message.createMessage("Hello everyone!", sentDateTime: currentDate!, conversation: groupConversation, fromContact: secondContact, entity: "Message", context: dataContext) currentDate = MockedData.dateByAddingMinutes(1, date: currentDate) var msg12 = Message.createMessage("Hi!", sentDateTime: currentDate!, conversation: groupConversation, fromContact: nil, entity: "Message", context: dataContext) @@ -86,6 +86,35 @@ class MockedData { groupConversation.messages = groupMessages conversationSet.addObject(groupConversation) + // create multiple group chat + var contactsInMultipleGroupChat = NSMutableSet() + contactsInMultipleGroupChat.addObjectsFromArray([firstContact, secondContact, thirdContact]) + var multipleGroupConversation = Conversation.createConversation(nil, account: telegramAccount, betweenContacts: contactsInMultipleGroupChat, messages: nil, entity: "Conversation", context: dataContext) + + // create some messages for multiple group chat + currentDate = MockedData.dateByAddingMinutes(-50, date: NSDate()) + var msg17 = Message.createMessage("1, 2, 3", sentDateTime: currentDate!, conversation: multipleGroupConversation, fromContact: secondContact, entity: "Message", context: dataContext) + + currentDate = MockedData.dateByAddingMinutes(1, date: currentDate) + var msg18 = Message.createMessage("4", sentDateTime: currentDate!, conversation: multipleGroupConversation, fromContact: firstContact, entity: "Message", context: dataContext) + + currentDate = MockedData.dateByAddingMinutes(0, date: currentDate) + var msg19 = Message.createMessage("5", sentDateTime: currentDate!, conversation: multipleGroupConversation, fromContact: secondContact, entity: "Message", context: dataContext) + + currentDate = MockedData.dateByAddingMinutes(2, date: currentDate) + var msg20 = Message.createMessage("6, 7, 7, 7", sentDateTime: currentDate!, conversation: multipleGroupConversation, fromContact: thirdContact, entity: "Message", context: dataContext) + + currentDate = MockedData.dateByAddingMinutes(1, date: currentDate) + var msg21 = Message.createMessage("blah blah 8", sentDateTime: currentDate!, conversation: multipleGroupConversation, fromContact: nil, entity: "Message", context:dataContext) + + currentDate = MockedData.dateByAddingMinutes(1, date: currentDate) + var msg22 = Message.createMessage("9Blah! ", sentDateTime: currentDate!, conversation: multipleGroupConversation, fromContact: secondContact, entity: "Message", context: dataContext) + + var multipleGroupMessages = NSMutableSet() + multipleGroupMessages.addObjectsFromArray([msg17, msg18, msg19, msg20, msg21, msg22]) + multipleGroupConversation.messages = multipleGroupMessages + conversationSet.addObject(multipleGroupConversation) + // associate contact list with the Telegram account telegramAccount.contacts = contactSet // associate conversation list with the Telegram account diff --git a/EyeTypeChat/model/Conversation.swift b/EyeTypeChat/model/Conversation.swift index 10e0c13..128853a 100644 --- a/EyeTypeChat/model/Conversation.swift +++ b/EyeTypeChat/model/Conversation.swift @@ -16,10 +16,14 @@ class Conversation: NSManagedObject { @NSManaged var betweenContacts: NSSet @NSManaged var messages: NSSet? - class func createConversation(title: String, account: Account, betweenContacts: NSSet, messages: NSSet?, entity: String, context: NSManagedObjectContext) -> Conversation{ + class func createConversation(title: String?, account: Account, betweenContacts: NSSet, messages: NSSet?, entity: String, context: NSManagedObjectContext) -> Conversation{ + var defaultTitle = "" + if title == nil{ + defaultTitle = createDefaultTitleConversationBetweenContacts(betweenContacts) + } var conversation = NSEntityDescription.insertNewObjectForEntityForName(entity, inManagedObjectContext: context) as Conversation - conversation.title = title + conversation.title = title != nil ? title! : defaultTitle conversation.account = account conversation.betweenContacts = betweenContacts; conversation.messages = messages; @@ -27,4 +31,17 @@ class Conversation: NSManagedObject { return conversation } -} + class func createDefaultTitleConversationBetweenContacts(betweenContacts: NSSet) -> NSString{ + var title = "Chat with " + for var i = 0; i Date: Fri, 23 Jan 2015 11:35:41 -0300 Subject: [PATCH 15/24] Default user image --- EyeTypeChat/ChatViewController.swift | 6 ++++- .../user_default.imageset/Contents.json | 23 ++++++++++++++++++ .../ic_account_circle_black_48dp-1.png | Bin 0 -> 756 bytes .../ic_account_circle_black_48dp-2.png | Bin 0 -> 2013 bytes .../ic_account_circle_black_48dp.png | Bin 0 -> 1395 bytes EyeTypeChat/MockedData.swift | 2 +- 6 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 EyeTypeChat/Images.xcassets/user_default.imageset/Contents.json create mode 100644 EyeTypeChat/Images.xcassets/user_default.imageset/ic_account_circle_black_48dp-1.png create mode 100644 EyeTypeChat/Images.xcassets/user_default.imageset/ic_account_circle_black_48dp-2.png create mode 100644 EyeTypeChat/Images.xcassets/user_default.imageset/ic_account_circle_black_48dp.png diff --git a/EyeTypeChat/ChatViewController.swift b/EyeTypeChat/ChatViewController.swift index d8945c8..ade2961 100644 --- a/EyeTypeChat/ChatViewController.swift +++ b/EyeTypeChat/ChatViewController.swift @@ -97,9 +97,13 @@ class ChatViewController: BaseMenuViewController { messageFrom = "\(MockedData.getUserIdentifier(managedObjectContext!)!)" } - cell.textLabel?.text = messageFrom + ": " + messageItems[indexPath.row].message.text + cell.textLabel?.text = messageFrom + ":\n" + messageItems[indexPath.row].message.text + cell.textLabel?.lineBreakMode = .ByWordWrapping + cell.textLabel?.numberOfLines = 0 cell.detailTextLabel?.text = MockedData.getFormattedDate(messageItems[indexPath.row].message.sentDateTime) + cell.detailTextLabel?.textColor = UIColor.blueColor() cell.selectionStyle = .None + cell.imageView?.image = UIImage(named: "user_default.png") cell.userInteractionEnabled = false return cell } diff --git a/EyeTypeChat/Images.xcassets/user_default.imageset/Contents.json b/EyeTypeChat/Images.xcassets/user_default.imageset/Contents.json new file mode 100644 index 0000000..b9825cd --- /dev/null +++ b/EyeTypeChat/Images.xcassets/user_default.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x", + "filename" : "ic_account_circle_black_48dp-1.png" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "ic_account_circle_black_48dp.png" + }, + { + "idiom" : "universal", + "scale" : "3x", + "filename" : "ic_account_circle_black_48dp-2.png" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/EyeTypeChat/Images.xcassets/user_default.imageset/ic_account_circle_black_48dp-1.png b/EyeTypeChat/Images.xcassets/user_default.imageset/ic_account_circle_black_48dp-1.png new file mode 100644 index 0000000000000000000000000000000000000000..dba1d58139706f5ca3d9a0adf2db30b6948375d1 GIT binary patch literal 756 zcmV004R> z004l5008;`004mK004C`008P>0026e000+ooVrmw00002VoOIv0RM-N%)bBt010qN zS#tmY3ljhU3ljkVnw%H_00L}DL_t(o!|j*LPE%17hCi{|wDAscpyCUlqCgQy^er?n zaHd2tMrT|e0FVU1Ku8lbVcw)hNF#|aL7HlevsRo?s>T~_0~`mY$~k+jbM~nwXu@98 zZ~g!2-fOMB3w!H-SPgVDLYf>Us#GbFBh4^fH2k^vStfXoqr@uXG}kYFl6k7Ccr7X< zX{ty51|I^&Yf+*vocIBrT8q~rNyJt@&T?pZ2Zs!CyRVn!H<+Z2C{fy(qO4e0{E8=H zYJnCPb)HpaqXLgs{`wY!yg)@{d;JUZqnI=)($gZlPNQxxuN+^SNOvgooZhusTSY}a zrncT`*4Dnre#Ubq>` zpx-rAPH9-ub=4Gfw*De;IPFj7Fl3{MP9Qd5KF{t zt0H1-RB+7Nef`ekUbhxs3qD$DH8K}?_d1lB@h?pOb%rqts(7AJy=%k#jqPNJ6j_Q? ms8A$Jia`?cNZVWg+WG+&@s>Z$I`L}&0000004R> z004l5008;`004mK004C`008P>0026e000+ooVrmw00002VoOIv0RM-N%)bBt010qN zS#tmY3ljhU3ljkVnw%H_00&h`L_t(|+U=eDYfxnv$3JemIVmqwyI3=k@RCL9Tyt$+ zB8U`B)X7lRLf!I$S+-($0b`*A6?j2WQS*{Bb&9JjZ@HYzONuiY1eKM#Nf_BSom01Y z`eCfhyqx!(=Y7vRcfQXb@O=56_q^|Od(VLoAwq-*5h6s05FtW@2+^Dn%TTgdKpush zqMS-PV^)-tduOA|pVhqXv^vmIhI5lv5= z7Nqfmc5xc5lvG+YC3#-tdt>4>+6jg>4RN}$!?-w&mQPo^#fju?ssod!Aq<#d?~e2& zM*nlm(13@iyrs%)r-AC+jW0)agW5oeuYfe z9w$>Ha_Ae0i(*8=!VAPJuGv2XydF0ZU9S_7r>C;t-XapM(w~w_yj<~~d_O1hqGjkU zXj~ScnCaR7RFOP4DLYBNRRo*uq9^cIPW-q2HPmWX}weDl~W zQkd0HyOt@%C;8?vNQB20`9_XR&Lz=t`&ER?VA(dHOrLA12%8lmT#ie&8qTx1$ z(uLTJk~`j|n#g@c_{0mbIVH7*QpM^rGLvGR#Q2Pq5lC)ALuNiKT8z&@2|7uF#ZTJ= za!B+~XT2aD+g>q;HGavo7o85XYm;uMGq&|dW~v|=+m3m^wFLkUh?21>P;9h)eyDU2 z?tIylYW!PYc*vF)%)#M#OOn-_Ez3KZ&&A2uQSSJ!ZSzVcN~FMg>w@m-OP;4Rw7V;5 zWy@lAaMM<%*{{9ya&fTlH^5|q zxw`Ho3N3Y!g$`Q@q$lxJ{?@E4YoPCT86CYsK~lgAaQ}hS1jD5{cY0WF&_qs z{sP7QhN#`(4Bzr8A2EyRWHE)en9V}+D59JjhFI)X7ignaLRUG=B3`3EF?VIrh5<}s z3CA?wZS;_=&ewFD7V{p1JzOej!wbykn5OU}H~50tRd$d;N8gRZ&Sdg6*Ml#Z4H0yI zge>9jMa42*^tOJo7YY)Nuki`}(1ip(qb{hTJ(T$tXEBeV8{JsxTck7IT>EPrZlxQh z(A(#jg~!HWj*qzXWlUo%7fiRFQ#?P9_5^`W>@hp*8s+JWK<^VAB3a~taRn{CI#l0< z-XUnH_w(|-JDZ~D>SJucN=4R_yt{f-DX>4{eW{9~wbJFAIy(DtR;ZAb_rn$>D+sj5 zpR38P9essOIAY=j18C>^DsQ?~0=Z4KFY$n1S8H9mvg_N0{avzN?cdcvm#(6%5~!U^ z)(H~M4!LqQ(<*_oU2!gwaW=+fLF`#;Kb< zF$Qg!M};znG6Rk9f67r_E{y-l2Lj*Y?aGJz z<-vQE*=oaZj}tnz6fl<7o_xlT#+M!k6|V7;>9}>QkC}=p@|mCz&Big2?LPkeQY-gC zHx;D&9y>Y5X67=QK6JQE@b@%hn9CN<`5yZlA5?OfDmV&vm2yr~N-3u)7rexKEtu8Q zh+!JO?;&Yb=J%fepJ?Z;m8Z;(I(eLO=xD}{nu~kx9bK=sPM+nq{na-^Dbv?$75Yp#!8B9S$k{)2d#)iU!v!J{pi>=U||(~zIs(X9(pS*i00000NkvXXu0mjfAEm%e literal 0 HcmV?d00001 diff --git a/EyeTypeChat/Images.xcassets/user_default.imageset/ic_account_circle_black_48dp.png b/EyeTypeChat/Images.xcassets/user_default.imageset/ic_account_circle_black_48dp.png new file mode 100644 index 0000000000000000000000000000000000000000..94ede996d36b82835205f740ae3e1add04758a17 GIT binary patch literal 1395 zcmV-(1&sQMP)004R> z004l5008;`004mK004C`008P>0026e000+ooVrmw00002VoOIv0RM-N%)bBt010qN zS#tmY3ljhU3ljkVnw%H_00iqvL_t(|+U=WPOx9%-$3MO_kiU@&OkhpRTGmB5b28VB z7X-wdn`4=pZe5$qx!1yJtt%{N%f=$&MOaN^Id3!PA8f5uTwYjXBgX(mT?{Prl|L)k zuM1Q5ZMOI& zpUF4g$WM7Q^Zk9Ke)Ud2Am9RpKIlImvSCWRhi6^We~CYnMn53nCd=IZ`cnG6)KNwe z>7-Lc8T;rHr?Au&{YAp!>0`qT5+TAyt_cgN&`sx&y}CyfGA)NT5mtwbj`X!C2M+js*m)GlOroJVm`_oWR?b5gN_ldo1Cv8uscuu3JXJu28(+Ldd6BwV<35@6yn4HrIOgsV!JoF{> z(7(iP+Gw21oZv7qVjSiKzi~HNZL~cE{4n3Mmr9CfL@wqHKHvv#hlp@WpFoQh@D=J< zO`4IMevH@nm~N{$P42~9oG)2vHM(3ylen;=Zsqh4wd98y-!EW~XoO}knOJDtkq_{= zlPjzzIB5L!DKG&vsm^X*b$Sb0O0TOUCB(EqKeNF3J#+!*wQ(EFpw??(E_vGU$>*{r z@>*g>K#bQ97 z*97tv_xAH7KsyrxZS$JI_Jnb3WI(yxO864L?2Z0%#u7vwl<%4DR@{{oc%fgY7`;U0 za9N5m)J5r)o6$4Bq!=4#+CXknbcCNAr;x`lifC`z!k$!sUUazGrryRoZV$Xzd3x&Q z6({spD94V&JRJsHy)QAwHd%L`VccG$nS+Gh=slznSZ8=4g!cJSgZ@?c2Rxq+O^|=6 zXOS4Um@oKOgM3bSeV(vC>u=4*XlA*f>RSy4Xx%*Ns!J^8rqO}#cRpl=;<`1Bm3%~} z5!Q_`n_AOtnPCd|mc-hr=Uu8$l2K0{8( z4-&Q0`{6Bz9U+@*4>hy>r^E>5v{~H0#5qD)NG&!T_C|qKPQwo(2LbOIgZNma<3G{sXt Date: Fri, 23 Jan 2015 12:57:09 -0300 Subject: [PATCH 16/24] Date info --- EyeTypeChat/MockedData.swift | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/EyeTypeChat/MockedData.swift b/EyeTypeChat/MockedData.swift index b6fe9d6..5118255 100644 --- a/EyeTypeChat/MockedData.swift +++ b/EyeTypeChat/MockedData.swift @@ -34,10 +34,10 @@ class MockedData { // create some messages for bff chat var currentDate: NSDate? = NSDate(); - currentDate = MockedData.dateByAddingMinutes(-30, date: currentDate) - var msg01 = Message.createMessage("Hi Mary!", sentDateTime: currentDate!, conversation: bffConversation, fromContact: nil, entity: "Message", context: dataContext) + let yesterdayDate: NSDate? = NSCalendar.currentCalendar().dateByAddingUnit(.CalendarUnitDay, value: -1, toDate: NSDate(), options: nil) + var msg01 = Message.createMessage("Hi Mary!", sentDateTime: yesterdayDate!, conversation: bffConversation, fromContact: nil, entity: "Message", context: dataContext) - currentDate = MockedData.dateByAddingMinutes(1, date: currentDate) + currentDate = MockedData.dateByAddingMinutes(-30, date: currentDate) var msg02 = Message.createMessage("How are you?", sentDateTime: currentDate!, conversation: bffConversation, fromContact: nil, entity: "Message", context: dataContext) currentDate = MockedData.dateByAddingMinutes(2, date: currentDate) @@ -173,11 +173,7 @@ class MockedData { fetchRequest.predicate = chatPredicate var dateDescriptor = NSSortDescriptor(key: "sentDateTime", ascending: true) fetchRequest.sortDescriptors = [dateDescriptor] - if let fetchResults = dataContext.executeFetchRequest(fetchRequest, error: nil) as? [Message] - { - return fetchResults - } - return nil + return dataContext.executeFetchRequest(fetchRequest, error: nil) as? [Message] } class func addNewMessage(dataContext: NSManagedObjectContext, message: String, conversation: Conversation){ @@ -230,9 +226,24 @@ class MockedData { class func getFormattedDate(dateTime: NSDate)-> String{ let dateStringFormatter = NSDateFormatter() - dateStringFormatter.dateFormat = "hh:mm"// MM-dd-yyyy + if MockedData.isSameDay(dateTime, thanDate: NSDate()){ + dateStringFormatter.dateFormat = "hh:mm" + } + else{ + dateStringFormatter.dateFormat = "MM-dd-yyyy hh:mm" + } return dateStringFormatter.stringFromDate(dateTime) } + class func isSameDay(dateTime: NSDate, thanDate anotherDate: NSDate)-> Bool { + let calendar = NSCalendar.currentCalendar() + let unitFlags: NSCalendarUnit = .YearCalendarUnit | .MonthCalendarUnit | .DayCalendarUnit + let componentDateTime = calendar.components(unitFlags, fromDate: dateTime) + let componentToday = calendar.components(unitFlags, fromDate: anotherDate) + let day = componentDateTime.day == componentToday.day + let month = componentDateTime.month == componentToday.month + let year = componentDateTime.year == componentToday.year + return (day && month && year) + } } \ No newline at end of file From 257be65790e0f1538a71e80a7faf4888693a9cdc Mon Sep 17 00:00:00 2001 From: Maria Ines Casadei Date: Mon, 26 Jan 2015 15:57:46 -0300 Subject: [PATCH 17/24] Custom cell for chat view --- EyeTypeChat.xcodeproj/project.pbxproj | 9 ++++++ EyeTypeChat/Base.lproj/Main.storyboard | 43 ++++++++++++++++++++++++-- EyeTypeChat/ChatTableViewCell.swift | 29 +++++++++++++++++ EyeTypeChat/ChatViewController.swift | 25 +++++++++------ 4 files changed, 95 insertions(+), 11 deletions(-) create mode 100644 EyeTypeChat/ChatTableViewCell.swift diff --git a/EyeTypeChat.xcodeproj/project.pbxproj b/EyeTypeChat.xcodeproj/project.pbxproj index 1fb4954..e11c424 100644 --- a/EyeTypeChat.xcodeproj/project.pbxproj +++ b/EyeTypeChat.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 231A94151A72AE38008CD10E /* ChatTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 231A94141A72AE38008CD10E /* ChatTableViewCell.swift */; }; 232CE5321A3A3D6100C94EE8 /* Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = 232CE5311A3A3D6100C94EE8 /* Account.swift */; }; 232CE5341A3A3D9300C94EE8 /* TelegramAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 232CE5331A3A3D9300C94EE8 /* TelegramAccount.swift */; }; 232CE5361A3A3DCF00C94EE8 /* Conversation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 232CE5351A3A3DCF00C94EE8 /* Conversation.swift */; }; @@ -67,6 +68,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 231A94141A72AE38008CD10E /* ChatTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatTableViewCell.swift; sourceTree = ""; }; 232CE5311A3A3D6100C94EE8 /* Account.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Account.swift; path = model/Account.swift; sourceTree = ""; }; 232CE5331A3A3D9300C94EE8 /* TelegramAccount.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TelegramAccount.swift; path = model/TelegramAccount.swift; sourceTree = ""; }; 232CE5351A3A3DCF00C94EE8 /* Conversation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Conversation.swift; path = model/Conversation.swift; sourceTree = ""; }; @@ -217,6 +219,7 @@ 236ACA291A44BEFB003D1F53 /* Controllers */, 887A2CC41A0BDB4500094E3C /* AppDelegate.swift */, 23C120CD1A4340F8004D7B5E /* MockedData.swift */, + 231A94141A72AE38008CD10E /* ChatTableViewCell.swift */, 88A759AB1A2F9D4D0005B04C /* EyeControllable.swift */, 237E245F1A56E4E90031B30A /* ChatControllable.swift */, 8856809E1A374B2D005F2BB0 /* fixedMenus.plist */, @@ -358,6 +361,11 @@ TargetAttributes = { 887A2CBE1A0BDB4500094E3C = { CreatedOnToolsVersion = 6.1; + SystemCapabilities = { + com.apple.Maps.iOS = { + enabled = 0; + }; + }; }; 887A2CD61A0BDB4500094E3C = { CreatedOnToolsVersion = 6.1; @@ -465,6 +473,7 @@ 2333C0A21A51A0F900784BEA /* ChatViewModel.swift in Sources */, 232CE5361A3A3DCF00C94EE8 /* Conversation.swift in Sources */, 887A2CCA1A0BDB4500094E3C /* MainViewController.swift in Sources */, + 231A94151A72AE38008CD10E /* ChatTableViewCell.swift in Sources */, 232CE53A1A3A3E9C00C94EE8 /* Contact.swift in Sources */, 232CE5341A3A3D9300C94EE8 /* TelegramAccount.swift in Sources */, 237E24601A56E4E90031B30A /* ChatControllable.swift in Sources */, diff --git a/EyeTypeChat/Base.lproj/Main.storyboard b/EyeTypeChat/Base.lproj/Main.storyboard index 6966d42..8ad30fc 100644 --- a/EyeTypeChat/Base.lproj/Main.storyboard +++ b/EyeTypeChat/Base.lproj/Main.storyboard @@ -149,11 +149,50 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -178,7 +217,7 @@ - + diff --git a/EyeTypeChat/ChatTableViewCell.swift b/EyeTypeChat/ChatTableViewCell.swift new file mode 100644 index 0000000..714cde5 --- /dev/null +++ b/EyeTypeChat/ChatTableViewCell.swift @@ -0,0 +1,29 @@ +// +// ChatTableViewCell.swift +// EyeTypeChat +// +// Created by Maria Ines Casadei on 1/23/15. +// Copyright (c) 2015 SCV Soft. All rights reserved. +// + +import Foundation + +class ChatTableViewCell: UITableViewCell { + + @IBOutlet weak var photoView: UIImageView! + + @IBOutlet weak var fromLabel: UILabel! + + @IBOutlet weak var messageLabel: UILabel! + + @IBOutlet weak var sentDateLabel: UILabel! + + func loadItem(from fromMessage: String, message: String, sentDate: NSDate, imageName: String) { + + fromLabel.text = fromMessage + messageLabel.text = message + sentDateLabel.text = MockedData.getFormattedDate(sentDate) + photoView.image = UIImage(named: imageName) + + } +} \ No newline at end of file diff --git a/EyeTypeChat/ChatViewController.swift b/EyeTypeChat/ChatViewController.swift index ade2961..3d50469 100644 --- a/EyeTypeChat/ChatViewController.swift +++ b/EyeTypeChat/ChatViewController.swift @@ -89,7 +89,17 @@ class ChatViewController: BaseMenuViewController { override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { - let cell = self.chatCell() + var cell:ChatTableViewCell = self.tableView.dequeueReusableCellWithIdentifier("chatCell") as ChatTableViewCell + + //configuring cell + cell.textLabel?.lineBreakMode = .ByWordWrapping + cell.textLabel?.numberOfLines = 0 + cell.selectionStyle = .None + cell.userInteractionEnabled = false + + //getting values for cell + let messageText = messageItems[indexPath.row].message.text + let messageSentDate = messageItems[indexPath.row].message.sentDateTime var messageFrom:String if let from = messageItems[indexPath.row].message.fromContact{ messageFrom = "\(from.name)" @@ -97,14 +107,11 @@ class ChatViewController: BaseMenuViewController { messageFrom = "\(MockedData.getUserIdentifier(managedObjectContext!)!)" } - cell.textLabel?.text = messageFrom + ":\n" + messageItems[indexPath.row].message.text - cell.textLabel?.lineBreakMode = .ByWordWrapping - cell.textLabel?.numberOfLines = 0 - cell.detailTextLabel?.text = MockedData.getFormattedDate(messageItems[indexPath.row].message.sentDateTime) - cell.detailTextLabel?.textColor = UIColor.blueColor() - cell.selectionStyle = .None - cell.imageView?.image = UIImage(named: "user_default.png") - cell.userInteractionEnabled = false + let userDefaultImage = "user_default.png" + + //loading cell + cell.loadItem(from: messageFrom, message: messageText, sentDate: messageSentDate, imageName: userDefaultImage) + return cell } From b7b61a6d9c940f2f842963d42506cfe97872bce9 Mon Sep 17 00:00:00 2001 From: Maria Ines Casadei Date: Wed, 28 Jan 2015 17:26:58 -0300 Subject: [PATCH 18/24] Assigned random colors to each new contact and saved in core data --- EyeTypeChat.xcodeproj/project.pbxproj | 8 +-- EyeTypeChat/ChatTableViewCell.swift | 3 +- EyeTypeChat/ChatViewController.swift | 5 +- .../EyeTypeChat.xcdatamodel/contents | 5 +- EyeTypeChat/MockedData.swift | 55 ++++++++++++++++++- EyeTypeChat/model/Contact.swift | 14 +++-- 6 files changed, 75 insertions(+), 15 deletions(-) diff --git a/EyeTypeChat.xcodeproj/project.pbxproj b/EyeTypeChat.xcodeproj/project.pbxproj index e11c424..08af211 100644 --- a/EyeTypeChat.xcodeproj/project.pbxproj +++ b/EyeTypeChat.xcodeproj/project.pbxproj @@ -12,8 +12,8 @@ 232CE5341A3A3D9300C94EE8 /* TelegramAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 232CE5331A3A3D9300C94EE8 /* TelegramAccount.swift */; }; 232CE5361A3A3DCF00C94EE8 /* Conversation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 232CE5351A3A3DCF00C94EE8 /* Conversation.swift */; }; 232CE5381A3A3E4D00C94EE8 /* Message.swift in Sources */ = {isa = PBXBuildFile; fileRef = 232CE5371A3A3E4D00C94EE8 /* Message.swift */; }; - 232CE53A1A3A3E9C00C94EE8 /* Contact.swift in Sources */ = {isa = PBXBuildFile; fileRef = 232CE5391A3A3E9C00C94EE8 /* Contact.swift */; }; 2333C0A21A51A0F900784BEA /* ChatViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2333C0A11A51A0F900784BEA /* ChatViewModel.swift */; }; + 2338BB451A794B5D00901026 /* Contact.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2338BB441A794B5D00901026 /* Contact.swift */; }; 236ACA281A44B8B2003D1F53 /* EyeControllable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88A759AB1A2F9D4D0005B04C /* EyeControllable.swift */; }; 237E24601A56E4E90031B30A /* ChatControllable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 237E245F1A56E4E90031B30A /* ChatControllable.swift */; }; 23C120CE1A4340F8004D7B5E /* MockedData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23C120CD1A4340F8004D7B5E /* MockedData.swift */; }; @@ -73,8 +73,8 @@ 232CE5331A3A3D9300C94EE8 /* TelegramAccount.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TelegramAccount.swift; path = model/TelegramAccount.swift; sourceTree = ""; }; 232CE5351A3A3DCF00C94EE8 /* Conversation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Conversation.swift; path = model/Conversation.swift; sourceTree = ""; }; 232CE5371A3A3E4D00C94EE8 /* Message.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Message.swift; path = model/Message.swift; sourceTree = ""; }; - 232CE5391A3A3E9C00C94EE8 /* Contact.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Contact.swift; path = model/Contact.swift; sourceTree = ""; }; 2333C0A11A51A0F900784BEA /* ChatViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatViewModel.swift; sourceTree = ""; }; + 2338BB441A794B5D00901026 /* Contact.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Contact.swift; path = model/Contact.swift; sourceTree = ""; }; 237E245F1A56E4E90031B30A /* ChatControllable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatControllable.swift; sourceTree = ""; }; 23C120CD1A4340F8004D7B5E /* MockedData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockedData.swift; sourceTree = ""; }; 23FAF5441A52EDED00ADD423 /* ChatViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatViewController.swift; sourceTree = ""; }; @@ -181,7 +181,7 @@ 23BA3E251A38EB1500C5AD4B /* Core Data Model */ = { isa = PBXGroup; children = ( - 232CE5391A3A3E9C00C94EE8 /* Contact.swift */, + 2338BB441A794B5D00901026 /* Contact.swift */, 232CE5371A3A3E4D00C94EE8 /* Message.swift */, 232CE5351A3A3DCF00C94EE8 /* Conversation.swift */, 232CE5331A3A3D9300C94EE8 /* TelegramAccount.swift */, @@ -474,7 +474,6 @@ 232CE5361A3A3DCF00C94EE8 /* Conversation.swift in Sources */, 887A2CCA1A0BDB4500094E3C /* MainViewController.swift in Sources */, 231A94151A72AE38008CD10E /* ChatTableViewCell.swift in Sources */, - 232CE53A1A3A3E9C00C94EE8 /* Contact.swift in Sources */, 232CE5341A3A3D9300C94EE8 /* TelegramAccount.swift in Sources */, 237E24601A56E4E90031B30A /* ChatControllable.swift in Sources */, 88A759B11A2F9FC10005B04C /* KeyboardViewController.swift in Sources */, @@ -482,6 +481,7 @@ 887A2CC81A0BDB4500094E3C /* EyeTypeChat.xcdatamodeld in Sources */, 88A759A11A2F7B070005B04C /* MainViewModel.swift in Sources */, 8823D7B11A30E8B500271406 /* UIViewController+EyeType.swift in Sources */, + 2338BB451A794B5D00901026 /* Contact.swift in Sources */, 885680A21A374BB8005F2BB0 /* FixedMenuViewController.swift in Sources */, 885680A51A376E47005F2BB0 /* SwiftBridge.m in Sources */, 885680A71A378E55005F2BB0 /* BaseMenuViewController+Commands.swift in Sources */, diff --git a/EyeTypeChat/ChatTableViewCell.swift b/EyeTypeChat/ChatTableViewCell.swift index 714cde5..69ae5c9 100644 --- a/EyeTypeChat/ChatTableViewCell.swift +++ b/EyeTypeChat/ChatTableViewCell.swift @@ -18,9 +18,10 @@ class ChatTableViewCell: UITableViewCell { @IBOutlet weak var sentDateLabel: UILabel! - func loadItem(from fromMessage: String, message: String, sentDate: NSDate, imageName: String) { + func loadItem(from fromMessage: String, fromContactColor: UIColor, message: String, sentDate: NSDate, imageName: String) { fromLabel.text = fromMessage + fromLabel.textColor = fromContactColor messageLabel.text = message sentDateLabel.text = MockedData.getFormattedDate(sentDate) photoView.image = UIImage(named: imageName) diff --git a/EyeTypeChat/ChatViewController.swift b/EyeTypeChat/ChatViewController.swift index 3d50469..06f21fb 100644 --- a/EyeTypeChat/ChatViewController.swift +++ b/EyeTypeChat/ChatViewController.swift @@ -101,16 +101,19 @@ class ChatViewController: BaseMenuViewController { let messageText = messageItems[indexPath.row].message.text let messageSentDate = messageItems[indexPath.row].message.sentDateTime var messageFrom:String + var contactColor:UIColor if let from = messageItems[indexPath.row].message.fromContact{ messageFrom = "\(from.name)" + contactColor = from.color }else{ messageFrom = "\(MockedData.getUserIdentifier(managedObjectContext!)!)" + contactColor = UIColor.blueColor() // default color for user: blue } let userDefaultImage = "user_default.png" //loading cell - cell.loadItem(from: messageFrom, message: messageText, sentDate: messageSentDate, imageName: userDefaultImage) + cell.loadItem(from: messageFrom, fromContactColor: contactColor, message: messageText, sentDate: messageSentDate, imageName: userDefaultImage) return cell } diff --git a/EyeTypeChat/EyeTypeChat.xcdatamodeld/EyeTypeChat.xcdatamodel/contents b/EyeTypeChat/EyeTypeChat.xcdatamodeld/EyeTypeChat.xcdatamodel/contents index 017bc24..c4e2a64 100644 --- a/EyeTypeChat/EyeTypeChat.xcdatamodeld/EyeTypeChat.xcdatamodel/contents +++ b/EyeTypeChat/EyeTypeChat.xcdatamodeld/EyeTypeChat.xcdatamodel/contents @@ -6,6 +6,7 @@ + @@ -25,9 +26,9 @@ - + - + \ No newline at end of file diff --git a/EyeTypeChat/MockedData.swift b/EyeTypeChat/MockedData.swift index 5118255..9df5c58 100644 --- a/EyeTypeChat/MockedData.swift +++ b/EyeTypeChat/MockedData.swift @@ -19,9 +19,9 @@ class MockedData { // create contact list var contactSet = NSMutableSet() - var firstContact = Contact.createContact("Mary", phoneNumber: 263823827, account: telegramAccount, entity: "Contact", context: dataContext) - var secondContact = Contact.createContact("Anna", phoneNumber: 1161690000, account: telegramAccount, entity: "Contact", context: dataContext) - var thirdContact = Contact.createContact("John", phoneNumber: 328378738, account: telegramAccount, entity: "Contact", context: dataContext) + var firstContact = Contact.createContact("Mary", phoneNumber: 263823827, color: MockedData.randomColor(), account: telegramAccount, entity: "Contact", context: dataContext) + var secondContact = Contact.createContact("Anna", phoneNumber: 1161690000, color: MockedData.randomColor(), account: telegramAccount, entity: "Contact", context: dataContext) + var thirdContact = Contact.createContact("John", phoneNumber: 328378738, color: MockedData.randomColor(), account: telegramAccount, entity: "Contact", context: dataContext) contactSet.addObjectsFromArray([firstContact, secondContact, thirdContact]) // create conversations @@ -246,4 +246,53 @@ class MockedData { return (day && month && year) } + /* + Distributed under The MIT License: + http://opensource.org/licenses/mit-license.php + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + class func randomColor() -> UIColor{ + // from https://gist.github.com/kylefox/1689973 + + let value1 = UInt32(128) + let value2 : Float32 = 256.0 + let value3 : Float32 = 0.5 + + let hueRandom = Float(arc4random() % 256) + let hueValue = hueRandom / 256.0 // 0.0 to 1.0 + let hue = CGFloat(hueValue) + print(hueValue) + + let saturationRandom = arc4random() % value1 + let saturationValue = Float(saturationRandom) / value2 + value3 // 0.5 to 1.0, away from white + let saturation = CGFloat(saturationValue) + print(saturationValue) + + let brightnessRandom = arc4random() % value1 + let brightnessValue = Float(brightnessRandom) / value2 + value3 // 0.5 to 1.0, away from black + let brightness = CGFloat(brightnessValue) + print(brightnessValue) + + let color = UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1) + return color + } + } \ No newline at end of file diff --git a/EyeTypeChat/model/Contact.swift b/EyeTypeChat/model/Contact.swift index 793d610..ced0951 100644 --- a/EyeTypeChat/model/Contact.swift +++ b/EyeTypeChat/model/Contact.swift @@ -2,8 +2,8 @@ // EyeTypeChat.swift // EyeTypeChat // -// Created by Maria Ines Casadei on 12/11/14. -// Copyright (c) 2014 SCV Soft. All rights reserved. +// Created by Maria Ines Casadei on 1/28/15. +// Copyright (c) 2015 SCV Soft. All rights reserved. // import Foundation @@ -11,17 +11,23 @@ import CoreData class Contact: NSManagedObject { + @NSManaged dynamic var color: UIColor @NSManaged var name: String @NSManaged var phoneNumber: NSNumber @NSManaged var account: EyeTypeChat.Account // TODO: mark as unowned to avoid strong reference cycles - - class func createContact(name: String, phoneNumber: NSNumber, account: Account, entity: String, context: NSManagedObjectContext) -> Contact{ + + + class func createContact(name: String, phoneNumber: NSNumber, color: UIColor, account: Account, entity: String, context: NSManagedObjectContext) -> Contact{ var contact = NSEntityDescription.insertNewObjectForEntityForName(entity, inManagedObjectContext: context) as Contact contact.name = name contact.phoneNumber = phoneNumber contact.account = account + contact.color = color return contact + } + + } From 554032ef3b69efb7640d6fc9691146fc922ee575 Mon Sep 17 00:00:00 2001 From: Maria Ines Casadei Date: Fri, 30 Jan 2015 17:49:31 -0300 Subject: [PATCH 19/24] Scrolling chat table to the bottom of the conversation. Image colored according to contact. --- EyeTypeChat.xcodeproj/project.pbxproj | 4 ++ EyeTypeChat/Base.lproj/Main.storyboard | 60 ++++++++++++------- .../BaseMenuViewController+Commands.swift | 1 - EyeTypeChat/BaseMenuViewController.swift | 8 --- EyeTypeChat/ChatTableViewCell.swift | 3 +- EyeTypeChat/ChatViewController.swift | 15 ++++- EyeTypeChat/MainViewController.swift | 2 +- EyeTypeChat/MockedData.swift | 4 +- EyeTypeChat/UIImage+Color.swift | 39 ++++++++++++ 9 files changed, 98 insertions(+), 38 deletions(-) create mode 100644 EyeTypeChat/UIImage+Color.swift diff --git a/EyeTypeChat.xcodeproj/project.pbxproj b/EyeTypeChat.xcodeproj/project.pbxproj index 08af211..e184897 100644 --- a/EyeTypeChat.xcodeproj/project.pbxproj +++ b/EyeTypeChat.xcodeproj/project.pbxproj @@ -17,6 +17,7 @@ 236ACA281A44B8B2003D1F53 /* EyeControllable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88A759AB1A2F9D4D0005B04C /* EyeControllable.swift */; }; 237E24601A56E4E90031B30A /* ChatControllable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 237E245F1A56E4E90031B30A /* ChatControllable.swift */; }; 23C120CE1A4340F8004D7B5E /* MockedData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23C120CD1A4340F8004D7B5E /* MockedData.swift */; }; + 23E593011A7BC78E003DCE61 /* UIImage+Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23E593001A7BC78E003DCE61 /* UIImage+Color.swift */; }; 23FAF5451A52EDED00ADD423 /* ChatViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23FAF5441A52EDED00ADD423 /* ChatViewController.swift */; }; 5E9B341BA996967017148759 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A49492BC4CA902EDA58BC35 /* libPods.a */; }; 8823D7AE1A30E3D200271406 /* ConversationListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8823D7AD1A30E3D200271406 /* ConversationListViewController.swift */; }; @@ -77,6 +78,7 @@ 2338BB441A794B5D00901026 /* Contact.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Contact.swift; path = model/Contact.swift; sourceTree = ""; }; 237E245F1A56E4E90031B30A /* ChatControllable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatControllable.swift; sourceTree = ""; }; 23C120CD1A4340F8004D7B5E /* MockedData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockedData.swift; sourceTree = ""; }; + 23E593001A7BC78E003DCE61 /* UIImage+Color.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Color.swift"; sourceTree = ""; }; 23FAF5441A52EDED00ADD423 /* ChatViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatViewController.swift; sourceTree = ""; }; 8823D7AD1A30E3D200271406 /* ConversationListViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConversationListViewController.swift; sourceTree = ""; }; 8823D7B01A30E8B500271406 /* UIViewController+EyeType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+EyeType.swift"; sourceTree = ""; }; @@ -220,6 +222,7 @@ 887A2CC41A0BDB4500094E3C /* AppDelegate.swift */, 23C120CD1A4340F8004D7B5E /* MockedData.swift */, 231A94141A72AE38008CD10E /* ChatTableViewCell.swift */, + 23E593001A7BC78E003DCE61 /* UIImage+Color.swift */, 88A759AB1A2F9D4D0005B04C /* EyeControllable.swift */, 237E245F1A56E4E90031B30A /* ChatControllable.swift */, 8856809E1A374B2D005F2BB0 /* fixedMenus.plist */, @@ -484,6 +487,7 @@ 2338BB451A794B5D00901026 /* Contact.swift in Sources */, 885680A21A374BB8005F2BB0 /* FixedMenuViewController.swift in Sources */, 885680A51A376E47005F2BB0 /* SwiftBridge.m in Sources */, + 23E593011A7BC78E003DCE61 /* UIImage+Color.swift in Sources */, 885680A71A378E55005F2BB0 /* BaseMenuViewController+Commands.swift in Sources */, 8823D7B31A30F65E00271406 /* BaseMenuViewController.swift in Sources */, 23C120CE1A4340F8004D7B5E /* MockedData.swift in Sources */, diff --git a/EyeTypeChat/Base.lproj/Main.storyboard b/EyeTypeChat/Base.lproj/Main.storyboard index 8ad30fc..ba8a907 100644 --- a/EyeTypeChat/Base.lproj/Main.storyboard +++ b/EyeTypeChat/Base.lproj/Main.storyboard @@ -144,47 +144,61 @@ - + - + - - - - - - - - - - - + + + + + + + + + + + + + diff --git a/EyeTypeChat/BaseMenuViewController+Commands.swift b/EyeTypeChat/BaseMenuViewController+Commands.swift index 7e62037..9e28cb8 100644 --- a/EyeTypeChat/BaseMenuViewController+Commands.swift +++ b/EyeTypeChat/BaseMenuViewController+Commands.swift @@ -15,5 +15,4 @@ extension BaseMenuViewController { viewController.chatControllable = mainViewController? self.navigationController!.pushViewController(viewController, animated: true) } - } diff --git a/EyeTypeChat/BaseMenuViewController.swift b/EyeTypeChat/BaseMenuViewController.swift index 87cb3e2..de82c18 100644 --- a/EyeTypeChat/BaseMenuViewController.swift +++ b/EyeTypeChat/BaseMenuViewController.swift @@ -33,14 +33,6 @@ class BaseMenuViewController: UITableViewController, EyeControllable { } return cell! } - - func chatCell() -> UITableViewCell { - var cell = tableView.dequeueReusableCellWithIdentifier(CellIdentifier) as UITableViewCell? - if cell == nil { - cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: CellIdentifier) - } - return cell! - } func validRow(indexPath: NSIndexPath) -> NSIndexPath { if (indexPath.section >= numberOfSectionsInTableView(tableView)) { diff --git a/EyeTypeChat/ChatTableViewCell.swift b/EyeTypeChat/ChatTableViewCell.swift index 69ae5c9..90a1172 100644 --- a/EyeTypeChat/ChatTableViewCell.swift +++ b/EyeTypeChat/ChatTableViewCell.swift @@ -24,7 +24,8 @@ class ChatTableViewCell: UITableViewCell { fromLabel.textColor = fromContactColor messageLabel.text = message sentDateLabel.text = MockedData.getFormattedDate(sentDate) - photoView.image = UIImage(named: imageName) + let image = UIImage(named: imageName) + photoView.image = image?.colorizeWith(fromContactColor) } } \ No newline at end of file diff --git a/EyeTypeChat/ChatViewController.swift b/EyeTypeChat/ChatViewController.swift index 06f21fb..87f05e8 100644 --- a/EyeTypeChat/ChatViewController.swift +++ b/EyeTypeChat/ChatViewController.swift @@ -58,7 +58,8 @@ class ChatViewController: BaseMenuViewController { let chatItem = MessageItem(item: item as Message) messageItems.append(chatItem) } - self.tableView.reloadData() + tableView.reloadData() + goToBottom() } func addNewMessage(){ @@ -111,7 +112,7 @@ class ChatViewController: BaseMenuViewController { } let userDefaultImage = "user_default.png" - + //loading cell cell.loadItem(from: messageFrom, fromContactColor: contactColor, message: messageText, sentDate: messageSentDate, imageName: userDefaultImage) @@ -141,5 +142,15 @@ class ChatViewController: BaseMenuViewController { writingTextField.text = chatModel.currentWritingText } + func goToBottom(){ + tableView.scrollToRowAtIndexPath(lastIndexPath(), atScrollPosition: UITableViewScrollPosition.Top, animated: true) + } + + func lastIndexPath() -> NSIndexPath{ + let lastRowIndex = tableView.numberOfRowsInSection(0) - 1 + print(lastRowIndex) + return NSIndexPath(forRow: lastRowIndex, inSection: 0) + } + } diff --git a/EyeTypeChat/MainViewController.swift b/EyeTypeChat/MainViewController.swift index c5725f6..ed7a244 100644 --- a/EyeTypeChat/MainViewController.swift +++ b/EyeTypeChat/MainViewController.swift @@ -69,7 +69,7 @@ class MainViewController: ETVideoSourceViewController , ChatControllable { func createAndPrintMockedData(){ var mockedData = MockedData(dataContext: managedObjectContext!) - MockedData.printMockedData(managedObjectContext!) + // MockedData.printMockedData(managedObjectContext!) } diff --git a/EyeTypeChat/MockedData.swift b/EyeTypeChat/MockedData.swift index 9df5c58..bb3eb47 100644 --- a/EyeTypeChat/MockedData.swift +++ b/EyeTypeChat/MockedData.swift @@ -73,7 +73,7 @@ class MockedData { var msg13 = Message.createMessage("Any news from Tom?", sentDateTime: currentDate!, conversation: groupConversation, fromContact: secondContact, entity: "Message", context: dataContext) currentDate = MockedData.dateByAddingMinutes(2, date: currentDate) - var msg14 = Message.createMessage("He sent a confirmation email, testing test testi n g a e i o ups hey !! 628ndnjshuy ash sjue ttt ehsshs xbxbxb sggsye yquwwb ja.", sentDateTime: currentDate!, conversation: groupConversation, fromContact: thirdContact, entity: "Message", context: dataContext) + var msg14 = Message.createMessage("He sent a confirmation email", sentDateTime: currentDate!, conversation: groupConversation, fromContact: thirdContact, entity: "Message", context: dataContext) currentDate = MockedData.dateByAddingMinutes(1, date: currentDate) var msg15 = Message.createMessage("The plane arrives to NY at 10pm", sentDateTime: currentDate!, conversation: groupConversation, fromContact: nil, entity: "Message", context:dataContext) @@ -294,5 +294,5 @@ class MockedData { let color = UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1) return color } - + } \ No newline at end of file diff --git a/EyeTypeChat/UIImage+Color.swift b/EyeTypeChat/UIImage+Color.swift new file mode 100644 index 0000000..5acf316 --- /dev/null +++ b/EyeTypeChat/UIImage+Color.swift @@ -0,0 +1,39 @@ +// +// UIImage+Color.swift +// EyeTypeChat +// +// Created by Maria Ines Casadei on 1/30/15. +// Copyright (c) 2015 SCV Soft. All rights reserved. +// + +import Foundation + +extension UIImage { + + //TODO: move to another class or make an extension + func colorizeWith(color: UIColor) -> UIImage { + + UIGraphicsBeginImageContext(self.size) + let context = UIGraphicsGetCurrentContext() + color.setFill() + CGContextTranslateCTM(context, 0, self.size.height) + CGContextScaleCTM(context, 1.0, -1.0) + + // set the blend mode to color burn, and the original image + CGContextSetBlendMode(context, kCGBlendModeNormal); + let rect = CGRectMake(0, 0, self.size.width, self.size.height); + CGContextDrawImage(context, rect, self.CGImage); + + // set a mask that matches the shape of the image, then draw (color burn) a colored rectangle + CGContextClipToMask(context, rect, self.CGImage); + CGContextAddRect(context, rect); + CGContextDrawPath(context,kCGPathFill); + + // generate a new UIImage from the graphics context we drew onto + let coloredImage = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + //return the color-burned image + return coloredImage; + } +} From b5f5ea1cd6b366148ae9217969a907a6e7d4c96e Mon Sep 17 00:00:00 2001 From: Maria Ines Casadei Date: Tue, 3 Feb 2015 11:35:39 -0300 Subject: [PATCH 20/24] Dynamic type adoption and constraints fixed --- EyeTypeChat/Base.lproj/Main.storyboard | 55 +++++++++++--------------- EyeTypeChat/ChatTableViewCell.swift | 3 ++ 2 files changed, 26 insertions(+), 32 deletions(-) diff --git a/EyeTypeChat/Base.lproj/Main.storyboard b/EyeTypeChat/Base.lproj/Main.storyboard index ba8a907..754a191 100644 --- a/EyeTypeChat/Base.lproj/Main.storyboard +++ b/EyeTypeChat/Base.lproj/Main.storyboard @@ -1,5 +1,5 @@ - + @@ -155,50 +155,41 @@ - - - - - + + - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/EyeTypeChat/ChatTableViewCell.swift b/EyeTypeChat/ChatTableViewCell.swift index 90a1172..505c159 100644 --- a/EyeTypeChat/ChatTableViewCell.swift +++ b/EyeTypeChat/ChatTableViewCell.swift @@ -22,8 +22,11 @@ class ChatTableViewCell: UITableViewCell { fromLabel.text = fromMessage fromLabel.textColor = fromContactColor + fromLabel.font = UIFont .preferredFontForTextStyle(UIFontTextStyleHeadline) messageLabel.text = message + messageLabel.font = UIFont .preferredFontForTextStyle(UIFontTextStyleBody) sentDateLabel.text = MockedData.getFormattedDate(sentDate) + sentDateLabel.font = UIFont .preferredFontForTextStyle(UIFontTextStyleSubheadline) let image = UIImage(named: imageName) photoView.image = image?.colorizeWith(fromContactColor) From 2ae60d5bd4d8c6dea92ae2654ab8f1ce29551240 Mon Sep 17 00:00:00 2001 From: Maria Ines Casadei Date: Tue, 3 Feb 2015 14:31:19 -0300 Subject: [PATCH 21/24] Dynamic row size --- EyeTypeChat.xcodeproj/project.pbxproj | 2 +- EyeTypeChat/Base.lproj/Main.storyboard | 54 ++++++++++++++++++-------- EyeTypeChat/ChatTableViewCell.swift | 1 + EyeTypeChat/ChatViewController.swift | 8 +++- EyeTypeChat/MockedData.swift | 2 +- 5 files changed, 48 insertions(+), 19 deletions(-) diff --git a/EyeTypeChat.xcodeproj/project.pbxproj b/EyeTypeChat.xcodeproj/project.pbxproj index e184897..6397e15 100644 --- a/EyeTypeChat.xcodeproj/project.pbxproj +++ b/EyeTypeChat.xcodeproj/project.pbxproj @@ -79,7 +79,7 @@ 237E245F1A56E4E90031B30A /* ChatControllable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatControllable.swift; sourceTree = ""; }; 23C120CD1A4340F8004D7B5E /* MockedData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockedData.swift; sourceTree = ""; }; 23E593001A7BC78E003DCE61 /* UIImage+Color.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Color.swift"; sourceTree = ""; }; - 23FAF5441A52EDED00ADD423 /* ChatViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatViewController.swift; sourceTree = ""; }; + 23FAF5441A52EDED00ADD423 /* ChatViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatViewController.swift; sourceTree = ""; wrapsLines = 1; }; 8823D7AD1A30E3D200271406 /* ConversationListViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConversationListViewController.swift; sourceTree = ""; }; 8823D7B01A30E8B500271406 /* UIViewController+EyeType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+EyeType.swift"; sourceTree = ""; }; 8823D7B21A30F65E00271406 /* BaseMenuViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseMenuViewController.swift; sourceTree = ""; }; diff --git a/EyeTypeChat/Base.lproj/Main.storyboard b/EyeTypeChat/Base.lproj/Main.storyboard index 754a191..9decc55 100644 --- a/EyeTypeChat/Base.lproj/Main.storyboard +++ b/EyeTypeChat/Base.lproj/Main.storyboard @@ -3,6 +3,7 @@ + @@ -149,48 +150,69 @@ - + - + - + + - - - + + + + + + + + + - - + + - + + + + - + + + + + + + + + + + + diff --git a/EyeTypeChat/ChatTableViewCell.swift b/EyeTypeChat/ChatTableViewCell.swift index 505c159..edc2835 100644 --- a/EyeTypeChat/ChatTableViewCell.swift +++ b/EyeTypeChat/ChatTableViewCell.swift @@ -25,6 +25,7 @@ class ChatTableViewCell: UITableViewCell { fromLabel.font = UIFont .preferredFontForTextStyle(UIFontTextStyleHeadline) messageLabel.text = message messageLabel.font = UIFont .preferredFontForTextStyle(UIFontTextStyleBody) + messageLabel.numberOfLines = 0 sentDateLabel.text = MockedData.getFormattedDate(sentDate) sentDateLabel.font = UIFont .preferredFontForTextStyle(UIFontTextStyleSubheadline) let image = UIImage(named: imageName) diff --git a/EyeTypeChat/ChatViewController.swift b/EyeTypeChat/ChatViewController.swift index 87f05e8..85d9d52 100644 --- a/EyeTypeChat/ChatViewController.swift +++ b/EyeTypeChat/ChatViewController.swift @@ -34,6 +34,12 @@ class ChatViewController: BaseMenuViewController { override func viewDidLoad() { loadConversations() super.viewDidLoad() + setupTableView() + } + + func setupTableView(){ + self.tableView.estimatedRowHeight = 50.0 + self.tableView.rowHeight = UITableViewAutomaticDimension } func loadConversations(){ @@ -91,7 +97,7 @@ class ChatViewController: BaseMenuViewController { override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { var cell:ChatTableViewCell = self.tableView.dequeueReusableCellWithIdentifier("chatCell") as ChatTableViewCell - + //configuring cell cell.textLabel?.lineBreakMode = .ByWordWrapping cell.textLabel?.numberOfLines = 0 diff --git a/EyeTypeChat/MockedData.swift b/EyeTypeChat/MockedData.swift index bb3eb47..ff5cd2a 100644 --- a/EyeTypeChat/MockedData.swift +++ b/EyeTypeChat/MockedData.swift @@ -76,7 +76,7 @@ class MockedData { var msg14 = Message.createMessage("He sent a confirmation email", sentDateTime: currentDate!, conversation: groupConversation, fromContact: thirdContact, entity: "Message", context: dataContext) currentDate = MockedData.dateByAddingMinutes(1, date: currentDate) - var msg15 = Message.createMessage("The plane arrives to NY at 10pm", sentDateTime: currentDate!, conversation: groupConversation, fromContact: nil, entity: "Message", context:dataContext) + var msg15 = Message.createMessage("The plane arrives to NY at 10pm 8pm 7278pm shsjjs hsdhsha test testing eyeun 11 34pm hddueok ma shs aew uwi blah bluon uy 66282 syu or s wop ww bb asrsueoq mlq test.", sentDateTime: currentDate!, conversation: groupConversation, fromContact: nil, entity: "Message", context:dataContext) currentDate = MockedData.dateByAddingMinutes(1, date: currentDate) var msg16 = Message.createMessage("Perfect", sentDateTime: currentDate!, conversation: groupConversation, fromContact: secondContact, entity: "Message", context: dataContext) From 48ed3a55a0f3cbaed2f23ed6a3c86e27a6c939a6 Mon Sep 17 00:00:00 2001 From: Maria Ines Casadei Date: Tue, 3 Feb 2015 16:23:14 -0300 Subject: [PATCH 22/24] Fixed problem when scroolling --- EyeTypeChat/Base.lproj/Main.storyboard | 2 +- EyeTypeChat/ChatViewController.swift | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/EyeTypeChat/Base.lproj/Main.storyboard b/EyeTypeChat/Base.lproj/Main.storyboard index 9decc55..fb8410a 100644 --- a/EyeTypeChat/Base.lproj/Main.storyboard +++ b/EyeTypeChat/Base.lproj/Main.storyboard @@ -145,7 +145,7 @@ - + diff --git a/EyeTypeChat/ChatViewController.swift b/EyeTypeChat/ChatViewController.swift index 85d9d52..2e208a3 100644 --- a/EyeTypeChat/ChatViewController.swift +++ b/EyeTypeChat/ChatViewController.swift @@ -32,13 +32,18 @@ class ChatViewController: BaseMenuViewController { override func viewDidLoad() { + setupTableView() loadConversations() super.viewDidLoad() - setupTableView() + } + + override func viewDidAppear(animated: Bool) { + super.viewDidAppear(animated) + goToBottom() } func setupTableView(){ - self.tableView.estimatedRowHeight = 50.0 + self.tableView.estimatedRowHeight = 60.0 self.tableView.rowHeight = UITableViewAutomaticDimension } @@ -65,6 +70,7 @@ class ChatViewController: BaseMenuViewController { messageItems.append(chatItem) } tableView.reloadData() + tableView.layoutIfNeeded() goToBottom() } @@ -149,12 +155,11 @@ class ChatViewController: BaseMenuViewController { } func goToBottom(){ - tableView.scrollToRowAtIndexPath(lastIndexPath(), atScrollPosition: UITableViewScrollPosition.Top, animated: true) + tableView.scrollToRowAtIndexPath(lastIndexPath(), atScrollPosition: UITableViewScrollPosition.Top, animated: false) } func lastIndexPath() -> NSIndexPath{ let lastRowIndex = tableView.numberOfRowsInSection(0) - 1 - print(lastRowIndex) return NSIndexPath(forRow: lastRowIndex, inSection: 0) } From e43da8906dc6ffdcde6e4e0803dec8001eb4d242 Mon Sep 17 00:00:00 2001 From: Maria Ines Casadei Date: Wed, 4 Feb 2015 13:12:46 -0300 Subject: [PATCH 23/24] Refactor --- EyeTypeChat/ChatControllable.swift | 6 +++--- EyeTypeChat/ChatViewController.swift | 7 ++++++- EyeTypeChat/KeyboardViewController.swift | 6 +++--- EyeTypeChat/MainViewController.swift | 6 +++--- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/EyeTypeChat/ChatControllable.swift b/EyeTypeChat/ChatControllable.swift index 606141c..8a829fa 100644 --- a/EyeTypeChat/ChatControllable.swift +++ b/EyeTypeChat/ChatControllable.swift @@ -11,8 +11,8 @@ import Foundation @objc protocol ChatControllable { - func chatDidType(letter: String) - func chatDidSend() - func chatDidClearAll() + func chatWillType(letter: String) + func chatWillSend() + func chatWillClearAll() } \ No newline at end of file diff --git a/EyeTypeChat/ChatViewController.swift b/EyeTypeChat/ChatViewController.swift index 2e208a3..b0ce046 100644 --- a/EyeTypeChat/ChatViewController.swift +++ b/EyeTypeChat/ChatViewController.swift @@ -69,6 +69,11 @@ class ChatViewController: BaseMenuViewController { let chatItem = MessageItem(item: item as Message) messageItems.append(chatItem) } + updateUI(); + + } + + func updateUI(){ tableView.reloadData() tableView.layoutIfNeeded() goToBottom() @@ -155,7 +160,7 @@ class ChatViewController: BaseMenuViewController { } func goToBottom(){ - tableView.scrollToRowAtIndexPath(lastIndexPath(), atScrollPosition: UITableViewScrollPosition.Top, animated: false) + tableView.scrollToRowAtIndexPath(lastIndexPath(), atScrollPosition: UITableViewScrollPosition.None, animated: false) } func lastIndexPath() -> NSIndexPath{ diff --git a/EyeTypeChat/KeyboardViewController.swift b/EyeTypeChat/KeyboardViewController.swift index 3d325fb..535c9ac 100644 --- a/EyeTypeChat/KeyboardViewController.swift +++ b/EyeTypeChat/KeyboardViewController.swift @@ -96,15 +96,15 @@ class KeyboardViewController: UIViewController, EyeControllable { } func updateWritingText(letter:String) { - chatControllable.chatDidType(letter) + chatControllable.chatWillType(letter) } func sendWrittenText() { - chatControllable.chatDidSend() + chatControllable.chatWillSend() } func clearWrittenText() { - chatControllable.chatDidClearAll() + chatControllable.chatWillClearAll() } func executeActionAccordingToKeySelection(key: String){ diff --git a/EyeTypeChat/MainViewController.swift b/EyeTypeChat/MainViewController.swift index ed7a244..292148d 100644 --- a/EyeTypeChat/MainViewController.swift +++ b/EyeTypeChat/MainViewController.swift @@ -121,17 +121,17 @@ class MainViewController: ETVideoSourceViewController , ChatControllable { // MARK: ChatControllable - func chatDidType(letter: String) { + func chatWillType(letter: String) { let c = self.chatNavigationController.topViewController as ChatViewController c.type(letter) } - func chatDidSend() { + func chatWillSend() { let c = self.chatNavigationController.topViewController as ChatViewController c.sendMessage() } - func chatDidClearAll() { + func chatWillClearAll() { let c = self.chatNavigationController.topViewController as ChatViewController c.clearCurrentText() } From a650b7fddad4082bf35d359ab7cfd1a90ee376b7 Mon Sep 17 00:00:00 2001 From: Maria Ines Casadei Date: Thu, 19 Feb 2015 12:42:02 -0300 Subject: [PATCH 24/24] Update UI after rotation --- EyeTypeChat/Base.lproj/Main.storyboard | 18 ------------------ EyeTypeChat/ChatViewController.swift | 4 ++++ EyeTypeChat/UIImage+Color.swift | 1 - 3 files changed, 4 insertions(+), 19 deletions(-) diff --git a/EyeTypeChat/Base.lproj/Main.storyboard b/EyeTypeChat/Base.lproj/Main.storyboard index fb8410a..67a38cd 100644 --- a/EyeTypeChat/Base.lproj/Main.storyboard +++ b/EyeTypeChat/Base.lproj/Main.storyboard @@ -178,19 +178,12 @@ - - - - - - - @@ -202,17 +195,6 @@ - - - - - - - - - - - diff --git a/EyeTypeChat/ChatViewController.swift b/EyeTypeChat/ChatViewController.swift index b0ce046..f410862 100644 --- a/EyeTypeChat/ChatViewController.swift +++ b/EyeTypeChat/ChatViewController.swift @@ -79,6 +79,10 @@ class ChatViewController: BaseMenuViewController { goToBottom() } + override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) { + updateUI() + } + func addNewMessage(){ MockedData.addNewMessage(managedObjectContext!, message: self.writingTextField.text, conversation: self.chatModel.currentConversation) } diff --git a/EyeTypeChat/UIImage+Color.swift b/EyeTypeChat/UIImage+Color.swift index 5acf316..8d2f2df 100644 --- a/EyeTypeChat/UIImage+Color.swift +++ b/EyeTypeChat/UIImage+Color.swift @@ -10,7 +10,6 @@ import Foundation extension UIImage { - //TODO: move to another class or make an extension func colorizeWith(color: UIColor) -> UIImage { UIGraphicsBeginImageContext(self.size)