├── .DS_Store
├── fbMessenger
├── Assets.xcassets
│ ├── Contents.json
│ ├── calls.imageset
│ │ ├── calls@3x.png
│ │ └── Contents.json
│ ├── gandhi.imageset
│ │ ├── gandhi.png
│ │ └── Contents.json
│ ├── groups.imageset
│ │ ├── groups@3x.png
│ │ └── Contents.json
│ ├── people.imageset
│ │ ├── people@3x.png
│ │ └── Contents.json
│ ├── recent.imageset
│ │ ├── recent@3x.png
│ │ └── Contents.json
│ ├── settings.imageset
│ │ ├── settings@3x.png
│ │ └── Contents.json
│ ├── zuckprofile.imageset
│ │ ├── zuckprofile.jpg
│ │ └── Contents.json
│ ├── bubble_blue.imageset
│ │ ├── bubble_blue@2x.png
│ │ └── Contents.json
│ ├── bubble_gray.imageset
│ │ ├── bubble_gray@2x.png
│ │ └── Contents.json
│ ├── steve_profile.imageset
│ │ ├── steve_profile.png
│ │ └── Contents.json
│ ├── hillary_profile.imageset
│ │ ├── hillary_profile.jpg
│ │ └── Contents.json
│ ├── donald_trump_profile.imageset
│ │ ├── donald_trump_profile.png
│ │ └── Contents.json
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── fbMessenger.xcdatamodeld
│ ├── .xccurrentversion
│ └── fbMessenger.xcdatamodel
│ │ └── contents
├── Extensions.swift
├── Info.plist
├── CustomTabbarController.swift
├── Base.lproj
│ └── LaunchScreen.storyboard
├── FriendsControllerHelper.swift
├── AppDelegate.swift
├── FriendsController.swift
└── ChatLogController.swift
├── fbMessenger.xcodeproj
├── xcuserdata
│ └── VamshiKrishna.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── fbMessenger.xcscheme
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ └── VamshiKrishna.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
└── project.pbxproj
└── README.md
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBChatClone/HEAD/.DS_Store
--------------------------------------------------------------------------------
/fbMessenger/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/fbMessenger/Assets.xcassets/calls.imageset/calls@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBChatClone/HEAD/fbMessenger/Assets.xcassets/calls.imageset/calls@3x.png
--------------------------------------------------------------------------------
/fbMessenger/Assets.xcassets/gandhi.imageset/gandhi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBChatClone/HEAD/fbMessenger/Assets.xcassets/gandhi.imageset/gandhi.png
--------------------------------------------------------------------------------
/fbMessenger/Assets.xcassets/groups.imageset/groups@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBChatClone/HEAD/fbMessenger/Assets.xcassets/groups.imageset/groups@3x.png
--------------------------------------------------------------------------------
/fbMessenger/Assets.xcassets/people.imageset/people@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBChatClone/HEAD/fbMessenger/Assets.xcassets/people.imageset/people@3x.png
--------------------------------------------------------------------------------
/fbMessenger/Assets.xcassets/recent.imageset/recent@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBChatClone/HEAD/fbMessenger/Assets.xcassets/recent.imageset/recent@3x.png
--------------------------------------------------------------------------------
/fbMessenger/Assets.xcassets/settings.imageset/settings@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBChatClone/HEAD/fbMessenger/Assets.xcassets/settings.imageset/settings@3x.png
--------------------------------------------------------------------------------
/fbMessenger/Assets.xcassets/zuckprofile.imageset/zuckprofile.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBChatClone/HEAD/fbMessenger/Assets.xcassets/zuckprofile.imageset/zuckprofile.jpg
--------------------------------------------------------------------------------
/fbMessenger/Assets.xcassets/bubble_blue.imageset/bubble_blue@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBChatClone/HEAD/fbMessenger/Assets.xcassets/bubble_blue.imageset/bubble_blue@2x.png
--------------------------------------------------------------------------------
/fbMessenger/Assets.xcassets/bubble_gray.imageset/bubble_gray@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBChatClone/HEAD/fbMessenger/Assets.xcassets/bubble_gray.imageset/bubble_gray@2x.png
--------------------------------------------------------------------------------
/fbMessenger/Assets.xcassets/steve_profile.imageset/steve_profile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBChatClone/HEAD/fbMessenger/Assets.xcassets/steve_profile.imageset/steve_profile.png
--------------------------------------------------------------------------------
/fbMessenger.xcodeproj/xcuserdata/VamshiKrishna.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/fbMessenger/Assets.xcassets/hillary_profile.imageset/hillary_profile.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBChatClone/HEAD/fbMessenger/Assets.xcassets/hillary_profile.imageset/hillary_profile.jpg
--------------------------------------------------------------------------------
/fbMessenger/Assets.xcassets/donald_trump_profile.imageset/donald_trump_profile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBChatClone/HEAD/fbMessenger/Assets.xcassets/donald_trump_profile.imageset/donald_trump_profile.png
--------------------------------------------------------------------------------
/fbMessenger.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/fbMessenger.xcodeproj/project.xcworkspace/xcuserdata/VamshiKrishna.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBChatClone/HEAD/fbMessenger.xcodeproj/project.xcworkspace/xcuserdata/VamshiKrishna.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/fbMessenger/fbMessenger.xcdatamodeld/.xccurrentversion:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | _XCCurrentVersionName
6 | fbMessenger.xcdatamodel
7 |
8 |
9 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # FBChatClone
2 | 1) Auto Layout Using Code
3 | 2) Core Data Entities: Create, Read, Delete and a lot more operations involving Core Data which would help in understanding the power of Core Data
4 | 3) Creating a Tab Bar Menu Programatically
5 | 4) Creating Chat Bubbles With Tails
6 | 5) How to Auto Update UICollectionView by inserting rows using NSFetchedResultsController
7 | 6) No Storyboards used
8 |
--------------------------------------------------------------------------------
/fbMessenger/Assets.xcassets/calls.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "calls@3x.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/fbMessenger/Assets.xcassets/gandhi.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "gandhi.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/fbMessenger/Assets.xcassets/groups.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "groups@3x.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/fbMessenger/Assets.xcassets/people.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "people@3x.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/fbMessenger/Assets.xcassets/recent.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "recent@3x.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/fbMessenger/Assets.xcassets/settings.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "settings@3x.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/fbMessenger/Assets.xcassets/zuckprofile.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "zuckprofile.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/fbMessenger/Assets.xcassets/bubble_blue.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "bubble_blue@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/fbMessenger/Assets.xcassets/bubble_gray.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "bubble_gray@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/fbMessenger/Assets.xcassets/steve_profile.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "steve_profile.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/fbMessenger/Assets.xcassets/hillary_profile.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "hillary_profile.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/fbMessenger/Assets.xcassets/donald_trump_profile.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "donald_trump_profile.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/fbMessenger.xcodeproj/xcuserdata/VamshiKrishna.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | fbMessenger.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 96988E951EDDD5CA0098F653
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/fbMessenger/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | }
43 | ],
44 | "info" : {
45 | "version" : 1,
46 | "author" : "xcode"
47 | }
48 | }
--------------------------------------------------------------------------------
/fbMessenger/Extensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Extensions.swift
3 | // fbMessenger
4 | //
5 | // Created by Vamshi Krishna on 30/05/17.
6 | // Copyright © 2017 VamshiKrishna. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | extension UIColor{
13 | static func returnRGBColor(r:CGFloat, g:CGFloat, b:CGFloat, alpha:CGFloat) -> UIColor{
14 | return UIColor(red: r/255, green: g/255, blue: b/255, alpha: alpha)
15 | }
16 | }
17 |
18 | extension UIView{
19 | func addConstraintsWithFormat(format:String, views: UIView...){
20 |
21 | var viewsDictionary = [String:UIView]()
22 | for (index, view) in views.enumerated(){
23 | let key = "v\(index)"
24 | view.translatesAutoresizingMaskIntoConstraints = false
25 | viewsDictionary[key] = view
26 | }
27 | addConstraints(NSLayoutConstraint.constraints(withVisualFormat: format, options: NSLayoutFormatOptions(), metrics: nil, views: viewsDictionary))
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/fbMessenger/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIRequiredDeviceCapabilities
26 |
27 | armv7
28 |
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/fbMessenger/CustomTabbarController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CustomTabbarController.swift
3 | // fbMessenger
4 | //
5 | // Created by Vamshi Krishna on 01/06/17.
6 | // Copyright © 2017 VamshiKrishna. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | class CustomTabbarController: UITabBarController {
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 |
16 | let layout = UICollectionViewFlowLayout()
17 | let friendsController = FriendsController(collectionViewLayout: layout)
18 | let recentMessagesControlelr = UINavigationController(rootViewController: friendsController)
19 | recentMessagesControlelr.tabBarItem.title = "Recent"
20 | recentMessagesControlelr.tabBarItem.image = UIImage(named: "recent")
21 |
22 | viewControllers = [recentMessagesControlelr, createDummyTabbarController(title: "Calls", imageName: "calls"), createDummyTabbarController(title: "Groups", imageName: "groups"), createDummyTabbarController(title: "People", imageName: "people"), createDummyTabbarController(title: "Settings", imageName: "settings")]
23 | }
24 |
25 | private func createDummyTabbarController(title:String, imageName:String) -> UINavigationController{
26 | let viewController = UIViewController()
27 | let navController = UINavigationController(rootViewController: viewController)
28 | navController.tabBarItem.title = title
29 | navController.tabBarItem.image = UIImage(named: imageName)
30 | return navController
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/fbMessenger/fbMessenger.xcdatamodeld/fbMessenger.xcdatamodel/contents:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/fbMessenger/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/fbMessenger.xcodeproj/xcuserdata/VamshiKrishna.xcuserdatad/xcschemes/fbMessenger.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/fbMessenger/FriendsControllerHelper.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FriendsControllerHelper.swift
3 | // fbMessenger
4 | //
5 | // Created by Vamshi Krishna on 30/05/17.
6 | // Copyright © 2017 VamshiKrishna. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | import UIKit
12 | import CoreData
13 |
14 | extension FriendsController{
15 |
16 | func clearData(){
17 | guard let delegate = UIApplication.shared.delegate as? AppDelegate else{
18 | return
19 | }
20 |
21 | let context = delegate.persistentContainer.viewContext
22 | do{
23 | let entityNames = ["Friend", "Message"]
24 | for entityName in entityNames{
25 | let fetchRequest = NSFetchRequest(entityName: entityName)
26 | let objects = try (context.fetch(fetchRequest))
27 | for object in objects{
28 | context.delete(object)
29 | }
30 | }
31 | try (context.save())
32 | } catch let error{
33 | print(error)
34 | }
35 | }
36 | func setupData(){
37 | clearData()
38 | guard let delegate =
39 | UIApplication.shared.delegate as? AppDelegate else {
40 | return
41 | }
42 | let context = delegate.persistentContainer.viewContext
43 |
44 | createSteveMessagesWithContext(context: context)
45 |
46 | let donald = NSEntityDescription.insertNewObject(forEntityName: "Friend", into: context) as! Friend
47 | donald.name = "Donald Trump"
48 | donald.profileImageName = "donald_trump_profile"
49 | _=FriendsController.createMessageWithText(text: "My name is Donald Trump!", friend: donald, minutesAgo: 5, context: context)
50 |
51 | let gandhi = NSEntityDescription.insertNewObject(forEntityName: "Friend", into: context) as! Friend
52 | gandhi.name = "Mahatma Gandhi"
53 | gandhi.profileImageName = "gandhi"
54 | _=FriendsController.createMessageWithText(text: "My name is MK Gandhi", friend: gandhi, minutesAgo: 60*36, context: context)
55 |
56 | let hillary = NSEntityDescription.insertNewObject(forEntityName: "Friend", into: context) as! Friend
57 | hillary.name = "Hillary Clinton"
58 | hillary.profileImageName = "hillary_profile"
59 | _=FriendsController.createMessageWithText(text: "My name is Hillary Clinton", friend: hillary, minutesAgo: 8*60*36, context: context)
60 |
61 | do{
62 | try(context.save())
63 | } catch let error{
64 | print (error)
65 | }
66 | }
67 |
68 | private func createSteveMessagesWithContext(context: NSManagedObjectContext){
69 | let steve = NSEntityDescription.insertNewObject(forEntityName: "Friend", into: context) as! Friend
70 | steve.name = "Steve Jobs"
71 | steve.profileImageName = "steve_profile"
72 |
73 | _=FriendsController.createMessageWithText(text: "Hello! I am Jobs!Hello! I am Jobs!Hello! I am Jobs!Hello! I am Jobs!Hello! I am Jobs!Hello! I am Jobs!", friend: steve, minutesAgo: 10, context: context)
74 | _=FriendsController.createMessageWithText(text: "How are you doing?", friend: steve, minutesAgo: 8, context: context)
75 | _=FriendsController.createMessageWithText(text: "How's work? Interested in working for apple?How's work? Interested in working for apple?How's work? Interested in working for apple?", friend: steve, minutesAgo: 7, context: context)
76 |
77 | //response messages
78 | _=FriendsController.createMessageWithText(text: "Yes! I would love to", friend: steve, minutesAgo: 4, context: context, isSender: true)
79 | _=FriendsController.createMessageWithText(text: "Whatever you say!Whatever you say!Whatever you say!Whatever you say!", friend: steve, minutesAgo: 6, context: context, isSender: true)
80 | _=FriendsController.createMessageWithText(text: "Yes! I would be humbled!Yes! I would be humbled!Yes! I would be humbled!Yes! I would be humbled!", friend: steve, minutesAgo: 2, context: context, isSender: true)
81 | }
82 |
83 | static func createMessageWithText(text:String, friend:Friend,minutesAgo:Double, context:NSManagedObjectContext, isSender:Bool = false) -> Message {
84 | let message = NSEntityDescription.insertNewObject(forEntityName: "Message", into: context) as! Message
85 | message.friend = friend
86 | message.text = text
87 | message.date = NSDate().addingTimeInterval(-minutesAgo * 60)
88 | message.isSender = NSNumber(booleanLiteral: isSender) as! Bool
89 | friend.lastMessage = message
90 | return message
91 | }
92 |
93 | }
94 |
--------------------------------------------------------------------------------
/fbMessenger/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // fbMessenger
4 | //
5 | // Created by Vamshi Krishna on 30/05/17.
6 | // Copyright © 2017 VamshiKrishna. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import CoreData
11 |
12 | @UIApplicationMain
13 | class AppDelegate: UIResponder, UIApplicationDelegate {
14 |
15 | var window: UIWindow?
16 |
17 |
18 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
19 | // Override point for customization after application launch.
20 | window = UIWindow(frame:UIScreen.main.bounds)
21 | window?.makeKeyAndVisible()
22 |
23 | window?.rootViewController = CustomTabbarController()
24 |
25 | return true
26 | }
27 |
28 | func applicationWillResignActive(_ application: UIApplication) {
29 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
30 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
31 | }
32 |
33 | func applicationDidEnterBackground(_ application: UIApplication) {
34 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
35 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
36 | }
37 |
38 | func applicationWillEnterForeground(_ application: UIApplication) {
39 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
40 | }
41 |
42 | func applicationDidBecomeActive(_ application: UIApplication) {
43 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
44 | }
45 |
46 | func applicationWillTerminate(_ application: UIApplication) {
47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
48 | // Saves changes in the application's managed object context before the application terminates.
49 | self.saveContext()
50 | }
51 |
52 | // MARK: - Core Data stack
53 |
54 | lazy var persistentContainer: NSPersistentContainer = {
55 | /*
56 | The persistent container for the application. This implementation
57 | creates and returns a container, having loaded the store for the
58 | application to it. This property is optional since there are legitimate
59 | error conditions that could cause the creation of the store to fail.
60 | */
61 | let container = NSPersistentContainer(name: "fbMessenger")
62 | container.loadPersistentStores(completionHandler: { (storeDescription, error) in
63 | if let error = error as NSError? {
64 | // Replace this implementation with code to handle the error appropriately.
65 | // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
66 |
67 | /*
68 | Typical reasons for an error here include:
69 | * The parent directory does not exist, cannot be created, or disallows writing.
70 | * The persistent store is not accessible, due to permissions or data protection when the device is locked.
71 | * The device is out of space.
72 | * The store could not be migrated to the current model version.
73 | Check the error message to determine what the actual problem was.
74 | */
75 | fatalError("Unresolved error \(error), \(error.userInfo)")
76 | }
77 | })
78 | return container
79 | }()
80 |
81 | // MARK: - Core Data Saving support
82 |
83 | func saveContext () {
84 | let context = persistentContainer.viewContext
85 | if context.hasChanges {
86 | do {
87 | try context.save()
88 | } catch {
89 | // Replace this implementation with code to handle the error appropriately.
90 | // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
91 | let nserror = error as NSError
92 | fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
93 | }
94 | }
95 | }
96 |
97 | }
98 |
99 |
--------------------------------------------------------------------------------
/fbMessenger/FriendsController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // fbMessenger
4 | //
5 | // Created by Vamshi Krishna on 30/05/17.
6 | // Copyright © 2017 VamshiKrishna. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import CoreData
11 |
12 | class FriendsController: UICollectionViewController, UICollectionViewDelegateFlowLayout, NSFetchedResultsControllerDelegate {
13 |
14 | private let cellId = "cellId"
15 |
16 | lazy var fetchedResultsController:NSFetchedResultsController = { () -> NSFetchedResultsController in
17 | let fetchRequest = NSFetchRequest(entityName: "Friend")
18 | fetchRequest.sortDescriptors = [NSSortDescriptor(key: "lastMessage.date", ascending: false)]
19 | fetchRequest.predicate = NSPredicate(format:"lastMessage != nil")
20 | let delegate = UIApplication.shared.delegate as?AppDelegate;
21 | let context = delegate?.persistentContainer.viewContext
22 | let frc = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context!, sectionNameKeyPath: nil, cacheName: nil)
23 | frc.delegate = self
24 | return frc
25 | }()
26 |
27 | func controller(_ controller: NSFetchedResultsController, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
28 | if type == .insert{
29 | blockOperations.append(BlockOperation(block: {
30 | (self.collectionView?.insertItems(at: [newIndexPath!]))!
31 | }))
32 | }
33 | }
34 |
35 | var blockOperations = [BlockOperation]()
36 |
37 | func controllerDidChangeContent(_ controller: NSFetchedResultsController) {
38 | collectionView?.performBatchUpdates({
39 | for operation in self.blockOperations{
40 | operation.start()
41 | }
42 | }, completion: { (completed) in
43 | let lastItem = (self.fetchedResultsController.sections?[0].numberOfObjects)! - 1
44 | let indexPath = IndexPath(item: lastItem, section: 0)
45 | self.collectionView?.scrollToItem(at: indexPath, at: .bottom, animated: true)
46 | })
47 | }
48 |
49 | override func viewWillAppear(_ animated: Bool) {
50 | tabBarController?.tabBar.isHidden = false
51 | }
52 | override func viewDidLoad() {
53 | super.viewDidLoad()
54 | navigationItem.title = "Recent"
55 | collectionView?.backgroundColor = .white
56 | collectionView?.alwaysBounceVertical = true
57 | setupData()
58 | collectionView?.register(MessageCell.self, forCellWithReuseIdentifier: cellId)
59 |
60 | do{
61 | try fetchedResultsController.performFetch()
62 | }catch let error{
63 | print(error)
64 | }
65 |
66 | navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Add Mark", style: .plain, target: self, action: #selector(addMark))
67 | }
68 |
69 | func addMark(){
70 | guard let delegate =
71 | UIApplication.shared.delegate as? AppDelegate else {
72 | return
73 | }
74 | let context = delegate.persistentContainer.viewContext
75 | let mark = NSEntityDescription.insertNewObject(forEntityName: "Friend", into: context) as! Friend
76 | mark.name = "Mark Zuckerberg"
77 | mark.profileImageName = "zuckprofile"
78 | _=FriendsController.createMessageWithText(text: "Hey, I am Mark!", friend: mark, minutesAgo: 8*60*36, context: context)
79 |
80 | let bill = NSEntityDescription.insertNewObject(forEntityName: "Friend", into: context) as! Friend
81 | bill.name = "Bill Gates"
82 | mark.profileImageName = "zuckprofile"
83 | _=FriendsController.createMessageWithText(text: "Hey, I am Bill!", friend: bill, minutesAgo: 8*60*24, context: context)
84 | }
85 |
86 | override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
87 | if let count = fetchedResultsController.sections?[section].numberOfObjects{
88 | return count
89 | }
90 | return 0
91 | }
92 |
93 | override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
94 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! MessageCell
95 | let friend = fetchedResultsController.object(at: indexPath) as! Friend
96 | cell.message = friend.lastMessage
97 | return cell
98 | }
99 |
100 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
101 | return CGSize(width: view.frame.width, height: 100)
102 | }
103 |
104 | override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
105 | let layout = UICollectionViewFlowLayout()
106 | let controller = ChatLogController(collectionViewLayout: layout)
107 | let friend = fetchedResultsController.object(at: indexPath) as! Friend
108 | controller.friend = friend
109 | navigationController?.pushViewController(controller, animated: true)
110 | }
111 | }
112 |
113 | class MessageCell:BaseCell{
114 |
115 | override var isHighlighted: Bool{
116 | didSet{
117 | backgroundColor = isHighlighted ? UIColor.returnRGBColor(r: 0, g: 134, b: 249, alpha: 1) : UIColor.white
118 | nameLabel.textColor = isHighlighted ? UIColor.white : UIColor.black
119 | timeLabel.textColor = isHighlighted ? UIColor.white : UIColor.black
120 | messageLabel.textColor = isHighlighted ? UIColor.white : UIColor.black
121 | }
122 | }
123 | var message:Message?{
124 | didSet{
125 | nameLabel.text = message?.friend?.name
126 | messageLabel.text = message?.text
127 |
128 | if let profileImageName = message?.friend?.profileImageName{
129 | profileImageView.image = UIImage(named: profileImageName)
130 | hasReadImageView.image = UIImage(named: profileImageName)
131 | }
132 |
133 | if let date = message?.date{
134 | let dateFormatter = DateFormatter()
135 | dateFormatter.dateFormat = "hh:mm a"
136 | let elapsedTimeInSeconds = NSDate().timeIntervalSince(date as Date)
137 | let secondsInDay : TimeInterval = 60*60*24
138 |
139 | if(elapsedTimeInSeconds > 7*secondsInDay){
140 | dateFormatter.dateFormat = "MM/dd/yy"
141 | } else if elapsedTimeInSeconds > secondsInDay{
142 | dateFormatter.dateFormat = "EEE"
143 | }
144 |
145 | timeLabel.text = dateFormatter.string(from: date as Date)
146 | }
147 | }
148 | }
149 |
150 | let profileImageView:UIImageView = {
151 | let iv = UIImageView()
152 | iv.contentMode = .scaleAspectFill
153 | iv.layer.cornerRadius = 34
154 | iv.layer.masksToBounds = true
155 | return iv
156 | }()
157 |
158 | let nameLabel:UILabel = {
159 | let label = UILabel()
160 | label.text = "Friend's Name"
161 | label.font = UIFont.systemFont(ofSize: 18)
162 | return label
163 | }()
164 |
165 | let messageLabel:UILabel = {
166 | let label = UILabel()
167 | label.text = "Message MessageMessageMessage containerViewcontainerViewcontainerView"
168 | label.textColor = UIColor.darkGray
169 | label.font = UIFont.systemFont(ofSize: 14)
170 | return label
171 | }()
172 |
173 | let timeLabel : UILabel = {
174 | let label = UILabel()
175 | label.text = "09:50 pm"
176 | label.font = UIFont.systemFont(ofSize: 16)
177 | label.textAlignment = .right
178 | return label
179 | }()
180 |
181 | let dividerLineView:UIView = {
182 | let dv = UIView()
183 | dv.backgroundColor = UIColor(white: 0.5, alpha: 0.5)
184 | return dv
185 | }()
186 |
187 | let hasReadImageView : UIImageView = {
188 | let iv = UIImageView()
189 | iv.contentMode = .scaleAspectFill
190 | iv.layer.cornerRadius = 10
191 | iv.layer.masksToBounds = true
192 | return iv
193 | }()
194 |
195 | override func setupViews() {
196 | addSubview(profileImageView)
197 | addSubview(dividerLineView)
198 |
199 | setupContainerView()
200 | profileImageView.image = UIImage(named:"zuckprofile")
201 | hasReadImageView.image = UIImage(named:"zuckprofile")
202 | addConstraintsWithFormat(format: "H:|-12-[v0(68)]", views: profileImageView)
203 | addConstraintsWithFormat(format: "V:[v0(68)]", views: profileImageView)
204 | addConstraint(NSLayoutConstraint(item: profileImageView, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0))
205 |
206 | addConstraintsWithFormat(format: "H:|-82-[v0]|", views: dividerLineView)
207 | addConstraintsWithFormat(format: "V:[v0(1)]|", views: dividerLineView)
208 |
209 | }
210 |
211 | private func setupContainerView() {
212 | let containerView = UIView()
213 | addSubview(containerView)
214 | addConstraintsWithFormat(format: "H:|-90-[v0]|", views: containerView)
215 | addConstraintsWithFormat(format: "V:[v0(50)]", views: containerView)
216 | addConstraint(NSLayoutConstraint(item: containerView, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0))
217 |
218 | containerView.addSubview(nameLabel)
219 | containerView.addSubview(messageLabel)
220 | containerView.addSubview(timeLabel)
221 | containerView.addSubview(hasReadImageView)
222 |
223 | containerView.addConstraintsWithFormat(format: "H:|[v0][v1(80)]-12-|", views: nameLabel, timeLabel)
224 | containerView.addConstraintsWithFormat(format: "V:|[v0][v1(24)]|", views: nameLabel,messageLabel)
225 | containerView.addConstraintsWithFormat(format: "H:|[v0]-8-[v1(20)]-12-|", views: messageLabel, hasReadImageView)
226 | containerView.addConstraintsWithFormat(format: "V:|[v0(24)]", views: timeLabel)
227 | containerView.addConstraintsWithFormat(format: "V:[v0(20)]|", views: hasReadImageView)
228 | }
229 | }
230 |
231 | class BaseCell:UICollectionViewCell{
232 | override init(frame: CGRect) {
233 | super.init(frame: frame)
234 | setupViews()
235 | }
236 |
237 | required init?(coder aDecoder: NSCoder) {
238 | fatalError("init(coder:) has not been implemented")
239 | }
240 |
241 | func setupViews(){
242 |
243 | }
244 | }
245 |
246 |
247 |
--------------------------------------------------------------------------------
/fbMessenger/ChatLogController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ChatLogController.swift
3 | // fbMessenger
4 | //
5 | // Created by Vamshi Krishna on 01/06/17.
6 | // Copyright © 2017 VamshiKrishna. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 | import CoreData
12 |
13 | class ChatLogController: UICollectionViewController , UICollectionViewDelegateFlowLayout, NSFetchedResultsControllerDelegate {
14 |
15 | private let cellId = "cellId"
16 |
17 | var friend:Friend?{
18 | didSet{
19 | navigationItem.title = friend?.name
20 | }
21 | }
22 |
23 | let messageInputContainerView:UIView = {
24 | let view = UIView()
25 | view.backgroundColor = .white
26 | return view
27 | }()
28 |
29 | let inputTextField:UITextField = {
30 | let tf = UITextField()
31 | tf.placeholder = "Enter Message Here"
32 | return tf
33 | }()
34 |
35 | let sendButton:UIButton = {
36 | let button = UIButton(type: .system)
37 | button.setTitle("Send", for: .normal)
38 | let titleColor = UIColor.returnRGBColor(r: 0, g: 137, b: 249, alpha: 1)
39 | button.setTitleColor(titleColor, for: .normal)
40 | button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16)
41 | button.addTarget(self, action: #selector(handleSend), for: .touchUpInside)
42 | return button
43 | }()
44 |
45 | func handleSend(){
46 | guard let delegate = UIApplication.shared.delegate as?AppDelegate else{
47 | return
48 | }
49 | let context = delegate.persistentContainer.viewContext
50 | _ = FriendsController.createMessageWithText(text: inputTextField.text!, friend: friend!, minutesAgo: 2, context: context, isSender: true)
51 |
52 | do{
53 | try context.save()
54 | inputTextField.text = nil
55 |
56 | }catch let error{
57 | print(error)
58 | }
59 | }
60 |
61 | private func setupInputComponents(){
62 | let topBorderView = UIView()
63 | topBorderView.backgroundColor = UIColor(white: 0.5, alpha: 0.5)
64 |
65 | messageInputContainerView.addSubview(inputTextField)
66 | messageInputContainerView.addSubview(sendButton)
67 | messageInputContainerView.addSubview(topBorderView)
68 |
69 | messageInputContainerView.addConstraintsWithFormat(format: "H:|-8-[v0][v1(60)]|", views: inputTextField ,sendButton)
70 | messageInputContainerView.addConstraintsWithFormat(format: "V:|[v0]|", views: inputTextField)
71 | messageInputContainerView.addConstraintsWithFormat(format: "V:|[v0]|", views: sendButton)
72 | messageInputContainerView.addConstraintsWithFormat(format: "H:|[v0]|", views: topBorderView)
73 | messageInputContainerView.addConstraintsWithFormat(format: "V:|[v0(0.5)]", views: topBorderView)
74 | }
75 |
76 | var bottomConstraint:NSLayoutConstraint?
77 |
78 | lazy var fetchedRequestsController:NSFetchedResultsController = { () -> NSFetchedResultsController in
79 | let fetchRequest = NSFetchRequest(entityName: "Message")
80 | fetchRequest.sortDescriptors = [NSSortDescriptor(key: "date", ascending: true)]
81 | fetchRequest.predicate = NSPredicate(format: "friend.name = %@", (self.friend?.name)!)
82 | let delegate = UIApplication.shared.delegate as?AppDelegate;
83 | let context = delegate?.persistentContainer.viewContext
84 | let frc = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context!, sectionNameKeyPath: nil, cacheName: nil)
85 | frc.delegate = self
86 | return frc
87 | }()
88 |
89 | var blockOperations = [BlockOperation]()
90 |
91 | func controller(_ controller: NSFetchedResultsController, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
92 | if type == .insert{
93 | blockOperations.append(BlockOperation(block: {
94 | (self.collectionView?.insertItems(at: [newIndexPath!]))!
95 | }))
96 | }
97 | }
98 |
99 | func controllerDidChangeContent(_ controller: NSFetchedResultsController) {
100 | collectionView?.performBatchUpdates({
101 | for operation in self.blockOperations{
102 | operation.start()
103 | }
104 | }, completion: { (completed) in
105 | let lastItem = (self.fetchedRequestsController.sections?[0].numberOfObjects)! - 1
106 | let indexPath = IndexPath(item: lastItem, section: 0)
107 | self.collectionView?.scrollToItem(at: indexPath, at: .bottom, animated: true)
108 | })
109 | }
110 | override func viewDidLoad() {
111 | super.viewDidLoad()
112 |
113 | do {
114 | try fetchedRequestsController.performFetch()
115 | }catch let error{
116 | print(error)
117 | }
118 |
119 | tabBarController?.tabBar.isHidden = true
120 | collectionView?.backgroundColor = UIColor.white
121 | collectionView?.register(ChatlogCell.self, forCellWithReuseIdentifier: cellId)
122 | view.addSubview(messageInputContainerView)
123 | view.addConstraintsWithFormat(format: "H:|[v0]|", views: messageInputContainerView)
124 | view.addConstraintsWithFormat(format: "V:[v0(48)]", views: messageInputContainerView)
125 | bottomConstraint = NSLayoutConstraint(item: messageInputContainerView, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: 0)
126 | view.addConstraint(bottomConstraint!)
127 | setupInputComponents()
128 | NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboard), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
129 | NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboard), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
130 | navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Simulate", style: .plain, target: self, action: #selector(simulateSenderMessages))
131 | }
132 |
133 | func simulateSenderMessages(){
134 | guard let delegate = UIApplication.shared.delegate as?AppDelegate else{
135 | return
136 | }
137 | let context = delegate.persistentContainer.viewContext
138 | _ = FriendsController.createMessageWithText(text: "This message was sent a few minutes ago....", friend: friend!, minutesAgo: 1, context: context)
139 | _ = FriendsController.createMessageWithText(text: "Another message was sent a few seconds ago....", friend: friend!, minutesAgo: 0, context: context)
140 | do{
141 | try context.save()
142 |
143 | }catch let error{
144 | print(error)
145 | }
146 | }
147 |
148 | func handleKeyboard(notification:NSNotification){
149 | if let userInfo = notification.userInfo{
150 | let keyboardFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as AnyObject).cgRectValue
151 | let isKeyboardShowing = notification.name == NSNotification.Name.UIKeyboardWillShow
152 | bottomConstraint?.constant = isKeyboardShowing ? -(keyboardFrame?.height)! : 0
153 | UIView.animate(withDuration: 0, delay: 0, options: .curveEaseOut, animations: {
154 | self.view.layoutIfNeeded()
155 | }, completion: { (completed) in
156 | if (isKeyboardShowing){
157 | let lastItem = (self.fetchedRequestsController.sections?[0].numberOfObjects)! - 1
158 | let indexPath = IndexPath(item: lastItem, section: 0)
159 | self.collectionView?.scrollToItem(at: indexPath, at: .bottom, animated: true)
160 | }
161 | })
162 |
163 | }
164 | }
165 |
166 | override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
167 | inputTextField.endEditing(true)
168 | }
169 |
170 | override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
171 | if let count = fetchedRequestsController.sections?[0].numberOfObjects{
172 | return count
173 | }
174 | return 0
175 | }
176 |
177 | override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
178 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! ChatlogCell
179 | let message = fetchedRequestsController.object(at: indexPath) as! Message
180 | cell.messageTextView.text = message.text
181 |
182 |
183 | if let messageText = message.text, let profileImageName = message.friend?.profileImageName{
184 |
185 | cell.profileImageView.image = UIImage(named: profileImageName)
186 | let size = CGSize(width: 250, height: 1000)
187 | let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
188 | let estimatedFrame = NSString(string: messageText).boundingRect(with: size, options: options, attributes: [NSFontAttributeName:UIFont.systemFont(ofSize: 18)], context: nil)
189 | if !message.isSender{
190 | cell.messageTextView.frame = CGRect(x: 48+8, y: 0, width: estimatedFrame.width + 16, height: estimatedFrame.height+20)
191 | cell.textBubbleView.frame = CGRect(x: 48 - 10, y: -4, width: estimatedFrame.width + 16 + 8 + 16, height: estimatedFrame.height+20+6)
192 | cell.profileImageView.isHidden = false
193 | cell.bubbleImageView.image = ChatlogCell.grayBubbleImage
194 | cell.bubbleImageView.tintColor = UIColor(white: 0.95, alpha: 1)
195 | cell.messageTextView.textColor = UIColor.black
196 | }
197 | else{
198 |
199 | //outgoing sender messages
200 | cell.messageTextView.frame = CGRect(x: view.frame.width - estimatedFrame.width - 16 - 16 - 8 , y: 0, width: estimatedFrame.width + 16, height: estimatedFrame.height+20)
201 | cell.textBubbleView.frame = CGRect(x: view.frame.width-estimatedFrame.width - 16 - 8 - 16 - 10, y: -4, width: estimatedFrame.width + 16 + 8 + 10, height: estimatedFrame.height+20+6)
202 | cell.profileImageView.isHidden = true
203 | cell.bubbleImageView.image = ChatlogCell.blueBubbleImage
204 | cell.bubbleImageView.tintColor = UIColor.returnRGBColor(r: 0, g: 137, b: 249, alpha: 1)
205 | cell.messageTextView.textColor = UIColor.white
206 | }
207 |
208 | }
209 | return cell
210 | }
211 |
212 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
213 | let message = fetchedRequestsController.object(at: indexPath) as! Message
214 | if let messageText = message.text{
215 | let size = CGSize(width: 250, height: 1000)
216 | let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
217 | let estimatedFrame = NSString(string: messageText).boundingRect(with: size, options: options, attributes: [NSFontAttributeName:UIFont.systemFont(ofSize: 18)], context: nil)
218 | return CGSize(width: view.frame.width, height: estimatedFrame.height+20)
219 | }
220 | return CGSize(width: view.frame.width, height: 100)
221 | }
222 |
223 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
224 | return UIEdgeInsetsMake(8, 0, 0, 0)
225 | }
226 | }
227 |
228 | class ChatlogCell:BaseCell{
229 |
230 | static let grayBubbleImage = UIImage(named:"bubble_gray")?.resizableImage(withCapInsets: UIEdgeInsetsMake(22, 26, 22, 26)).withRenderingMode(.alwaysTemplate)
231 | static let blueBubbleImage = UIImage(named:"bubble_blue")?.resizableImage(withCapInsets: UIEdgeInsetsMake(22, 26, 22, 26)).withRenderingMode(.alwaysTemplate)
232 |
233 |
234 | let messageTextView : UITextView = {
235 | let textView = UITextView()
236 | textView.text = "Sample Message"
237 | textView.font = UIFont.systemFont(ofSize: 18)
238 | textView.backgroundColor = UIColor.clear
239 | textView.isEditable = false
240 | return textView
241 | }()
242 |
243 | let textBubbleView:UIView = {
244 | let view = UIView()
245 | view.layer.cornerRadius = 15
246 | view.layer.masksToBounds = true
247 | return view
248 | }()
249 |
250 | let profileImageView: UIImageView = {
251 | let iv = UIImageView()
252 | iv.layer.cornerRadius = 15
253 | iv.layer.masksToBounds = true
254 | return iv
255 | }()
256 |
257 | let bubbleImageView : UIImageView = {
258 | let iv = UIImageView()
259 | iv.image = ChatlogCell.grayBubbleImage
260 | iv.tintColor = UIColor(white: 0.90, alpha: 1)
261 | return iv
262 | }()
263 |
264 | override func setupViews() {
265 | super.setupViews()
266 |
267 | addSubview(textBubbleView)
268 | addSubview(messageTextView)
269 | addSubview(profileImageView)
270 |
271 | addConstraintsWithFormat(format: "H:|-8-[v0(30)]|", views: profileImageView)
272 | addConstraintsWithFormat(format: "V:[v0(30)]|", views: profileImageView)
273 |
274 | textBubbleView.addSubview(bubbleImageView)
275 | textBubbleView.addConstraintsWithFormat(format: "H:|[v0]|", views: bubbleImageView)
276 | textBubbleView.addConstraintsWithFormat(format: "V:|[v0]|", views: bubbleImageView)
277 |
278 | }
279 |
280 | }
281 |
--------------------------------------------------------------------------------
/fbMessenger.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 967455681EDFC9130010CE2C /* ChatLogController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 967455671EDFC9130010CE2C /* ChatLogController.swift */; };
11 | 9674556A1EDFD5910010CE2C /* CustomTabbarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 967455691EDFD5910010CE2C /* CustomTabbarController.swift */; };
12 | 96988E9A1EDDD5CA0098F653 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96988E991EDDD5CA0098F653 /* AppDelegate.swift */; };
13 | 96988E9C1EDDD5CA0098F653 /* FriendsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96988E9B1EDDD5CA0098F653 /* FriendsController.swift */; };
14 | 96988EA21EDDD5CA0098F653 /* fbMessenger.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 96988EA01EDDD5CA0098F653 /* fbMessenger.xcdatamodeld */; };
15 | 96988EA41EDDD5CA0098F653 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 96988EA31EDDD5CA0098F653 /* Assets.xcassets */; };
16 | 96988EA71EDDD5CA0098F653 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 96988EA51EDDD5CA0098F653 /* LaunchScreen.storyboard */; };
17 | 96988EAF1EDDD6330098F653 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96988EAE1EDDD6330098F653 /* Extensions.swift */; };
18 | 96988EB11EDDD6520098F653 /* FriendsControllerHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96988EB01EDDD6520098F653 /* FriendsControllerHelper.swift */; };
19 | /* End PBXBuildFile section */
20 |
21 | /* Begin PBXFileReference section */
22 | 967455671EDFC9130010CE2C /* ChatLogController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatLogController.swift; sourceTree = ""; };
23 | 967455691EDFD5910010CE2C /* CustomTabbarController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomTabbarController.swift; sourceTree = ""; };
24 | 96988E961EDDD5CA0098F653 /* fbMessenger.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = fbMessenger.app; sourceTree = BUILT_PRODUCTS_DIR; };
25 | 96988E991EDDD5CA0098F653 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
26 | 96988E9B1EDDD5CA0098F653 /* FriendsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FriendsController.swift; sourceTree = ""; };
27 | 96988EA11EDDD5CA0098F653 /* fbMessenger.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = fbMessenger.xcdatamodel; sourceTree = ""; };
28 | 96988EA31EDDD5CA0098F653 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
29 | 96988EA61EDDD5CA0098F653 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
30 | 96988EA81EDDD5CA0098F653 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
31 | 96988EAE1EDDD6330098F653 /* Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; };
32 | 96988EB01EDDD6520098F653 /* FriendsControllerHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FriendsControllerHelper.swift; sourceTree = ""; };
33 | /* End PBXFileReference section */
34 |
35 | /* Begin PBXFrameworksBuildPhase section */
36 | 96988E931EDDD5CA0098F653 /* Frameworks */ = {
37 | isa = PBXFrameworksBuildPhase;
38 | buildActionMask = 2147483647;
39 | files = (
40 | );
41 | runOnlyForDeploymentPostprocessing = 0;
42 | };
43 | /* End PBXFrameworksBuildPhase section */
44 |
45 | /* Begin PBXGroup section */
46 | 96988E8D1EDDD5CA0098F653 = {
47 | isa = PBXGroup;
48 | children = (
49 | 96988E981EDDD5CA0098F653 /* fbMessenger */,
50 | 96988E971EDDD5CA0098F653 /* Products */,
51 | );
52 | sourceTree = "";
53 | };
54 | 96988E971EDDD5CA0098F653 /* Products */ = {
55 | isa = PBXGroup;
56 | children = (
57 | 96988E961EDDD5CA0098F653 /* fbMessenger.app */,
58 | );
59 | name = Products;
60 | sourceTree = "";
61 | };
62 | 96988E981EDDD5CA0098F653 /* fbMessenger */ = {
63 | isa = PBXGroup;
64 | children = (
65 | 96988E991EDDD5CA0098F653 /* AppDelegate.swift */,
66 | 96988E9B1EDDD5CA0098F653 /* FriendsController.swift */,
67 | 967455691EDFD5910010CE2C /* CustomTabbarController.swift */,
68 | 96988EAE1EDDD6330098F653 /* Extensions.swift */,
69 | 967455671EDFC9130010CE2C /* ChatLogController.swift */,
70 | 96988EB01EDDD6520098F653 /* FriendsControllerHelper.swift */,
71 | 96988EA31EDDD5CA0098F653 /* Assets.xcassets */,
72 | 96988EA51EDDD5CA0098F653 /* LaunchScreen.storyboard */,
73 | 96988EA81EDDD5CA0098F653 /* Info.plist */,
74 | 96988EA01EDDD5CA0098F653 /* fbMessenger.xcdatamodeld */,
75 | );
76 | path = fbMessenger;
77 | sourceTree = "";
78 | };
79 | /* End PBXGroup section */
80 |
81 | /* Begin PBXNativeTarget section */
82 | 96988E951EDDD5CA0098F653 /* fbMessenger */ = {
83 | isa = PBXNativeTarget;
84 | buildConfigurationList = 96988EAB1EDDD5CA0098F653 /* Build configuration list for PBXNativeTarget "fbMessenger" */;
85 | buildPhases = (
86 | 96988E921EDDD5CA0098F653 /* Sources */,
87 | 96988E931EDDD5CA0098F653 /* Frameworks */,
88 | 96988E941EDDD5CA0098F653 /* Resources */,
89 | );
90 | buildRules = (
91 | );
92 | dependencies = (
93 | );
94 | name = fbMessenger;
95 | productName = fbMessenger;
96 | productReference = 96988E961EDDD5CA0098F653 /* fbMessenger.app */;
97 | productType = "com.apple.product-type.application";
98 | };
99 | /* End PBXNativeTarget section */
100 |
101 | /* Begin PBXProject section */
102 | 96988E8E1EDDD5CA0098F653 /* Project object */ = {
103 | isa = PBXProject;
104 | attributes = {
105 | LastSwiftUpdateCheck = 0830;
106 | LastUpgradeCheck = 0830;
107 | ORGANIZATIONNAME = VamshiKrishna;
108 | TargetAttributes = {
109 | 96988E951EDDD5CA0098F653 = {
110 | CreatedOnToolsVersion = 8.3.2;
111 | DevelopmentTeam = BJBC582Q56;
112 | ProvisioningStyle = Automatic;
113 | };
114 | };
115 | };
116 | buildConfigurationList = 96988E911EDDD5CA0098F653 /* Build configuration list for PBXProject "fbMessenger" */;
117 | compatibilityVersion = "Xcode 3.2";
118 | developmentRegion = English;
119 | hasScannedForEncodings = 0;
120 | knownRegions = (
121 | en,
122 | Base,
123 | );
124 | mainGroup = 96988E8D1EDDD5CA0098F653;
125 | productRefGroup = 96988E971EDDD5CA0098F653 /* Products */;
126 | projectDirPath = "";
127 | projectRoot = "";
128 | targets = (
129 | 96988E951EDDD5CA0098F653 /* fbMessenger */,
130 | );
131 | };
132 | /* End PBXProject section */
133 |
134 | /* Begin PBXResourcesBuildPhase section */
135 | 96988E941EDDD5CA0098F653 /* Resources */ = {
136 | isa = PBXResourcesBuildPhase;
137 | buildActionMask = 2147483647;
138 | files = (
139 | 96988EA71EDDD5CA0098F653 /* LaunchScreen.storyboard in Resources */,
140 | 96988EA41EDDD5CA0098F653 /* Assets.xcassets in Resources */,
141 | );
142 | runOnlyForDeploymentPostprocessing = 0;
143 | };
144 | /* End PBXResourcesBuildPhase section */
145 |
146 | /* Begin PBXSourcesBuildPhase section */
147 | 96988E921EDDD5CA0098F653 /* Sources */ = {
148 | isa = PBXSourcesBuildPhase;
149 | buildActionMask = 2147483647;
150 | files = (
151 | 967455681EDFC9130010CE2C /* ChatLogController.swift in Sources */,
152 | 96988E9C1EDDD5CA0098F653 /* FriendsController.swift in Sources */,
153 | 96988EA21EDDD5CA0098F653 /* fbMessenger.xcdatamodeld in Sources */,
154 | 96988E9A1EDDD5CA0098F653 /* AppDelegate.swift in Sources */,
155 | 9674556A1EDFD5910010CE2C /* CustomTabbarController.swift in Sources */,
156 | 96988EAF1EDDD6330098F653 /* Extensions.swift in Sources */,
157 | 96988EB11EDDD6520098F653 /* FriendsControllerHelper.swift in Sources */,
158 | );
159 | runOnlyForDeploymentPostprocessing = 0;
160 | };
161 | /* End PBXSourcesBuildPhase section */
162 |
163 | /* Begin PBXVariantGroup section */
164 | 96988EA51EDDD5CA0098F653 /* LaunchScreen.storyboard */ = {
165 | isa = PBXVariantGroup;
166 | children = (
167 | 96988EA61EDDD5CA0098F653 /* Base */,
168 | );
169 | name = LaunchScreen.storyboard;
170 | sourceTree = "";
171 | };
172 | /* End PBXVariantGroup section */
173 |
174 | /* Begin XCBuildConfiguration section */
175 | 96988EA91EDDD5CA0098F653 /* Debug */ = {
176 | isa = XCBuildConfiguration;
177 | buildSettings = {
178 | ALWAYS_SEARCH_USER_PATHS = NO;
179 | CLANG_ANALYZER_NONNULL = YES;
180 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
181 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
182 | CLANG_CXX_LIBRARY = "libc++";
183 | CLANG_ENABLE_MODULES = YES;
184 | CLANG_ENABLE_OBJC_ARC = YES;
185 | CLANG_WARN_BOOL_CONVERSION = YES;
186 | CLANG_WARN_CONSTANT_CONVERSION = YES;
187 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
188 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
189 | CLANG_WARN_EMPTY_BODY = YES;
190 | CLANG_WARN_ENUM_CONVERSION = YES;
191 | CLANG_WARN_INFINITE_RECURSION = YES;
192 | CLANG_WARN_INT_CONVERSION = YES;
193 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
194 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
195 | CLANG_WARN_UNREACHABLE_CODE = YES;
196 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
197 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
198 | COPY_PHASE_STRIP = NO;
199 | DEBUG_INFORMATION_FORMAT = dwarf;
200 | ENABLE_STRICT_OBJC_MSGSEND = YES;
201 | ENABLE_TESTABILITY = YES;
202 | GCC_C_LANGUAGE_STANDARD = gnu99;
203 | GCC_DYNAMIC_NO_PIC = NO;
204 | GCC_NO_COMMON_BLOCKS = YES;
205 | GCC_OPTIMIZATION_LEVEL = 0;
206 | GCC_PREPROCESSOR_DEFINITIONS = (
207 | "DEBUG=1",
208 | "$(inherited)",
209 | );
210 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
211 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
212 | GCC_WARN_UNDECLARED_SELECTOR = YES;
213 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
214 | GCC_WARN_UNUSED_FUNCTION = YES;
215 | GCC_WARN_UNUSED_VARIABLE = YES;
216 | IPHONEOS_DEPLOYMENT_TARGET = 10.3;
217 | MTL_ENABLE_DEBUG_INFO = YES;
218 | ONLY_ACTIVE_ARCH = YES;
219 | SDKROOT = iphoneos;
220 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
221 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
222 | };
223 | name = Debug;
224 | };
225 | 96988EAA1EDDD5CA0098F653 /* Release */ = {
226 | isa = XCBuildConfiguration;
227 | buildSettings = {
228 | ALWAYS_SEARCH_USER_PATHS = NO;
229 | CLANG_ANALYZER_NONNULL = YES;
230 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
231 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
232 | CLANG_CXX_LIBRARY = "libc++";
233 | CLANG_ENABLE_MODULES = YES;
234 | CLANG_ENABLE_OBJC_ARC = YES;
235 | CLANG_WARN_BOOL_CONVERSION = YES;
236 | CLANG_WARN_CONSTANT_CONVERSION = YES;
237 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
238 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
239 | CLANG_WARN_EMPTY_BODY = YES;
240 | CLANG_WARN_ENUM_CONVERSION = YES;
241 | CLANG_WARN_INFINITE_RECURSION = YES;
242 | CLANG_WARN_INT_CONVERSION = YES;
243 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
244 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
245 | CLANG_WARN_UNREACHABLE_CODE = YES;
246 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
247 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
248 | COPY_PHASE_STRIP = NO;
249 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
250 | ENABLE_NS_ASSERTIONS = NO;
251 | ENABLE_STRICT_OBJC_MSGSEND = YES;
252 | GCC_C_LANGUAGE_STANDARD = gnu99;
253 | GCC_NO_COMMON_BLOCKS = YES;
254 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
255 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
256 | GCC_WARN_UNDECLARED_SELECTOR = YES;
257 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
258 | GCC_WARN_UNUSED_FUNCTION = YES;
259 | GCC_WARN_UNUSED_VARIABLE = YES;
260 | IPHONEOS_DEPLOYMENT_TARGET = 10.3;
261 | MTL_ENABLE_DEBUG_INFO = NO;
262 | SDKROOT = iphoneos;
263 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
264 | VALIDATE_PRODUCT = YES;
265 | };
266 | name = Release;
267 | };
268 | 96988EAC1EDDD5CA0098F653 /* Debug */ = {
269 | isa = XCBuildConfiguration;
270 | buildSettings = {
271 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
272 | DEVELOPMENT_TEAM = BJBC582Q56;
273 | INFOPLIST_FILE = fbMessenger/Info.plist;
274 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
275 | PRODUCT_BUNDLE_IDENTIFIER = VamshiKrishna.fbMessenger;
276 | PRODUCT_NAME = "$(TARGET_NAME)";
277 | SWIFT_VERSION = 3.0;
278 | };
279 | name = Debug;
280 | };
281 | 96988EAD1EDDD5CA0098F653 /* Release */ = {
282 | isa = XCBuildConfiguration;
283 | buildSettings = {
284 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
285 | DEVELOPMENT_TEAM = BJBC582Q56;
286 | INFOPLIST_FILE = fbMessenger/Info.plist;
287 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
288 | PRODUCT_BUNDLE_IDENTIFIER = VamshiKrishna.fbMessenger;
289 | PRODUCT_NAME = "$(TARGET_NAME)";
290 | SWIFT_VERSION = 3.0;
291 | };
292 | name = Release;
293 | };
294 | /* End XCBuildConfiguration section */
295 |
296 | /* Begin XCConfigurationList section */
297 | 96988E911EDDD5CA0098F653 /* Build configuration list for PBXProject "fbMessenger" */ = {
298 | isa = XCConfigurationList;
299 | buildConfigurations = (
300 | 96988EA91EDDD5CA0098F653 /* Debug */,
301 | 96988EAA1EDDD5CA0098F653 /* Release */,
302 | );
303 | defaultConfigurationIsVisible = 0;
304 | defaultConfigurationName = Release;
305 | };
306 | 96988EAB1EDDD5CA0098F653 /* Build configuration list for PBXNativeTarget "fbMessenger" */ = {
307 | isa = XCConfigurationList;
308 | buildConfigurations = (
309 | 96988EAC1EDDD5CA0098F653 /* Debug */,
310 | 96988EAD1EDDD5CA0098F653 /* Release */,
311 | );
312 | defaultConfigurationIsVisible = 0;
313 | defaultConfigurationName = Release;
314 | };
315 | /* End XCConfigurationList section */
316 |
317 | /* Begin XCVersionGroup section */
318 | 96988EA01EDDD5CA0098F653 /* fbMessenger.xcdatamodeld */ = {
319 | isa = XCVersionGroup;
320 | children = (
321 | 96988EA11EDDD5CA0098F653 /* fbMessenger.xcdatamodel */,
322 | );
323 | currentVersion = 96988EA11EDDD5CA0098F653 /* fbMessenger.xcdatamodel */;
324 | path = fbMessenger.xcdatamodeld;
325 | sourceTree = "";
326 | versionGroupType = wrapper.xcdatamodel;
327 | };
328 | /* End XCVersionGroup section */
329 | };
330 | rootObject = 96988E8E1EDDD5CA0098F653 /* Project object */;
331 | }
332 |
--------------------------------------------------------------------------------