├── .gitignore ├── LICENSE ├── Mogo-iOS.xcodeproj └── project.pbxproj ├── Mogo-iOS ├── Images.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── LaunchImage.launchimage │ │ └── Contents.json ├── MOGAppDelegate.h ├── MOGAppDelegate.m ├── Models │ ├── MOGMessage.h │ ├── MOGMessage.m │ ├── MOGRoom.h │ ├── MOGRoom.m │ ├── MOGUser.h │ └── MOGUser.m ├── Mogo-iOS-Info.plist ├── Mogo-iOS-Prefix.pch ├── Networking │ ├── MOGAPIClient.h │ ├── MOGAPIClient.m │ ├── MOGBaseService.h │ ├── MOGBaseService.m │ ├── MOGMessagePoller.h │ ├── MOGMessagePoller.m │ ├── MOGMessageService.h │ ├── MOGMessageService.m │ ├── MOGRoomService.h │ ├── MOGRoomService.m │ ├── MOGSessionService.h │ └── MOGSessionService.m ├── Storyboard.storyboard ├── ViewControllers │ ├── MOGChatViewController.h │ ├── MOGChatViewController.m │ ├── MOGLoginViewController.h │ ├── MOGLoginViewController.m │ ├── MOGNewRoomViewController.h │ ├── MOGNewRoomViewController.m │ ├── MOGRoomsTableViewController.h │ └── MOGRoomsTableViewController.m ├── Views │ ├── MOGAvatarFactory.h │ └── MOGAvatarFactory.m ├── en.lproj │ └── InfoPlist.strings └── main.m ├── Podfile ├── README.md └── screenshots ├── add-room.png ├── chat.png ├── room-overview.png └── sign-in.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | build/* 3 | *.pbxuser 4 | !default.pbxuser 5 | *.mode1v3 6 | !default.mode1v3 7 | *.mode2v3 8 | !default.mode2v3 9 | *.perspectivev3 10 | !default.perspectivev3 11 | *.xcworkspace 12 | !default.xcworkspace 13 | xcuserdata 14 | profile 15 | *.moved-aside 16 | 17 | docset-installed.txt 18 | .DS_Store 19 | */xcuserdata/ 20 | 21 | Podfile.lock 22 | Pods/* 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Jurre 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /Mogo-iOS.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0727EF3C18E3880A0023F2BE /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0727EF3B18E3880A0023F2BE /* Foundation.framework */; }; 11 | 0727EF3E18E3880A0023F2BE /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0727EF3D18E3880A0023F2BE /* CoreGraphics.framework */; }; 12 | 0727EF4018E3880A0023F2BE /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0727EF3F18E3880A0023F2BE /* UIKit.framework */; }; 13 | 0727EF4318E3880A0023F2BE /* Podfile in Resources */ = {isa = PBXBuildFile; fileRef = 0727EF4218E3880A0023F2BE /* Podfile */; }; 14 | 0727EF4918E3880A0023F2BE /* MOGAPIClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 0727EF4818E3880A0023F2BE /* MOGAPIClient.m */; }; 15 | 0727EF4D18E3880A0023F2BE /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0727EF4B18E3880A0023F2BE /* InfoPlist.strings */; }; 16 | 0727EF4F18E3880A0023F2BE /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 0727EF4E18E3880A0023F2BE /* main.m */; }; 17 | 0727EF5218E3880A0023F2BE /* MOGAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 0727EF5118E3880A0023F2BE /* MOGAppDelegate.m */; }; 18 | 0727EF5418E3880A0023F2BE /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0727EF5318E3880A0023F2BE /* Images.xcassets */; }; 19 | 0727EF5B18E3880A0023F2BE /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0727EF5A18E3880A0023F2BE /* XCTest.framework */; }; 20 | 0727EF5C18E3880A0023F2BE /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0727EF3B18E3880A0023F2BE /* Foundation.framework */; }; 21 | 0727EF5D18E3880A0023F2BE /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0727EF3F18E3880A0023F2BE /* UIKit.framework */; }; 22 | 0727EF7518E38F390023F2BE /* MOGRoomService.m in Sources */ = {isa = PBXBuildFile; fileRef = 0727EF7418E38F390023F2BE /* MOGRoomService.m */; }; 23 | 0727EF7918E391270023F2BE /* MOGLoginViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0727EF7818E391270023F2BE /* MOGLoginViewController.m */; }; 24 | 0727EF7B18E3916A0023F2BE /* Storyboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0727EF7A18E3916A0023F2BE /* Storyboard.storyboard */; }; 25 | 0727EF7E18E398870023F2BE /* MOGRoomsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0727EF7D18E398870023F2BE /* MOGRoomsTableViewController.m */; }; 26 | 073191D218E3A6A5003107B6 /* MOGRoom.m in Sources */ = {isa = PBXBuildFile; fileRef = 073191D118E3A6A5003107B6 /* MOGRoom.m */; }; 27 | 073191D518E41BDF003107B6 /* MOGChatViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 073191D418E41BDF003107B6 /* MOGChatViewController.m */; }; 28 | 07563CD318F15C2C00F66E24 /* MOGSessionService.m in Sources */ = {isa = PBXBuildFile; fileRef = 07563CD218F15C2C00F66E24 /* MOGSessionService.m */; }; 29 | 07563CD618F15D8300F66E24 /* MOGBaseService.m in Sources */ = {isa = PBXBuildFile; fileRef = 07563CD518F15D8300F66E24 /* MOGBaseService.m */; }; 30 | 07563CD918F1602B00F66E24 /* MOGUser.m in Sources */ = {isa = PBXBuildFile; fileRef = 07563CD818F1602B00F66E24 /* MOGUser.m */; }; 31 | 0795D10118E839DC006670C3 /* MOGMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 0795D10018E839DC006670C3 /* MOGMessage.m */; }; 32 | 0795D10418E83B6E006670C3 /* MOGMessageService.m in Sources */ = {isa = PBXBuildFile; fileRef = 0795D10318E83B6E006670C3 /* MOGMessageService.m */; }; 33 | 0795D10818E8721F006670C3 /* MOGAvatarFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = 0795D10718E8721F006670C3 /* MOGAvatarFactory.m */; }; 34 | 07A906A318F17FF600E5CEE8 /* MOGMessagePoller.m in Sources */ = {isa = PBXBuildFile; fileRef = 07A906A218F17FF600E5CEE8 /* MOGMessagePoller.m */; }; 35 | 07A906A618F1A55100E5CEE8 /* MOGNewRoomViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 07A906A518F1A55100E5CEE8 /* MOGNewRoomViewController.m */; }; 36 | 3B836B528D0C44BF95A800AF /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8F69626033574422A44E44A5 /* libPods.a */; }; 37 | /* End PBXBuildFile section */ 38 | 39 | /* Begin PBXContainerItemProxy section */ 40 | 0727EF5E18E3880A0023F2BE /* PBXContainerItemProxy */ = { 41 | isa = PBXContainerItemProxy; 42 | containerPortal = 0727EF3018E3880A0023F2BE /* Project object */; 43 | proxyType = 1; 44 | remoteGlobalIDString = 0727EF3718E3880A0023F2BE; 45 | remoteInfo = "Mogo-iOS"; 46 | }; 47 | /* End PBXContainerItemProxy section */ 48 | 49 | /* Begin PBXFileReference section */ 50 | 0727EF3818E3880A0023F2BE /* Mogo-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Mogo-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 51 | 0727EF3B18E3880A0023F2BE /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 52 | 0727EF3D18E3880A0023F2BE /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 53 | 0727EF3F18E3880A0023F2BE /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 54 | 0727EF4218E3880A0023F2BE /* Podfile */ = {isa = PBXFileReference; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 55 | 0727EF4518E3880A0023F2BE /* Mogo-iOS-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Mogo-iOS-Prefix.pch"; sourceTree = ""; }; 56 | 0727EF4718E3880A0023F2BE /* MOGAPIClient.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MOGAPIClient.h; path = Networking/MOGAPIClient.h; sourceTree = ""; }; 57 | 0727EF4818E3880A0023F2BE /* MOGAPIClient.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = MOGAPIClient.m; path = Networking/MOGAPIClient.m; sourceTree = ""; }; 58 | 0727EF4A18E3880A0023F2BE /* Mogo-iOS-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Mogo-iOS-Info.plist"; sourceTree = ""; }; 59 | 0727EF4C18E3880A0023F2BE /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 60 | 0727EF4E18E3880A0023F2BE /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 61 | 0727EF5018E3880A0023F2BE /* MOGAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MOGAppDelegate.h; sourceTree = ""; }; 62 | 0727EF5118E3880A0023F2BE /* MOGAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MOGAppDelegate.m; sourceTree = ""; }; 63 | 0727EF5318E3880A0023F2BE /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 64 | 0727EF5918E3880A0023F2BE /* Mogo-iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Mogo-iOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 65 | 0727EF5A18E3880A0023F2BE /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 66 | 0727EF7318E38F390023F2BE /* MOGRoomService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MOGRoomService.h; path = Networking/MOGRoomService.h; sourceTree = ""; }; 67 | 0727EF7418E38F390023F2BE /* MOGRoomService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MOGRoomService.m; path = Networking/MOGRoomService.m; sourceTree = ""; }; 68 | 0727EF7718E391270023F2BE /* MOGLoginViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MOGLoginViewController.h; path = ViewControllers/MOGLoginViewController.h; sourceTree = ""; }; 69 | 0727EF7818E391270023F2BE /* MOGLoginViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MOGLoginViewController.m; path = ViewControllers/MOGLoginViewController.m; sourceTree = ""; }; 70 | 0727EF7A18E3916A0023F2BE /* Storyboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Storyboard.storyboard; sourceTree = ""; }; 71 | 0727EF7C18E398870023F2BE /* MOGRoomsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MOGRoomsTableViewController.h; path = ViewControllers/MOGRoomsTableViewController.h; sourceTree = ""; }; 72 | 0727EF7D18E398870023F2BE /* MOGRoomsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MOGRoomsTableViewController.m; path = ViewControllers/MOGRoomsTableViewController.m; sourceTree = ""; }; 73 | 073191D018E3A6A5003107B6 /* MOGRoom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MOGRoom.h; path = Models/MOGRoom.h; sourceTree = ""; }; 74 | 073191D118E3A6A5003107B6 /* MOGRoom.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MOGRoom.m; path = Models/MOGRoom.m; sourceTree = ""; }; 75 | 073191D318E41BDF003107B6 /* MOGChatViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MOGChatViewController.h; path = ViewControllers/MOGChatViewController.h; sourceTree = ""; }; 76 | 073191D418E41BDF003107B6 /* MOGChatViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MOGChatViewController.m; path = ViewControllers/MOGChatViewController.m; sourceTree = ""; }; 77 | 07563CD118F15C2C00F66E24 /* MOGSessionService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MOGSessionService.h; path = Networking/MOGSessionService.h; sourceTree = ""; }; 78 | 07563CD218F15C2C00F66E24 /* MOGSessionService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MOGSessionService.m; path = Networking/MOGSessionService.m; sourceTree = ""; }; 79 | 07563CD418F15D8300F66E24 /* MOGBaseService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MOGBaseService.h; path = Networking/MOGBaseService.h; sourceTree = ""; }; 80 | 07563CD518F15D8300F66E24 /* MOGBaseService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MOGBaseService.m; path = Networking/MOGBaseService.m; sourceTree = ""; }; 81 | 07563CD718F1602B00F66E24 /* MOGUser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MOGUser.h; path = Models/MOGUser.h; sourceTree = ""; }; 82 | 07563CD818F1602B00F66E24 /* MOGUser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MOGUser.m; path = Models/MOGUser.m; sourceTree = ""; }; 83 | 0795D0FF18E839DC006670C3 /* MOGMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MOGMessage.h; path = Models/MOGMessage.h; sourceTree = ""; }; 84 | 0795D10018E839DC006670C3 /* MOGMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MOGMessage.m; path = Models/MOGMessage.m; sourceTree = ""; }; 85 | 0795D10218E83B6E006670C3 /* MOGMessageService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MOGMessageService.h; path = Networking/MOGMessageService.h; sourceTree = ""; }; 86 | 0795D10318E83B6E006670C3 /* MOGMessageService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MOGMessageService.m; path = Networking/MOGMessageService.m; sourceTree = ""; }; 87 | 0795D10618E8721F006670C3 /* MOGAvatarFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MOGAvatarFactory.h; path = Views/MOGAvatarFactory.h; sourceTree = ""; }; 88 | 0795D10718E8721F006670C3 /* MOGAvatarFactory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MOGAvatarFactory.m; path = Views/MOGAvatarFactory.m; sourceTree = ""; }; 89 | 07A906A118F17FF600E5CEE8 /* MOGMessagePoller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MOGMessagePoller.h; path = Networking/MOGMessagePoller.h; sourceTree = ""; }; 90 | 07A906A218F17FF600E5CEE8 /* MOGMessagePoller.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MOGMessagePoller.m; path = Networking/MOGMessagePoller.m; sourceTree = ""; }; 91 | 07A906A418F1A55100E5CEE8 /* MOGNewRoomViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MOGNewRoomViewController.h; path = ViewControllers/MOGNewRoomViewController.h; sourceTree = ""; }; 92 | 07A906A518F1A55100E5CEE8 /* MOGNewRoomViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MOGNewRoomViewController.m; path = ViewControllers/MOGNewRoomViewController.m; sourceTree = ""; }; 93 | 8F69626033574422A44E44A5 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; 94 | 94F6D6A1E34249C8A5A2EEC1 /* Pods.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.xcconfig; path = Pods/Pods.xcconfig; sourceTree = ""; }; 95 | /* End PBXFileReference section */ 96 | 97 | /* Begin PBXFrameworksBuildPhase section */ 98 | 0727EF3518E3880A0023F2BE /* Frameworks */ = { 99 | isa = PBXFrameworksBuildPhase; 100 | buildActionMask = 2147483647; 101 | files = ( 102 | 0727EF3E18E3880A0023F2BE /* CoreGraphics.framework in Frameworks */, 103 | 0727EF4018E3880A0023F2BE /* UIKit.framework in Frameworks */, 104 | 0727EF3C18E3880A0023F2BE /* Foundation.framework in Frameworks */, 105 | 3B836B528D0C44BF95A800AF /* libPods.a in Frameworks */, 106 | ); 107 | runOnlyForDeploymentPostprocessing = 0; 108 | }; 109 | 0727EF5618E3880A0023F2BE /* Frameworks */ = { 110 | isa = PBXFrameworksBuildPhase; 111 | buildActionMask = 2147483647; 112 | files = ( 113 | 0727EF5B18E3880A0023F2BE /* XCTest.framework in Frameworks */, 114 | 0727EF5D18E3880A0023F2BE /* UIKit.framework in Frameworks */, 115 | 0727EF5C18E3880A0023F2BE /* Foundation.framework in Frameworks */, 116 | ); 117 | runOnlyForDeploymentPostprocessing = 0; 118 | }; 119 | /* End PBXFrameworksBuildPhase section */ 120 | 121 | /* Begin PBXGroup section */ 122 | 0727EF2F18E3880A0023F2BE = { 123 | isa = PBXGroup; 124 | children = ( 125 | 0727EF4118E3880A0023F2BE /* Mogo-iOS */, 126 | 0727EF3A18E3880A0023F2BE /* Frameworks */, 127 | 0727EF3918E3880A0023F2BE /* Products */, 128 | 94F6D6A1E34249C8A5A2EEC1 /* Pods.xcconfig */, 129 | ); 130 | sourceTree = ""; 131 | }; 132 | 0727EF3918E3880A0023F2BE /* Products */ = { 133 | isa = PBXGroup; 134 | children = ( 135 | 0727EF3818E3880A0023F2BE /* Mogo-iOS.app */, 136 | 0727EF5918E3880A0023F2BE /* Mogo-iOSTests.xctest */, 137 | ); 138 | name = Products; 139 | sourceTree = ""; 140 | }; 141 | 0727EF3A18E3880A0023F2BE /* Frameworks */ = { 142 | isa = PBXGroup; 143 | children = ( 144 | 0727EF3B18E3880A0023F2BE /* Foundation.framework */, 145 | 0727EF3D18E3880A0023F2BE /* CoreGraphics.framework */, 146 | 0727EF3F18E3880A0023F2BE /* UIKit.framework */, 147 | 0727EF5A18E3880A0023F2BE /* XCTest.framework */, 148 | 8F69626033574422A44E44A5 /* libPods.a */, 149 | ); 150 | name = Frameworks; 151 | sourceTree = ""; 152 | }; 153 | 0727EF4118E3880A0023F2BE /* Mogo-iOS */ = { 154 | isa = PBXGroup; 155 | children = ( 156 | 0795D10518E87201006670C3 /* Views */, 157 | 073191CF18E3A68E003107B6 /* Models */, 158 | 0727EF7618E390FE0023F2BE /* ViewControllers */, 159 | 0727EF4218E3880A0023F2BE /* Podfile */, 160 | 0727EF5018E3880A0023F2BE /* MOGAppDelegate.h */, 161 | 0727EF5118E3880A0023F2BE /* MOGAppDelegate.m */, 162 | 0727EF5318E3880A0023F2BE /* Images.xcassets */, 163 | 0727EF4618E3880A0023F2BE /* Networking */, 164 | 0727EF4418E3880A0023F2BE /* Supporting Files */, 165 | 0727EF7A18E3916A0023F2BE /* Storyboard.storyboard */, 166 | ); 167 | path = "Mogo-iOS"; 168 | sourceTree = ""; 169 | }; 170 | 0727EF4418E3880A0023F2BE /* Supporting Files */ = { 171 | isa = PBXGroup; 172 | children = ( 173 | 0727EF4518E3880A0023F2BE /* Mogo-iOS-Prefix.pch */, 174 | 0727EF4A18E3880A0023F2BE /* Mogo-iOS-Info.plist */, 175 | 0727EF4B18E3880A0023F2BE /* InfoPlist.strings */, 176 | 0727EF4E18E3880A0023F2BE /* main.m */, 177 | ); 178 | name = "Supporting Files"; 179 | sourceTree = ""; 180 | }; 181 | 0727EF4618E3880A0023F2BE /* Networking */ = { 182 | isa = PBXGroup; 183 | children = ( 184 | 0727EF4718E3880A0023F2BE /* MOGAPIClient.h */, 185 | 0727EF4818E3880A0023F2BE /* MOGAPIClient.m */, 186 | 0727EF7318E38F390023F2BE /* MOGRoomService.h */, 187 | 0727EF7418E38F390023F2BE /* MOGRoomService.m */, 188 | 0795D10218E83B6E006670C3 /* MOGMessageService.h */, 189 | 0795D10318E83B6E006670C3 /* MOGMessageService.m */, 190 | 07563CD118F15C2C00F66E24 /* MOGSessionService.h */, 191 | 07563CD218F15C2C00F66E24 /* MOGSessionService.m */, 192 | 07563CD418F15D8300F66E24 /* MOGBaseService.h */, 193 | 07563CD518F15D8300F66E24 /* MOGBaseService.m */, 194 | 07A906A118F17FF600E5CEE8 /* MOGMessagePoller.h */, 195 | 07A906A218F17FF600E5CEE8 /* MOGMessagePoller.m */, 196 | ); 197 | name = Networking; 198 | sourceTree = ""; 199 | }; 200 | 0727EF7618E390FE0023F2BE /* ViewControllers */ = { 201 | isa = PBXGroup; 202 | children = ( 203 | 0727EF7718E391270023F2BE /* MOGLoginViewController.h */, 204 | 0727EF7818E391270023F2BE /* MOGLoginViewController.m */, 205 | 0727EF7C18E398870023F2BE /* MOGRoomsTableViewController.h */, 206 | 0727EF7D18E398870023F2BE /* MOGRoomsTableViewController.m */, 207 | 073191D318E41BDF003107B6 /* MOGChatViewController.h */, 208 | 073191D418E41BDF003107B6 /* MOGChatViewController.m */, 209 | 07A906A418F1A55100E5CEE8 /* MOGNewRoomViewController.h */, 210 | 07A906A518F1A55100E5CEE8 /* MOGNewRoomViewController.m */, 211 | ); 212 | name = ViewControllers; 213 | sourceTree = ""; 214 | }; 215 | 073191CF18E3A68E003107B6 /* Models */ = { 216 | isa = PBXGroup; 217 | children = ( 218 | 073191D018E3A6A5003107B6 /* MOGRoom.h */, 219 | 073191D118E3A6A5003107B6 /* MOGRoom.m */, 220 | 0795D0FF18E839DC006670C3 /* MOGMessage.h */, 221 | 0795D10018E839DC006670C3 /* MOGMessage.m */, 222 | 07563CD718F1602B00F66E24 /* MOGUser.h */, 223 | 07563CD818F1602B00F66E24 /* MOGUser.m */, 224 | ); 225 | name = Models; 226 | sourceTree = ""; 227 | }; 228 | 0795D10518E87201006670C3 /* Views */ = { 229 | isa = PBXGroup; 230 | children = ( 231 | 0795D10618E8721F006670C3 /* MOGAvatarFactory.h */, 232 | 0795D10718E8721F006670C3 /* MOGAvatarFactory.m */, 233 | ); 234 | name = Views; 235 | sourceTree = ""; 236 | }; 237 | /* End PBXGroup section */ 238 | 239 | /* Begin PBXNativeTarget section */ 240 | 0727EF3718E3880A0023F2BE /* Mogo-iOS */ = { 241 | isa = PBXNativeTarget; 242 | buildConfigurationList = 0727EF6A18E3880A0023F2BE /* Build configuration list for PBXNativeTarget "Mogo-iOS" */; 243 | buildPhases = ( 244 | E45D856A015647A18EE4A786 /* Check Pods Manifest.lock */, 245 | 0727EF3418E3880A0023F2BE /* Sources */, 246 | 0727EF3518E3880A0023F2BE /* Frameworks */, 247 | 0727EF3618E3880A0023F2BE /* Resources */, 248 | 9AFA8BA88AAE4535B4940961 /* Copy Pods Resources */, 249 | ); 250 | buildRules = ( 251 | ); 252 | dependencies = ( 253 | ); 254 | name = "Mogo-iOS"; 255 | productName = "Mogo-iOS"; 256 | productReference = 0727EF3818E3880A0023F2BE /* Mogo-iOS.app */; 257 | productType = "com.apple.product-type.application"; 258 | }; 259 | 0727EF5818E3880A0023F2BE /* Mogo-iOSTests */ = { 260 | isa = PBXNativeTarget; 261 | buildConfigurationList = 0727EF6D18E3880A0023F2BE /* Build configuration list for PBXNativeTarget "Mogo-iOSTests" */; 262 | buildPhases = ( 263 | 0727EF5518E3880A0023F2BE /* Sources */, 264 | 0727EF5618E3880A0023F2BE /* Frameworks */, 265 | 0727EF5718E3880A0023F2BE /* Resources */, 266 | ); 267 | buildRules = ( 268 | ); 269 | dependencies = ( 270 | 0727EF5F18E3880A0023F2BE /* PBXTargetDependency */, 271 | ); 272 | name = "Mogo-iOSTests"; 273 | productName = "Mogo-iOSTests"; 274 | productReference = 0727EF5918E3880A0023F2BE /* Mogo-iOSTests.xctest */; 275 | productType = "com.apple.product-type.bundle.unit-test"; 276 | }; 277 | /* End PBXNativeTarget section */ 278 | 279 | /* Begin PBXProject section */ 280 | 0727EF3018E3880A0023F2BE /* Project object */ = { 281 | isa = PBXProject; 282 | attributes = { 283 | CLASSPREFIX = MOG; 284 | LastUpgradeCheck = 0510; 285 | ORGANIZATIONNAME = jurre; 286 | TargetAttributes = { 287 | 0727EF5818E3880A0023F2BE = { 288 | TestTargetID = 0727EF3718E3880A0023F2BE; 289 | }; 290 | }; 291 | }; 292 | buildConfigurationList = 0727EF3318E3880A0023F2BE /* Build configuration list for PBXProject "Mogo-iOS" */; 293 | compatibilityVersion = "Xcode 3.2"; 294 | developmentRegion = English; 295 | hasScannedForEncodings = 0; 296 | knownRegions = ( 297 | en, 298 | ); 299 | mainGroup = 0727EF2F18E3880A0023F2BE; 300 | productRefGroup = 0727EF3918E3880A0023F2BE /* Products */; 301 | projectDirPath = ""; 302 | projectRoot = ""; 303 | targets = ( 304 | 0727EF3718E3880A0023F2BE /* Mogo-iOS */, 305 | 0727EF5818E3880A0023F2BE /* Mogo-iOSTests */, 306 | ); 307 | }; 308 | /* End PBXProject section */ 309 | 310 | /* Begin PBXResourcesBuildPhase section */ 311 | 0727EF3618E3880A0023F2BE /* Resources */ = { 312 | isa = PBXResourcesBuildPhase; 313 | buildActionMask = 2147483647; 314 | files = ( 315 | 0727EF5418E3880A0023F2BE /* Images.xcassets in Resources */, 316 | 0727EF7B18E3916A0023F2BE /* Storyboard.storyboard in Resources */, 317 | 0727EF4318E3880A0023F2BE /* Podfile in Resources */, 318 | 0727EF4D18E3880A0023F2BE /* InfoPlist.strings in Resources */, 319 | ); 320 | runOnlyForDeploymentPostprocessing = 0; 321 | }; 322 | 0727EF5718E3880A0023F2BE /* Resources */ = { 323 | isa = PBXResourcesBuildPhase; 324 | buildActionMask = 2147483647; 325 | files = ( 326 | ); 327 | runOnlyForDeploymentPostprocessing = 0; 328 | }; 329 | /* End PBXResourcesBuildPhase section */ 330 | 331 | /* Begin PBXShellScriptBuildPhase section */ 332 | 9AFA8BA88AAE4535B4940961 /* Copy Pods Resources */ = { 333 | isa = PBXShellScriptBuildPhase; 334 | buildActionMask = 2147483647; 335 | files = ( 336 | ); 337 | inputPaths = ( 338 | ); 339 | name = "Copy Pods Resources"; 340 | outputPaths = ( 341 | ); 342 | runOnlyForDeploymentPostprocessing = 0; 343 | shellPath = /bin/sh; 344 | shellScript = "\"${SRCROOT}/Pods/Pods-resources.sh\"\n"; 345 | showEnvVarsInLog = 0; 346 | }; 347 | E45D856A015647A18EE4A786 /* Check Pods Manifest.lock */ = { 348 | isa = PBXShellScriptBuildPhase; 349 | buildActionMask = 2147483647; 350 | files = ( 351 | ); 352 | inputPaths = ( 353 | ); 354 | name = "Check Pods Manifest.lock"; 355 | outputPaths = ( 356 | ); 357 | runOnlyForDeploymentPostprocessing = 0; 358 | shellPath = /bin/sh; 359 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; 360 | showEnvVarsInLog = 0; 361 | }; 362 | /* End PBXShellScriptBuildPhase section */ 363 | 364 | /* Begin PBXSourcesBuildPhase section */ 365 | 0727EF3418E3880A0023F2BE /* Sources */ = { 366 | isa = PBXSourcesBuildPhase; 367 | buildActionMask = 2147483647; 368 | files = ( 369 | 0727EF7E18E398870023F2BE /* MOGRoomsTableViewController.m in Sources */, 370 | 0795D10818E8721F006670C3 /* MOGAvatarFactory.m in Sources */, 371 | 07563CD318F15C2C00F66E24 /* MOGSessionService.m in Sources */, 372 | 0727EF7518E38F390023F2BE /* MOGRoomService.m in Sources */, 373 | 0727EF4F18E3880A0023F2BE /* main.m in Sources */, 374 | 0795D10418E83B6E006670C3 /* MOGMessageService.m in Sources */, 375 | 07A906A318F17FF600E5CEE8 /* MOGMessagePoller.m in Sources */, 376 | 07563CD918F1602B00F66E24 /* MOGUser.m in Sources */, 377 | 07563CD618F15D8300F66E24 /* MOGBaseService.m in Sources */, 378 | 0727EF4918E3880A0023F2BE /* MOGAPIClient.m in Sources */, 379 | 073191D518E41BDF003107B6 /* MOGChatViewController.m in Sources */, 380 | 073191D218E3A6A5003107B6 /* MOGRoom.m in Sources */, 381 | 0727EF7918E391270023F2BE /* MOGLoginViewController.m in Sources */, 382 | 0795D10118E839DC006670C3 /* MOGMessage.m in Sources */, 383 | 07A906A618F1A55100E5CEE8 /* MOGNewRoomViewController.m in Sources */, 384 | 0727EF5218E3880A0023F2BE /* MOGAppDelegate.m in Sources */, 385 | ); 386 | runOnlyForDeploymentPostprocessing = 0; 387 | }; 388 | 0727EF5518E3880A0023F2BE /* Sources */ = { 389 | isa = PBXSourcesBuildPhase; 390 | buildActionMask = 2147483647; 391 | files = ( 392 | ); 393 | runOnlyForDeploymentPostprocessing = 0; 394 | }; 395 | /* End PBXSourcesBuildPhase section */ 396 | 397 | /* Begin PBXTargetDependency section */ 398 | 0727EF5F18E3880A0023F2BE /* PBXTargetDependency */ = { 399 | isa = PBXTargetDependency; 400 | target = 0727EF3718E3880A0023F2BE /* Mogo-iOS */; 401 | targetProxy = 0727EF5E18E3880A0023F2BE /* PBXContainerItemProxy */; 402 | }; 403 | /* End PBXTargetDependency section */ 404 | 405 | /* Begin PBXVariantGroup section */ 406 | 0727EF4B18E3880A0023F2BE /* InfoPlist.strings */ = { 407 | isa = PBXVariantGroup; 408 | children = ( 409 | 0727EF4C18E3880A0023F2BE /* en */, 410 | ); 411 | name = InfoPlist.strings; 412 | sourceTree = ""; 413 | }; 414 | /* End PBXVariantGroup section */ 415 | 416 | /* Begin XCBuildConfiguration section */ 417 | 0727EF6818E3880A0023F2BE /* Debug */ = { 418 | isa = XCBuildConfiguration; 419 | buildSettings = { 420 | ALWAYS_SEARCH_USER_PATHS = NO; 421 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 422 | CLANG_CXX_LIBRARY = "libc++"; 423 | CLANG_ENABLE_MODULES = YES; 424 | CLANG_ENABLE_OBJC_ARC = YES; 425 | CLANG_WARN_BOOL_CONVERSION = YES; 426 | CLANG_WARN_CONSTANT_CONVERSION = YES; 427 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 428 | CLANG_WARN_EMPTY_BODY = YES; 429 | CLANG_WARN_ENUM_CONVERSION = YES; 430 | CLANG_WARN_INT_CONVERSION = YES; 431 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 432 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 433 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 434 | COPY_PHASE_STRIP = NO; 435 | GCC_C_LANGUAGE_STANDARD = gnu99; 436 | GCC_DYNAMIC_NO_PIC = NO; 437 | GCC_OPTIMIZATION_LEVEL = 0; 438 | GCC_PREPROCESSOR_DEFINITIONS = ( 439 | "DEBUG=1", 440 | "$(inherited)", 441 | ); 442 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 443 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 444 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 445 | GCC_WARN_UNDECLARED_SELECTOR = YES; 446 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 447 | GCC_WARN_UNUSED_FUNCTION = YES; 448 | GCC_WARN_UNUSED_VARIABLE = YES; 449 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 450 | ONLY_ACTIVE_ARCH = YES; 451 | SDKROOT = iphoneos; 452 | TARGETED_DEVICE_FAMILY = "1,2"; 453 | }; 454 | name = Debug; 455 | }; 456 | 0727EF6918E3880A0023F2BE /* Release */ = { 457 | isa = XCBuildConfiguration; 458 | buildSettings = { 459 | ALWAYS_SEARCH_USER_PATHS = NO; 460 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 461 | CLANG_CXX_LIBRARY = "libc++"; 462 | CLANG_ENABLE_MODULES = YES; 463 | CLANG_ENABLE_OBJC_ARC = YES; 464 | CLANG_WARN_BOOL_CONVERSION = YES; 465 | CLANG_WARN_CONSTANT_CONVERSION = YES; 466 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 467 | CLANG_WARN_EMPTY_BODY = YES; 468 | CLANG_WARN_ENUM_CONVERSION = YES; 469 | CLANG_WARN_INT_CONVERSION = YES; 470 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 471 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 472 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 473 | COPY_PHASE_STRIP = YES; 474 | ENABLE_NS_ASSERTIONS = NO; 475 | GCC_C_LANGUAGE_STANDARD = gnu99; 476 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 477 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 478 | GCC_WARN_UNDECLARED_SELECTOR = YES; 479 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 480 | GCC_WARN_UNUSED_FUNCTION = YES; 481 | GCC_WARN_UNUSED_VARIABLE = YES; 482 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 483 | SDKROOT = iphoneos; 484 | TARGETED_DEVICE_FAMILY = "1,2"; 485 | VALIDATE_PRODUCT = YES; 486 | }; 487 | name = Release; 488 | }; 489 | 0727EF6B18E3880A0023F2BE /* Debug */ = { 490 | isa = XCBuildConfiguration; 491 | baseConfigurationReference = 94F6D6A1E34249C8A5A2EEC1 /* Pods.xcconfig */; 492 | buildSettings = { 493 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 494 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 495 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 496 | GCC_PREFIX_HEADER = "Mogo-iOS/Mogo-iOS-Prefix.pch"; 497 | INFOPLIST_FILE = "Mogo-iOS/Mogo-iOS-Info.plist"; 498 | PRODUCT_NAME = "$(TARGET_NAME)"; 499 | WRAPPER_EXTENSION = app; 500 | }; 501 | name = Debug; 502 | }; 503 | 0727EF6C18E3880A0023F2BE /* Release */ = { 504 | isa = XCBuildConfiguration; 505 | baseConfigurationReference = 94F6D6A1E34249C8A5A2EEC1 /* Pods.xcconfig */; 506 | buildSettings = { 507 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 508 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 509 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 510 | GCC_PREFIX_HEADER = "Mogo-iOS/Mogo-iOS-Prefix.pch"; 511 | INFOPLIST_FILE = "Mogo-iOS/Mogo-iOS-Info.plist"; 512 | PRODUCT_NAME = "$(TARGET_NAME)"; 513 | WRAPPER_EXTENSION = app; 514 | }; 515 | name = Release; 516 | }; 517 | 0727EF6E18E3880A0023F2BE /* Debug */ = { 518 | isa = XCBuildConfiguration; 519 | buildSettings = { 520 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/Mogo-iOS.app/Mogo-iOS"; 521 | FRAMEWORK_SEARCH_PATHS = ( 522 | "$(SDKROOT)/Developer/Library/Frameworks", 523 | "$(inherited)", 524 | "$(DEVELOPER_FRAMEWORKS_DIR)", 525 | ); 526 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 527 | GCC_PREFIX_HEADER = "Mogo-iOS/Mogo-iOS-Prefix.pch"; 528 | GCC_PREPROCESSOR_DEFINITIONS = ( 529 | "DEBUG=1", 530 | "$(inherited)", 531 | ); 532 | INFOPLIST_FILE = "Mogo-iOSTests/Mogo-iOSTests-Info.plist"; 533 | PRODUCT_NAME = "$(TARGET_NAME)"; 534 | TEST_HOST = "$(BUNDLE_LOADER)"; 535 | WRAPPER_EXTENSION = xctest; 536 | }; 537 | name = Debug; 538 | }; 539 | 0727EF6F18E3880A0023F2BE /* Release */ = { 540 | isa = XCBuildConfiguration; 541 | buildSettings = { 542 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/Mogo-iOS.app/Mogo-iOS"; 543 | FRAMEWORK_SEARCH_PATHS = ( 544 | "$(SDKROOT)/Developer/Library/Frameworks", 545 | "$(inherited)", 546 | "$(DEVELOPER_FRAMEWORKS_DIR)", 547 | ); 548 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 549 | GCC_PREFIX_HEADER = "Mogo-iOS/Mogo-iOS-Prefix.pch"; 550 | INFOPLIST_FILE = "Mogo-iOSTests/Mogo-iOSTests-Info.plist"; 551 | PRODUCT_NAME = "$(TARGET_NAME)"; 552 | TEST_HOST = "$(BUNDLE_LOADER)"; 553 | WRAPPER_EXTENSION = xctest; 554 | }; 555 | name = Release; 556 | }; 557 | /* End XCBuildConfiguration section */ 558 | 559 | /* Begin XCConfigurationList section */ 560 | 0727EF3318E3880A0023F2BE /* Build configuration list for PBXProject "Mogo-iOS" */ = { 561 | isa = XCConfigurationList; 562 | buildConfigurations = ( 563 | 0727EF6818E3880A0023F2BE /* Debug */, 564 | 0727EF6918E3880A0023F2BE /* Release */, 565 | ); 566 | defaultConfigurationIsVisible = 0; 567 | defaultConfigurationName = Release; 568 | }; 569 | 0727EF6A18E3880A0023F2BE /* Build configuration list for PBXNativeTarget "Mogo-iOS" */ = { 570 | isa = XCConfigurationList; 571 | buildConfigurations = ( 572 | 0727EF6B18E3880A0023F2BE /* Debug */, 573 | 0727EF6C18E3880A0023F2BE /* Release */, 574 | ); 575 | defaultConfigurationIsVisible = 0; 576 | defaultConfigurationName = Release; 577 | }; 578 | 0727EF6D18E3880A0023F2BE /* Build configuration list for PBXNativeTarget "Mogo-iOSTests" */ = { 579 | isa = XCConfigurationList; 580 | buildConfigurations = ( 581 | 0727EF6E18E3880A0023F2BE /* Debug */, 582 | 0727EF6F18E3880A0023F2BE /* Release */, 583 | ); 584 | defaultConfigurationIsVisible = 0; 585 | defaultConfigurationName = Release; 586 | }; 587 | /* End XCConfigurationList section */ 588 | }; 589 | rootObject = 0727EF3018E3880A0023F2BE /* Project object */; 590 | } 591 | -------------------------------------------------------------------------------- /Mogo-iOS/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "40x40", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "60x60", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "ipad", 20 | "size" : "29x29", 21 | "scale" : "1x" 22 | }, 23 | { 24 | "idiom" : "ipad", 25 | "size" : "29x29", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "ipad", 30 | "size" : "40x40", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "40x40", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "76x76", 41 | "scale" : "1x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "76x76", 46 | "scale" : "2x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } -------------------------------------------------------------------------------- /Mogo-iOS/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "orientation" : "portrait", 20 | "idiom" : "ipad", 21 | "extent" : "full-screen", 22 | "minimum-system-version" : "7.0", 23 | "scale" : "1x" 24 | }, 25 | { 26 | "orientation" : "landscape", 27 | "idiom" : "ipad", 28 | "extent" : "full-screen", 29 | "minimum-system-version" : "7.0", 30 | "scale" : "1x" 31 | }, 32 | { 33 | "orientation" : "portrait", 34 | "idiom" : "ipad", 35 | "extent" : "full-screen", 36 | "minimum-system-version" : "7.0", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "orientation" : "landscape", 41 | "idiom" : "ipad", 42 | "extent" : "full-screen", 43 | "minimum-system-version" : "7.0", 44 | "scale" : "2x" 45 | } 46 | ], 47 | "info" : { 48 | "version" : 1, 49 | "author" : "xcode" 50 | } 51 | } -------------------------------------------------------------------------------- /Mogo-iOS/MOGAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // MOGAppDelegate.h 3 | // Mogo-iOS 4 | // 5 | // Created by Jurre Stender on 26/03/14. 6 | // Copyright (c) 2014 jurre. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MOGAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @property (strong, nonatomic) UINavigationController *navigationController; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Mogo-iOS/MOGAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // MOGAppDelegate.m 3 | // Mogo-iOS 4 | // 5 | // Created by Jurre Stender on 26/03/14. 6 | // Copyright (c) 2014 jurre. All rights reserved. 7 | // 8 | 9 | #import "MOGAppDelegate.h" 10 | 11 | #import "AFNetworkActivityIndicatorManager.h" 12 | 13 | @implementation MOGAppDelegate 14 | 15 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 16 | return YES; 17 | } 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Mogo-iOS/Models/MOGMessage.h: -------------------------------------------------------------------------------- 1 | // 2 | // MOGMessage.h 3 | // Mogo-iOS 4 | // 5 | // Created by Jurre Stender on 30/03/14. 6 | // Copyright (c) 2014 jurre. All rights reserved. 7 | // 8 | 9 | #import "JSMessage.h" 10 | 11 | @interface MOGMessage : JSMessage 12 | 13 | @property NSInteger senderId; 14 | @property NSInteger messageId; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Mogo-iOS/Models/MOGMessage.m: -------------------------------------------------------------------------------- 1 | // 2 | // MOGMessage.m 3 | // Mogo-iOS 4 | // 5 | // Created by Jurre Stender on 30/03/14. 6 | // Copyright (c) 2014 jurre. All rights reserved. 7 | // 8 | 9 | #import "MOGMessage.h" 10 | 11 | @implementation MOGMessage 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Mogo-iOS/Models/MOGRoom.h: -------------------------------------------------------------------------------- 1 | // 2 | // MOGRoom.h 3 | // Mogo-iOS 4 | // 5 | // Created by Jurre Stender on 27/03/14. 6 | // Copyright (c) 2014 jurre. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MOGRoom : NSObject 12 | 13 | @property (nonatomic, copy) NSString *name; 14 | @property (nonatomic) NSInteger roomId; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Mogo-iOS/Models/MOGRoom.m: -------------------------------------------------------------------------------- 1 | // 2 | // MOGRoom.m 3 | // Mogo-iOS 4 | // 5 | // Created by Jurre Stender on 27/03/14. 6 | // Copyright (c) 2014 jurre. All rights reserved. 7 | // 8 | 9 | #import "MOGRoom.h" 10 | 11 | @implementation MOGRoom 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Mogo-iOS/Models/MOGUser.h: -------------------------------------------------------------------------------- 1 | // 2 | // MOGUser.h 3 | // Mogo-iOS 4 | // 5 | // Created by Jurre Stender on 06/04/14. 6 | // Copyright (c) 2014 jurre. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MOGUser : NSObject 12 | 13 | @property NSInteger userId; 14 | @property (nonatomic, copy) NSString *name; 15 | @property (nonatomic, copy) NSString *email; 16 | @property (nonatomic, copy) NSString *authToken; 17 | @property (nonatomic, copy) NSString *role; 18 | 19 | - (BOOL)isAdmin; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Mogo-iOS/Models/MOGUser.m: -------------------------------------------------------------------------------- 1 | // 2 | // MOGUser.m 3 | // Mogo-iOS 4 | // 5 | // Created by Jurre Stender on 06/04/14. 6 | // Copyright (c) 2014 jurre. All rights reserved. 7 | // 8 | 9 | #import "MOGUser.h" 10 | 11 | @implementation MOGUser 12 | 13 | - (BOOL)isAdmin { 14 | return [self.role isEqualToString:@"admin"]; 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Mogo-iOS/Mogo-iOS-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.jurre.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIMainStoryboardFile 28 | Storyboard 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Mogo-iOS/Mogo-iOS-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #ifdef __OBJC__ 8 | #import 9 | #import 10 | #import 11 | #import 12 | #endif 13 | -------------------------------------------------------------------------------- /Mogo-iOS/Networking/MOGAPIClient.h: -------------------------------------------------------------------------------- 1 | #import "AFHTTPRequestOperationManager.h" 2 | 3 | //static NSString *const MOGOAPIBaseURL = @"http://floating-oasis-2485.herokuapp.com/api/"; 4 | 5 | @interface MOGAPIClient : AFHTTPRequestOperationManager 6 | 7 | @property (nonatomic, strong) NSString *authToken; 8 | 9 | + (MOGAPIClient *)sharedClient; 10 | 11 | - (void)setBaseURL:(NSString *)url; 12 | 13 | - (NSString *)baseURLString; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Mogo-iOS/Networking/MOGAPIClient.m: -------------------------------------------------------------------------------- 1 | #import "MOGAPIClient.h" 2 | 3 | @interface MOGAPIClient () 4 | 5 | @property (nonatomic, strong) NSURL *apiBaseURL; 6 | 7 | @end 8 | 9 | @implementation MOGAPIClient 10 | 11 | + (instancetype)sharedClient { 12 | static MOGAPIClient *_sharedClient = nil; 13 | static dispatch_once_t onceToken; 14 | dispatch_once(&onceToken, ^{ 15 | _sharedClient = [[self alloc] init]; 16 | }); 17 | 18 | return _sharedClient; 19 | } 20 | 21 | - (NSURL *)baseURL { 22 | return self.apiBaseURL; 23 | } 24 | 25 | - (void)setBaseURL:(NSString *)url { 26 | NSString *URLString = [url stringByAppendingPathComponent:@"api"]; 27 | _apiBaseURL = [NSURL URLWithString:URLString]; 28 | } 29 | 30 | - (NSString *)baseURLString { 31 | return [self.apiBaseURL absoluteString]; 32 | } 33 | 34 | - (AFHTTPRequestOperation *)HTTPRequestOperationWithRequest:(NSURLRequest *)request 35 | success:(void (^)(AFHTTPRequestOperation *, id))success 36 | failure:(void (^)(AFHTTPRequestOperation *, NSError *))failure { 37 | 38 | NSMutableURLRequest *mutableRequest = [request mutableCopy]; 39 | 40 | if (self.authToken) { 41 | [mutableRequest addValue:self.authToken forHTTPHeaderField:@"Authorization"]; 42 | } 43 | 44 | return [super HTTPRequestOperationWithRequest:mutableRequest 45 | success:success 46 | failure:failure]; 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /Mogo-iOS/Networking/MOGBaseService.h: -------------------------------------------------------------------------------- 1 | // 2 | // MOGBaseService.h 3 | // Mogo-iOS 4 | // 5 | // Created by Jurre Stender on 06/04/14. 6 | // Copyright (c) 2014 jurre. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MOGAPIClient.h" 11 | 12 | @interface MOGBaseService : NSObject 13 | 14 | @property (nonatomic, strong) MOGAPIClient *apiClient; 15 | 16 | + (instancetype)sharedService; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Mogo-iOS/Networking/MOGBaseService.m: -------------------------------------------------------------------------------- 1 | // 2 | // MOGBaseService.m 3 | // Mogo-iOS 4 | // 5 | // Created by Jurre Stender on 06/04/14. 6 | // Copyright (c) 2014 jurre. All rights reserved. 7 | // 8 | 9 | #import "MOGBaseService.h" 10 | 11 | @implementation MOGBaseService 12 | 13 | + (instancetype)sharedService { 14 | [NSException raise:@"Implement in subclass" format:@"This method should be implemented by subclasses only"]; 15 | return nil; 16 | } 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Mogo-iOS/Networking/MOGMessagePoller.h: -------------------------------------------------------------------------------- 1 | // 2 | // MOGMessagePoller.h 3 | // Mogo-iOS 4 | // 5 | // Created by Jurre Stender on 06/04/14. 6 | // Copyright (c) 2014 jurre. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MOGRoom.h" 11 | 12 | @protocol MOGMessagePollerDelegate 13 | 14 | @required 15 | - (void)pollerDidFetchNewMessages:(NSArray *)newMessages; 16 | 17 | @end 18 | 19 | @interface MOGMessagePoller : NSObject 20 | 21 | @property (nonatomic, weak) id delegate; 22 | 23 | - (instancetype)initWithRoom:(MOGRoom *)room; 24 | 25 | - (void)startPolling; 26 | - (void)stopPolling; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /Mogo-iOS/Networking/MOGMessagePoller.m: -------------------------------------------------------------------------------- 1 | // 2 | // MOGMessagePoller.m 3 | // Mogo-iOS 4 | // 5 | // Created by Jurre Stender on 06/04/14. 6 | // Copyright (c) 2014 jurre. All rights reserved. 7 | // 8 | 9 | #import "MOGMessagePoller.h" 10 | #import "MOGMessageService.h" 11 | 12 | static const CGFloat MOGMessagePollingInterval = 2.5f; 13 | 14 | @interface MOGMessagePoller() 15 | 16 | @property (nonatomic, strong) MOGRoom *room; 17 | @property (nonatomic, strong) NSTimer *timer; 18 | @property (nonatomic, strong) MOGMessageService *messageService; 19 | @property (nonatomic) NSInteger lastPolledMessage; 20 | 21 | @end 22 | 23 | @implementation MOGMessagePoller 24 | 25 | - (instancetype)initWithRoom:(MOGRoom *)room { 26 | self = [super init]; 27 | if (self) { 28 | _messageService = [MOGMessageService sharedService]; 29 | _room = room; 30 | } 31 | return self; 32 | } 33 | 34 | - (void)startPolling { 35 | self.timer = [NSTimer scheduledTimerWithTimeInterval:MOGMessagePollingInterval 36 | target:self 37 | selector:@selector(timerFired:) 38 | userInfo:nil 39 | repeats:YES]; 40 | } 41 | 42 | - (void)stopPolling { 43 | [self.timer invalidate]; 44 | self.timer = nil; 45 | self.lastPolledMessage = 0; 46 | } 47 | 48 | - (void)timerFired:(NSTimer *)timer { 49 | [self.messageService messagesForRoom:self.room after:self.lastPolledMessage completion:^(NSArray *result) { 50 | if (result.count > 0) { 51 | NSArray *messages = self.messageService.messages; 52 | self.lastPolledMessage = [[messages lastObject] messageId]; 53 | [self.delegate pollerDidFetchNewMessages:messages]; 54 | } 55 | } failure:^(NSError *error) { 56 | NSLog(@"Error polling for messages: %@", error); 57 | }]; 58 | } 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /Mogo-iOS/Networking/MOGMessageService.h: -------------------------------------------------------------------------------- 1 | // 2 | // MOGMessageService.h 3 | // Mogo-iOS 4 | // 5 | // Created by Jurre Stender on 30/03/14. 6 | // Copyright (c) 2014 jurre. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MOGBaseService.h" 11 | #import "MOGRoom.h" 12 | #import "MOGMessage.h" 13 | 14 | static NSString *const MOGApiEndpointMessages = @"messages/"; 15 | 16 | @interface MOGMessageService : MOGBaseService 17 | 18 | @property (nonatomic, strong) NSArray *messages; 19 | 20 | - (void)messagesForRoom:(MOGRoom *)room 21 | completion:(void (^)(NSArray *result))completion 22 | failure:(void (^)(NSError *error))failure; 23 | 24 | - (void)messagesForRoom:(MOGRoom *)room 25 | after:(NSInteger)after 26 | completion:(void (^)(NSArray *result))completion 27 | failure:(void (^)(NSError *error))failure; 28 | 29 | - (void)postMessage:(MOGMessage *)message 30 | toRoom:(MOGRoom *)room 31 | completion:(void (^)(NSArray *messages))completion 32 | failure:(void (^)(NSError *error))failure; 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /Mogo-iOS/Networking/MOGMessageService.m: -------------------------------------------------------------------------------- 1 | // 2 | // MOGMessageService.m 3 | // Mogo-iOS 4 | // 5 | // Created by Jurre Stender on 30/03/14. 6 | // Copyright (c) 2014 jurre. All rights reserved. 7 | // 8 | 9 | #import "MOGMessageService.h" 10 | #import "MOGSessionService.h" 11 | 12 | @interface MOGMessageService () 13 | 14 | @property (nonatomic, strong) NSArray *sentMessages; 15 | 16 | @end 17 | 18 | @implementation MOGMessageService 19 | 20 | + (instancetype)sharedService { 21 | static MOGMessageService *_sharedService = nil; 22 | static dispatch_once_t onceToken; 23 | dispatch_once(&onceToken, ^{ 24 | _sharedService = [[self alloc] init]; 25 | _sharedService.apiClient = [MOGAPIClient sharedClient]; 26 | }); 27 | return _sharedService; 28 | } 29 | 30 | - (NSArray *)messages { 31 | return [_messages arrayByAddingObjectsFromArray:self.sentMessages]; 32 | } 33 | 34 | - (NSString *)endpointForRoom:(MOGRoom *)room { 35 | NSString *roomString = [NSString stringWithFormat:@"%d", room.roomId]; 36 | return [[self.apiClient.baseURLString stringByAppendingPathComponent:MOGApiEndpointMessages] stringByAppendingPathComponent:roomString]; 37 | } 38 | 39 | - (NSString *)messagesEndpoint { 40 | return [self.apiClient.baseURLString stringByAppendingPathComponent:MOGApiEndpointMessages]; 41 | } 42 | 43 | - (void)messagesForRoom:(MOGRoom *)room 44 | completion:(void (^)(NSArray *result))completion 45 | failure:(void (^)(NSError *error))failure { 46 | [self messagesForRoom:room after:0 completion:completion failure:failure]; 47 | 48 | } 49 | 50 | - (void)messagesForRoom:(MOGRoom *)room 51 | after:(NSInteger)after 52 | completion:(void (^)(NSArray *result))completion 53 | failure:(void (^)(NSError *error))failure { 54 | NSDictionary *params = nil; 55 | if (after) { params = @{@"after": [NSNumber numberWithInteger:after] }; } 56 | 57 | [self.apiClient GET:[self endpointForRoom:room] 58 | parameters:params 59 | success:^(AFHTTPRequestOperation *operation, id responseObject) { 60 | self.sentMessages = @[]; 61 | NSArray *messages = [self messagesFromResponse:responseObject]; 62 | if (after) { 63 | self.messages = [self.messages arrayByAddingObjectsFromArray:messages]; 64 | } else { 65 | self.messages = messages; 66 | } 67 | completion(self.messages); 68 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 69 | failure(error); 70 | }]; 71 | 72 | } 73 | 74 | 75 | - (NSArray *)messagesFromResponse:(id)responseObject { 76 | NSArray *rawMessages = responseObject[@"messages"]; 77 | NSMutableArray *messages = [NSMutableArray arrayWithCapacity:[rawMessages count]]; 78 | for (NSDictionary *rawMessage in rawMessages) { 79 | MOGMessage *message = [self messageFromResponse:rawMessage]; 80 | [messages addObject:message]; 81 | } 82 | return [NSArray arrayWithArray:messages]; 83 | } 84 | 85 | - (MOGMessage *)messageFromResponse:(NSDictionary *)responseObject { 86 | NSDate *date = [self dateFromISO8601String:responseObject[@"created_at"]]; 87 | MOGMessage *message = [[MOGMessage alloc] initWithText:responseObject[@"body"] 88 | sender:responseObject[@"user"][@"name"] 89 | date:date]; 90 | message.messageId = [responseObject[@"id"] integerValue]; 91 | message.senderId = [responseObject[@"user_id"] integerValue]; 92 | return message; 93 | } 94 | 95 | - (void)postMessage:(MOGMessage *)message 96 | toRoom:(MOGRoom *)room 97 | completion:(void (^)(NSArray *messages))completion 98 | failure:(void (^)(NSError *error))failure { 99 | NSDictionary *serializedMessage = [self serializedMessage:message forRoom:room]; 100 | [self.apiClient POST:[self messagesEndpoint] 101 | parameters:serializedMessage 102 | success:^(AFHTTPRequestOperation *operation, id responseObject) { 103 | MOGMessage *message = [self messageFromResponse:responseObject[@"message"]]; 104 | message.sender = [MOGSessionService sharedService].currentUser.name; 105 | self.sentMessages = [self.sentMessages arrayByAddingObject:message]; 106 | completion(self.messages); 107 | } 108 | failure:^(AFHTTPRequestOperation *operation, NSError *error) { 109 | failure(error); 110 | }]; 111 | 112 | } 113 | 114 | - (NSDictionary *)serializedMessage:(MOGMessage *)message forRoom:(MOGRoom *)room { 115 | return @{ 116 | @"message": @{ 117 | @"room_id": [NSNumber numberWithInteger: room.roomId], 118 | @"user_id": [NSNumber numberWithInteger: [MOGSessionService sharedService].currentUser.userId], 119 | @"body": message.text, 120 | @"type": @"text" 121 | } 122 | }; 123 | } 124 | 125 | - (NSDate *)dateFromISO8601String:(NSString *)dateString { 126 | 127 | NSDate *dateFromString = [[self dateFormatter] dateFromString:dateString]; 128 | return dateFromString; 129 | } 130 | 131 | - (NSDateFormatter *)dateFormatter { 132 | static NSDateFormatter *dateFormatter; 133 | if (!dateFormatter) { 134 | dateFormatter = [[NSDateFormatter alloc] init]; 135 | [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"]; 136 | } 137 | return dateFormatter; 138 | } 139 | 140 | @end 141 | -------------------------------------------------------------------------------- /Mogo-iOS/Networking/MOGRoomService.h: -------------------------------------------------------------------------------- 1 | // 2 | // MOGRoomService.h 3 | // Mogo-iOS 4 | // 5 | // Created by Jurre Stender on 26/03/14. 6 | // Copyright (c) 2014 jurre. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MOGBaseService.h" 11 | #import "MOGRoom.h" 12 | 13 | static NSString *const MOGApiEndpointRooms = @"rooms"; 14 | 15 | @interface MOGRoomService : MOGBaseService 16 | 17 | @property (nonatomic, strong) NSArray *rooms; 18 | 19 | - (void)roomsWithCompletion:(void (^)(NSArray *result))completion failure:(void (^)(NSError *error))failure; 20 | 21 | - (void)createRoomWithName:(NSString *)name 22 | completion:(void (^)(MOGRoom *room))completion 23 | failure:(void (^)(NSError *error))failure; 24 | 25 | - (void)deleteRoom:(MOGRoom *)room 26 | completion:(void (^)(void))completion 27 | failure:(void (^)(NSError *error))failure; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Mogo-iOS/Networking/MOGRoomService.m: -------------------------------------------------------------------------------- 1 | // 2 | // MOGRoomService.m 3 | // Mogo-iOS 4 | // 5 | // Created by Jurre Stender on 26/03/14. 6 | // Copyright (c) 2014 jurre. All rights reserved. 7 | // 8 | 9 | #import "MOGRoomService.h" 10 | 11 | @implementation MOGRoomService 12 | 13 | + (instancetype)sharedService { 14 | static MOGRoomService *_sharedService = nil; 15 | static dispatch_once_t onceToken; 16 | dispatch_once(&onceToken, ^{ 17 | _sharedService = [[self alloc] init]; 18 | _sharedService.apiClient = [MOGAPIClient sharedClient]; 19 | }); 20 | return _sharedService; 21 | } 22 | 23 | - (NSString *)endpoint { 24 | return [self.apiClient.baseURLString stringByAppendingPathComponent:MOGApiEndpointRooms]; 25 | } 26 | 27 | - (NSString *)endpointWithRoom:(MOGRoom *)room { 28 | NSString *roomId = [NSString stringWithFormat:@"%d", room.roomId]; 29 | return [[self endpoint] stringByAppendingPathComponent:roomId]; 30 | } 31 | 32 | - (void)roomsWithCompletion:(void (^)(NSArray *result))completion failure:(void (^)(NSError *error))failure { 33 | [self.apiClient GET:[self endpoint] 34 | parameters:nil 35 | success:^(AFHTTPRequestOperation *operation, id responseObject) { 36 | NSArray *result = [self roomsFromResponse:responseObject]; 37 | completion(result); 38 | } 39 | failure:^(AFHTTPRequestOperation *operation, NSError *error) { 40 | failure(error); 41 | }]; 42 | } 43 | 44 | - (void)createRoomWithName:(NSString *)name 45 | completion:(void (^)(MOGRoom *room))completion 46 | failure:(void (^)(NSError *error))failure { 47 | NSDictionary *params = @{ @"room": @{@"name": name} }; 48 | [self.apiClient POST:[self endpoint] parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) { 49 | MOGRoom *room = [[MOGRoom alloc] init]; 50 | room.name = responseObject[@"room"][@"name"]; 51 | room.roomId = [responseObject[@"room"][@"id"] integerValue]; 52 | completion(room); 53 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 54 | failure(error); 55 | }]; 56 | } 57 | 58 | - (void)deleteRoom:(MOGRoom *)room 59 | completion:(void (^)(void))completion 60 | failure:(void (^)(NSError *error))failure { 61 | self.apiClient.responseSerializer.acceptableContentTypes = [self.apiClient.responseSerializer.acceptableContentTypes setByAddingObject:@"text/html"]; 62 | [self.apiClient DELETE:[self endpointWithRoom:room] 63 | parameters:nil 64 | success:^(AFHTTPRequestOperation *operation, id responseObject) { 65 | completion(); 66 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 67 | // For some reason the empty body that is returned by the server 68 | // causes AFNetworking/NSURLConnection to see this as a failure. 69 | // However, as long as the statusCode is 200, we should be fine. 70 | if (operation.response.statusCode == 200) { 71 | completion(); 72 | } else { 73 | failure(error); 74 | } 75 | }]; 76 | } 77 | 78 | #pragma mark - Private 79 | 80 | - (NSArray *)roomsFromResponse:(id)responseObject { 81 | NSArray *jsonArray = responseObject[@"rooms"]; 82 | NSMutableArray *rooms = [NSMutableArray arrayWithCapacity:[jsonArray count]]; 83 | for (NSDictionary *jsonRoom in jsonArray) { 84 | MOGRoom *room = [[MOGRoom alloc] init]; 85 | room.name = jsonRoom[@"name"]; 86 | room.roomId = [jsonRoom[@"id"] integerValue]; 87 | [rooms addObject:room]; 88 | } 89 | return [NSArray arrayWithArray:rooms]; 90 | } 91 | 92 | @end 93 | -------------------------------------------------------------------------------- /Mogo-iOS/Networking/MOGSessionService.h: -------------------------------------------------------------------------------- 1 | // 2 | // MOGSessionService.h 3 | // Mogo-iOS 4 | // 5 | // Created by Jurre Stender on 06/04/14. 6 | // Copyright (c) 2014 jurre. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MOGBaseService.h" 11 | #import "MOGUser.h" 12 | 13 | static NSString *const MOGAPIEndPointSession = @"sessions"; 14 | 15 | @interface MOGSessionService : MOGBaseService 16 | 17 | @property (nonatomic, strong) MOGUser *currentUser; 18 | @property (nonatomic, copy) NSString *baseURL; 19 | @property (nonatomic, copy) NSString *emailAddress; 20 | 21 | - (void)signInWithEmail:(NSString *)email 22 | password:(NSString *)password 23 | completion:(void (^)(MOGUser *user))completion 24 | failure:(void (^)(NSError *error))failure; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Mogo-iOS/Networking/MOGSessionService.m: -------------------------------------------------------------------------------- 1 | // 2 | // MOGSessionService.m 3 | // Mogo-iOS 4 | // 5 | // Created by Jurre Stender on 06/04/14. 6 | // Copyright (c) 2014 jurre. All rights reserved. 7 | // 8 | 9 | #import "MOGSessionService.h" 10 | 11 | static NSString *const MOGUserDefaultsBaseURL = @"MOGUserDefaultsBaseURL"; 12 | static NSString *const MOGUserDefaultsEmailAddress = @"MOGUserDefaultsEmailAddress"; 13 | 14 | @implementation MOGSessionService 15 | 16 | + (instancetype)sharedService { 17 | static MOGSessionService *_sharedService = nil; 18 | static dispatch_once_t onceToken; 19 | dispatch_once(&onceToken, ^{ 20 | _sharedService = [[self alloc] init]; 21 | _sharedService.apiClient = [MOGAPIClient sharedClient]; 22 | }); 23 | return _sharedService; 24 | } 25 | 26 | - (NSString *)endpoint { 27 | return [self.apiClient.baseURLString stringByAppendingPathComponent:MOGAPIEndPointSession]; 28 | } 29 | 30 | - (void)signInWithEmail:(NSString *)email 31 | password:(NSString *)password 32 | completion:(void (^)(MOGUser *user))completion 33 | failure:(void (^)(NSError *error))failure { 34 | NSDictionary *params = @{@"email": email, @"password": password}; 35 | [self.apiClient POST:[self endpoint] 36 | parameters:params 37 | success:^(AFHTTPRequestOperation *operation, id responseObject) { 38 | MOGUser *user = [self userFromResponse:responseObject]; 39 | self.currentUser = user; 40 | completion(user); 41 | } 42 | failure:^(AFHTTPRequestOperation *operation, NSError *error) { 43 | failure(error); 44 | }]; 45 | } 46 | 47 | - (MOGUser *)userFromResponse:(NSDictionary *)responseObject { 48 | MOGUser *user = [[MOGUser alloc] init]; 49 | responseObject = responseObject[@"user"]; 50 | user.userId = [responseObject[@"id"] integerValue]; 51 | user.name = responseObject[@"name"]; 52 | user.email = responseObject[@"email"]; 53 | user.authToken = responseObject[@"auth_token"]; 54 | user.role = responseObject[@"role"]; 55 | return user; 56 | } 57 | 58 | #pragma mark - User Defaults / Keychain 59 | 60 | - (void)setBaseURL:(NSString *)baseURL { 61 | [[NSUserDefaults standardUserDefaults] setValue:baseURL forKey:MOGUserDefaultsBaseURL]; 62 | [[NSUserDefaults standardUserDefaults] synchronize]; 63 | } 64 | 65 | - (NSString *)baseURL { 66 | return [[NSUserDefaults standardUserDefaults] valueForKey:MOGUserDefaultsBaseURL]; 67 | } 68 | 69 | - (void)setEmailAddress:(NSString *)emailAddress { 70 | [[NSUserDefaults standardUserDefaults] setValue:emailAddress forKey:MOGUserDefaultsEmailAddress]; 71 | [[NSUserDefaults standardUserDefaults] synchronize]; 72 | } 73 | 74 | - (NSString *)emailAddress { 75 | return [[NSUserDefaults standardUserDefaults] valueForKey:MOGUserDefaultsEmailAddress]; 76 | } 77 | 78 | 79 | @end 80 | -------------------------------------------------------------------------------- /Mogo-iOS/Storyboard.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 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 250 | 251 | 252 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | -------------------------------------------------------------------------------- /Mogo-iOS/ViewControllers/MOGChatViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MOGChatViewController.h 3 | // Mogo-iOS 4 | // 5 | // Created by Jurre Stender on 27/03/14. 6 | // Copyright (c) 2014 jurre. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "JSMessagesViewController.h" 11 | #import "MOGRoom.h" 12 | #import "MOGSessionService.h" 13 | #import "MOGMessageService.h" 14 | 15 | @interface MOGChatViewController : JSMessagesViewController 16 | 17 | @property (nonatomic, retain) MOGRoom *room; 18 | @property (nonatomic) MOGSessionService *sessionService; 19 | @property (nonatomic) MOGMessageService *messageService; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Mogo-iOS/ViewControllers/MOGChatViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MOGChatViewController.m 3 | // Mogo-iOS 4 | // 5 | // Created by Jurre Stender on 27/03/14. 6 | // Copyright (c) 2014 jurre. All rights reserved. 7 | // 8 | 9 | #import "MOGChatViewController.h" 10 | #import "MOGMessage.h" 11 | #import "MOGMessagePoller.h" 12 | 13 | @interface MOGChatViewController () 14 | 15 | @property (nonatomic, strong) NSArray *messages; 16 | @property (nonatomic) MOGMessagePoller *poller; 17 | 18 | @end 19 | 20 | @implementation MOGChatViewController 21 | 22 | - (void)viewDidLoad { 23 | [self setupChat]; 24 | [super viewDidLoad]; 25 | [self setupServices]; 26 | [self loadMessages]; 27 | [self setupPolling]; 28 | } 29 | 30 | - (void)viewWillDisappear:(BOOL)animated { 31 | [self.poller stopPolling]; 32 | [super viewWillDisappear:animated]; 33 | } 34 | 35 | - (void)setupChat { 36 | self.delegate = self; 37 | self.dataSource = self; 38 | self.messageInputView.textView.placeHolder = @"Message..."; 39 | 40 | self.sender = [self.sessionService currentUser].name; 41 | self.title = self.room.name; 42 | } 43 | 44 | - (void)setupPolling { 45 | self.poller = [[MOGMessagePoller alloc] initWithRoom:self.room]; 46 | self.poller.delegate = self; 47 | [self.poller startPolling]; 48 | } 49 | 50 | - (void)setupServices { 51 | self.sessionService = [MOGSessionService sharedService]; 52 | self.messageService = [MOGMessageService sharedService]; 53 | } 54 | 55 | - (void)loadMessages { 56 | [self.messageService messagesForRoom:self.room 57 | completion:^(NSArray *result) { 58 | self.messages = result; 59 | } failure:^(NSError *error) { 60 | NSLog(@"Error fetching messages: %@", error); 61 | }]; 62 | } 63 | 64 | - (void)setMessages:(NSArray *)messages { 65 | _messages = messages; 66 | [self.tableView reloadData]; 67 | [self scrollToBottomAnimated:NO]; 68 | } 69 | 70 | #pragma mark - 71 | 72 | - (MOGUser *)currentUser { 73 | return self.sessionService.currentUser; 74 | } 75 | 76 | #pragma mark - JSMessage deletage/datasource 77 | 78 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 79 | return self.messages.count; 80 | } 81 | 82 | - (id)messageForRowAtIndexPath:(NSIndexPath *)indexPath { 83 | return self.messages[indexPath.row]; 84 | } 85 | 86 | - (UIImageView *)avatarImageViewForRowAtIndexPath:(NSIndexPath *)indexPath sender:(NSString *)sender { 87 | return nil; // [MOGAvatarFactory avatarForUsername:sender]; 88 | } 89 | 90 | - (void)didSendText:(NSString *)text fromSender:(NSString *)sender onDate:(NSDate *)date { 91 | MOGMessage *message = [[MOGMessage alloc] initWithText:text sender:sender date:date]; 92 | message.senderId = self.currentUser.userId; 93 | 94 | [self.messageService postMessage:message 95 | toRoom:self.room 96 | completion:^(NSArray *messages) { 97 | self.messages = messages; 98 | } failure:^(NSError *error) { 99 | NSLog(@"Error posting message: %@", error); 100 | }]; 101 | 102 | [self.messageInputView.textView.undoManager removeAllActions]; 103 | [self finishSend]; 104 | } 105 | 106 | - (JSBubbleMessageType)messageTypeForRowAtIndexPath:(NSIndexPath *)indexPath { 107 | MOGMessage *message = self.messages[indexPath.row]; 108 | return message.senderId == self.currentUser.userId ? JSBubbleMessageTypeOutgoing : JSBubbleMessageTypeIncoming; 109 | } 110 | 111 | - (UIImageView *)bubbleImageViewWithType:(JSBubbleMessageType)type forRowAtIndexPath:(NSIndexPath *)indexPath { 112 | MOGMessage *message = self.messages[indexPath.row]; 113 | if (message.senderId == self.currentUser.userId) { 114 | return [JSBubbleImageViewFactory bubbleImageViewForType:type 115 | color:[UIColor js_bubbleBlueColor]]; 116 | } 117 | return [JSBubbleImageViewFactory bubbleImageViewForType:type 118 | color:[UIColor js_bubbleLightGrayColor]]; 119 | } 120 | 121 | - (JSMessageInputViewStyle)inputViewStyle { 122 | return JSMessageInputViewStyleFlat; 123 | } 124 | 125 | #pragma mark - MOGMessagePollerDelegate 126 | 127 | - (void)pollerDidFetchNewMessages:(NSArray *)newMessages { 128 | self.messages = newMessages; 129 | } 130 | 131 | @end 132 | -------------------------------------------------------------------------------- /Mogo-iOS/ViewControllers/MOGLoginViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MOGLoginViewController.h 3 | // Mogo-iOS 4 | // 5 | // Created by Jurre Stender on 26/03/14. 6 | // Copyright (c) 2014 jurre. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MOGAPIClient.h" 11 | #import "MOGSessionService.h" 12 | 13 | @interface MOGLoginViewController : UITableViewController 14 | 15 | @property (nonatomic, weak) IBOutlet UITextField *baseURLTextField; 16 | @property (nonatomic, weak) IBOutlet UITextField *emailTextField; 17 | @property (nonatomic, weak) IBOutlet UITextField *passwordTextField; 18 | @property (nonatomic, weak) IBOutlet UIButton *signInButton; 19 | 20 | @property (nonatomic, strong) MOGAPIClient *apiClient; 21 | @property (nonatomic, strong) MOGSessionService *sessionService; 22 | 23 | - (IBAction)signInButtonTapped:(id)sender; 24 | 25 | - (IBAction)textfieldDidChange:(UITextField *)textField; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /Mogo-iOS/ViewControllers/MOGLoginViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MOGLoginViewController.m 3 | // Mogo-iOS 4 | // 5 | // Created by Jurre Stender on 26/03/14. 6 | // Copyright (c) 2014 jurre. All rights reserved. 7 | // 8 | 9 | #import "MOGLoginViewController.h" 10 | #import "CRToast.h" 11 | 12 | static NSString *const MOGSegueIdentifierSignIn = @"MOGSignInSegue"; 13 | 14 | @implementation MOGLoginViewController 15 | 16 | - (id)initWithCoder:(NSCoder *)aDecoder { 17 | if ((self = [super initWithCoder:aDecoder])) { 18 | _apiClient = [MOGAPIClient sharedClient]; 19 | _sessionService = [MOGSessionService sharedService]; 20 | } 21 | return self; 22 | } 23 | 24 | - (void)viewDidLoad { 25 | [super viewDidLoad]; 26 | self.signInButton.enabled = false; 27 | self.baseURLTextField.text = self.sessionService.baseURL; 28 | self.emailTextField.text = self.sessionService.emailAddress; 29 | } 30 | 31 | - (IBAction)signInButtonTapped:(id)sender { 32 | [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; 33 | [self setSignInFieldsEnabled:NO]; 34 | 35 | void (^completion)() = ^{ 36 | [self setSignInFieldsEnabled:YES]; 37 | [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; 38 | }; 39 | 40 | NSString *baseURL = self.baseURLTextField.text; 41 | self.sessionService.baseURL = baseURL; 42 | self.apiClient.baseURL = baseURL; 43 | 44 | NSString *email = self.emailTextField.text; 45 | NSString *password = self.passwordTextField.text; 46 | 47 | self.sessionService.emailAddress = email; 48 | 49 | [self.sessionService signInWithEmail:email password:password completion:^(MOGUser *user) { 50 | self.emailTextField.text = @""; 51 | self.passwordTextField.text = @""; 52 | 53 | self.apiClient.authToken = user.authToken; 54 | completion(); 55 | [self performSegueWithIdentifier:MOGSegueIdentifierSignIn sender:self]; 56 | } failure:^(NSError *error) { 57 | completion(); 58 | 59 | [CRToastManager showNotificationWithMessage:@"You done goofed. Try again." completionBlock:nil]; 60 | NSLog(@"Failed signing in: %@", error); 61 | 62 | }]; 63 | } 64 | 65 | - (void)setSignInFieldsEnabled:(BOOL)enabled { 66 | self.emailTextField.enabled = enabled; 67 | self.passwordTextField.enabled = enabled; 68 | self.signInButton.enabled = enabled; 69 | } 70 | 71 | 72 | - (IBAction)textfieldDidChange:(UITextField *)textField { 73 | BOOL baseURLEntered = [self textFieldIsSet:self.baseURLTextField]; 74 | BOOL emailEntered = [self textFieldIsSet:self.emailTextField]; 75 | BOOL passwordEntered = [self textFieldIsSet:self.passwordTextField]; 76 | self.signInButton.enabled = baseURLEntered && emailEntered && passwordEntered; 77 | } 78 | 79 | - (BOOL)textFieldIsSet:(UITextField *)textField { 80 | return textField.text && textField.text.length > 0; 81 | } 82 | 83 | @end 84 | -------------------------------------------------------------------------------- /Mogo-iOS/ViewControllers/MOGNewRoomViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MOGNewRoomViewController.h 3 | // Mogo-iOS 4 | // 5 | // Created by Jurre Stender on 06/04/14. 6 | // Copyright (c) 2014 jurre. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MOGNewRoomViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Mogo-iOS/ViewControllers/MOGNewRoomViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MOGNewRoomViewController.m 3 | // Mogo-iOS 4 | // 5 | // Created by Jurre Stender on 06/04/14. 6 | // Copyright (c) 2014 jurre. All rights reserved. 7 | // 8 | 9 | #import "MOGNewRoomViewController.h" 10 | #import "MOGRoomService.h" 11 | #import "MOGRoomsTableViewController.h" 12 | 13 | @interface MOGNewRoomViewController () 14 | 15 | @property (nonatomic, weak) IBOutlet UIButton *saveButton; 16 | @property (nonatomic, weak) IBOutlet UIButton *cancelButton; 17 | @property (nonatomic, weak) IBOutlet UITextField *roomNameTextField; 18 | 19 | @end 20 | 21 | @implementation MOGNewRoomViewController 22 | 23 | - (void)viewDidLoad { 24 | self.saveButton.enabled = false; 25 | } 26 | 27 | - (IBAction)cancelButtonTapped:(id)sender { 28 | [self.presentingViewController dismissViewControllerAnimated:YES completion:nil]; 29 | } 30 | 31 | - (IBAction)textfieldDidChange:(UITextField *)textField { 32 | BOOL roomNameEntered = self.roomNameTextField.text && self.roomNameTextField.text.length > 0; 33 | self.saveButton.enabled = roomNameEntered; 34 | } 35 | 36 | - (IBAction)saveButtonTapped:(UIButton *)sender { 37 | [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; 38 | NSString *roomName = self.roomNameTextField.text; 39 | [self setInputsEnabled:NO]; 40 | [[MOGRoomService sharedService] createRoomWithName:roomName completion:^(MOGRoom *room) { 41 | [self.presentingViewController dismissViewControllerAnimated:YES completion:nil]; 42 | [self setInputsEnabled:YES]; 43 | [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; 44 | } failure:^(NSError *error) { 45 | NSLog(@"Failed saving room: %@", error); 46 | [self setInputsEnabled:YES]; 47 | [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; 48 | }]; 49 | } 50 | 51 | - (void)setInputsEnabled:(BOOL)enabled { 52 | self.roomNameTextField.enabled = enabled; 53 | self.saveButton.enabled = enabled; 54 | self.cancelButton.enabled = enabled; 55 | } 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /Mogo-iOS/ViewControllers/MOGRoomsTableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MOGRoomsTableViewController.h 3 | // Mogo-iOS 4 | // 5 | // Created by Jurre Stender on 27/03/14. 6 | // Copyright (c) 2014 jurre. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MOGRoomService.h" 11 | #import "MOGRoom.h" 12 | #import "MOGSessionService.h" 13 | 14 | @interface MOGRoomsTableViewController : UITableViewController 15 | 16 | @property (nonatomic, weak) IBOutlet UIBarButtonItem *addRoomButton; 17 | 18 | @property (nonatomic, strong) MOGRoomService *roomService; 19 | @property (nonatomic, strong) MOGSessionService *sessionService; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Mogo-iOS/ViewControllers/MOGRoomsTableViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MOGRoomsTableViewController.m 3 | // Mogo-iOS 4 | // 5 | // Created by Jurre Stender on 27/03/14. 6 | // Copyright (c) 2014 jurre. All rights reserved. 7 | // 8 | 9 | #import "MOGRoomsTableViewController.h" 10 | #import "MOGChatViewController.h" 11 | #import "CRToast.h" 12 | 13 | static NSString *MOGRoomCellIdentifier = @"MOGRoomCell"; 14 | static NSString *MOGSegueIdentifierOpenRoom = @"MOGSegueIdentifierOpenRoom"; 15 | 16 | @interface MOGRoomsTableViewController() 17 | 18 | @property (nonatomic, strong) NSArray *rooms; 19 | 20 | @end 21 | 22 | @implementation MOGRoomsTableViewController 23 | 24 | - (id)initWithStyle:(UITableViewStyle)style { 25 | self = [super initWithStyle:style]; 26 | if (self) { 27 | [self setup]; 28 | } 29 | return self; 30 | } 31 | 32 | - (id)initWithCoder:(NSCoder *)aDecoder { 33 | self = [super initWithCoder:aDecoder]; 34 | if (self) { 35 | [self setup]; 36 | } 37 | return self; 38 | } 39 | 40 | - (void)setup { 41 | _roomService = [MOGRoomService sharedService]; 42 | _sessionService = [MOGSessionService sharedService]; 43 | } 44 | 45 | - (void)viewDidLoad { 46 | [super viewDidLoad]; 47 | 48 | [self showAddRoomsButtonIfNeeded]; 49 | [self loadRooms]; 50 | } 51 | 52 | - (void)showAddRoomsButtonIfNeeded { 53 | if (![self.sessionService.currentUser isAdmin]) { 54 | [self.navigationItem setRightBarButtonItem:nil]; 55 | } 56 | } 57 | 58 | - (void)viewDidAppear:(BOOL)animated { 59 | [super viewDidAppear:animated]; 60 | [self loadRooms]; 61 | } 62 | 63 | - (void)loadRooms { 64 | [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; 65 | [self.roomService roomsWithCompletion:^(NSArray *result) { 66 | self.rooms = result; 67 | [self.tableView reloadData]; 68 | [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; 69 | } failure:^(NSError *error) { 70 | NSLog(@"Error loading rooms: %@", error); 71 | }]; 72 | } 73 | 74 | #pragma mark - Table view data source 75 | 76 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 77 | return [self.rooms count]; 78 | } 79 | 80 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 81 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MOGRoomCellIdentifier forIndexPath:indexPath]; 82 | MOGRoom *room = self.rooms[indexPath.row]; 83 | cell.textLabel.text = room.name; 84 | 85 | return cell; 86 | } 87 | 88 | - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { 89 | return [self.sessionService.currentUser isAdmin]; 90 | } 91 | 92 | - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 93 | [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; 94 | if (editingStyle == UITableViewCellEditingStyleDelete) { 95 | MOGRoom *room = self.rooms[indexPath.row]; 96 | [self.roomService deleteRoom:room completion:^{ 97 | NSMutableArray *mutableRooms = [self.rooms mutableCopy]; 98 | [mutableRooms removeObject:room]; 99 | self.rooms = [NSArray arrayWithArray:mutableRooms]; 100 | [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; 101 | [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; 102 | [CRToastManager showNotificationWithOptions:@{kCRToastTextKey: @"Successfully deleted room", kCRToastBackgroundColorKey: [UIColor colorWithRed:0.168 green:0.838 blue:0.285 alpha:1.000]} completionBlock:nil]; 103 | } failure:^(NSError *error) { 104 | NSLog(@"Error deleting rooms: %@", error); 105 | [CRToastManager showNotificationWithMessage:@"Uh oh, couldn't delete that room!" completionBlock:nil]; 106 | [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; 107 | }]; 108 | } 109 | } 110 | 111 | #pragma mark - 112 | 113 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 114 | if ([segue.identifier isEqualToString:MOGSegueIdentifierOpenRoom]) { 115 | ((MOGChatViewController *)segue.destinationViewController).room = self.rooms[[self.tableView indexPathForSelectedRow].row]; 116 | } 117 | } 118 | 119 | @end 120 | -------------------------------------------------------------------------------- /Mogo-iOS/Views/MOGAvatarFactory.h: -------------------------------------------------------------------------------- 1 | // 2 | // MOGAvatarFactory.h 3 | // Mogo-iOS 4 | // 5 | // Created by Jurre Stender on 30/03/14. 6 | // Copyright (c) 2014 jurre. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MOGAvatarFactory : NSObject 12 | 13 | + (UIImageView *)avatarForUsername:(NSString *)string; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Mogo-iOS/Views/MOGAvatarFactory.m: -------------------------------------------------------------------------------- 1 | // 2 | // MOGAvatarFactory.h 3 | // Mogo-iOS 4 | // 5 | // Created by Jurre Stender on 30/03/14. 6 | // Copyright (c) 2014 jurre. All rights reserved. 7 | // 8 | 9 | #import "MOGAvatarFactory.h" 10 | #import "JSAvatarImageFactory.h" 11 | #import "NSString+Hashtel.h" 12 | 13 | static const CGFloat MOGAvatarLabelSize = 150.0f; 14 | static const CGFloat MOGAvatarSize = 200.0f; 15 | 16 | @implementation MOGAvatarFactory 17 | 18 | + (UIImageView *)avatarForUsername:(NSString *)username { 19 | UIView *avatarView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, MOGAvatarSize, MOGAvatarSize)]; 20 | avatarView.backgroundColor = username.color; 21 | 22 | NSString *initial = [[username substringToIndex:1] uppercaseString]; 23 | 24 | CGFloat centerX = MOGAvatarLabelSize - (avatarView.frame.size.width / 2); 25 | UILabel *initialLabel = [[UILabel alloc] initWithFrame:CGRectMake(centerX, 0, MOGAvatarLabelSize, MOGAvatarSize)]; 26 | initialLabel.font = [UIFont systemFontOfSize:150]; 27 | initialLabel.textColor = [UIColor whiteColor]; 28 | initialLabel.text = initial; 29 | 30 | [avatarView addSubview:initialLabel]; 31 | 32 | UIGraphicsBeginImageContextWithOptions(avatarView.bounds.size, avatarView.opaque, 0.0); 33 | [avatarView.layer renderInContext:UIGraphicsGetCurrentContext()]; 34 | 35 | UIImage *avatarImage = UIGraphicsGetImageFromCurrentImageContext(); 36 | 37 | UIGraphicsEndImageContext(); 38 | 39 | return [[UIImageView alloc] initWithImage:[JSAvatarImageFactory avatarImage:avatarImage croppedToCircle:YES]]; 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /Mogo-iOS/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Mogo-iOS/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Mogo-iOS 4 | // 5 | // Created by Jurre Stender on 26/03/14. 6 | // Copyright (c) 2014 jurre. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "MOGAppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([MOGAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, "7.0" 2 | pod "AFNetworking" 3 | pod "JSMessagesViewController" 4 | pod "Hashtel", git: "git@github.com:jurre/hashtel-objc.git" 5 | pod "CRToast" 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Mogo iOS 2 | ========= 3 | An iOS client for [Mogo](https://github.com/HashNuke/mogo-chat). 4 | 5 | # Usage 6 | 1. Sign in by entering your Mogo's web address, username and password 7 | 2. Start chatting. 8 | 9 | ## What does it look like? 10 | 11 | login 12 | 13 | room overview 14 | 15 | chat 16 | 17 | chat 18 | -------------------------------------------------------------------------------- /screenshots/add-room.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jurre/Mogo-iOS/ccaecf5c0585a2985512f79385bcbb85d2b715cf/screenshots/add-room.png -------------------------------------------------------------------------------- /screenshots/chat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jurre/Mogo-iOS/ccaecf5c0585a2985512f79385bcbb85d2b715cf/screenshots/chat.png -------------------------------------------------------------------------------- /screenshots/room-overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jurre/Mogo-iOS/ccaecf5c0585a2985512f79385bcbb85d2b715cf/screenshots/room-overview.png -------------------------------------------------------------------------------- /screenshots/sign-in.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jurre/Mogo-iOS/ccaecf5c0585a2985512f79385bcbb85d2b715cf/screenshots/sign-in.png --------------------------------------------------------------------------------