Commit f53ad995 authored by Eric Eastwood's avatar Eric Eastwood
Browse files

Merge branch 'repackage-assets-swift-5' into 'master'

Repackage assets and upgrade to Swift 5

Closes #42 and #45

See merge request gitlab-org/gitter/gitter-ios-app!8
parents b7e16ebd 7daa75a9
......@@ -20,3 +20,4 @@ Common/Libraries/GTMOAuth/Source/GTMOAuth2.xcodeproj/xcuserdata
Gitter/GitterSecrets-Dev.plist
Gitter/GitterSecrets-Beta.plist
Gitter/GitterSecrets-Prod.plist
Gitter/www
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
LastUpgradeVersion = "1100"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
......@@ -27,6 +27,15 @@
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0ACAFF5616C04546008B7750"
BuildableName = "Gitter.app"
BlueprintName = "Gitter"
ReferencedContainer = "container:Gitter.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
<TestableReference
skipped = "NO">
......@@ -39,17 +48,6 @@
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0ACAFF5616C04546008B7750"
BuildableName = "Gitter.app"
BlueprintName = "Gitter"
ReferencedContainer = "container:Gitter.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
......@@ -71,8 +69,6 @@
ReferencedContainer = "container:Gitter.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
......
......@@ -4,7 +4,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
Crittercism.enable(withAppID: "539f10fd0729df2353000001")
// remove old cruft (remove after June 2016)
......@@ -46,8 +46,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
return true
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
application.setMinimumBackgroundFetchInterval(UIApplicationBackgroundFetchIntervalMinimum)
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
application.setMinimumBackgroundFetchInterval(UIApplication.backgroundFetchIntervalMinimum)
return true
}
......@@ -143,7 +143,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
NSLog("didFailToRegisterForRemoteNotificationsWithError: %@", error as NSError)
}
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool {
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any]) -> Bool {
return false
}
......
......@@ -133,7 +133,7 @@
CFMutableDictionaryRef outDictionary = NULL;
if (!SecItemCopyMatching((__bridge CFDictionaryRef)tempQuery, (CFTypeRef *)&outDictionary) == noErr)
if (SecItemCopyMatching((__bridge CFDictionaryRef)tempQuery, (CFTypeRef *)&outDictionary) != errSecSuccess)
{
// Stick these default values into keychain item if nothing found.
[self resetKeychainItem];
......
......@@ -14,9 +14,9 @@ class BayeuxService: NSObject, TREventControllerDelegate {
super.init()
connect()
notificationCenter.addObserver(self, selector: #selector(self.disconnect), name: NSNotification.Name.UIApplicationDidEnterBackground, object: nil)
notificationCenter.addObserver(self, selector: #selector(self.connect), name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil)
notificationCenter.addObserver(self, selector: #selector(self.disconnect), name: NSNotification.Name.UIApplicationWillTerminate, object: nil)
notificationCenter.addObserver(self, selector: #selector(self.disconnect), name: UIApplication.didEnterBackgroundNotification, object: nil)
notificationCenter.addObserver(self, selector: #selector(self.connect), name: UIApplication.willEnterForegroundNotification, object: nil)
notificationCenter.addObserver(self, selector: #selector(self.disconnect), name: UIApplication.willTerminateNotification, object: nil)
}
deinit {
......@@ -24,12 +24,12 @@ class BayeuxService: NSObject, TREventControllerDelegate {
disconnect()
}
func connect() {
@objc func connect() {
disconnect()
eventController = TREventController(delegate: self)
}
func disconnect() {
@objc func disconnect() {
eventController?.disconnect()
eventController = nil
}
......
......@@ -58,7 +58,9 @@ class CoreDataSingleton {
func deleteAllObjects(_ saveCallback: @escaping SaveCallback) {
workerManagedObjectContext.perform {
for entityName in ["Room", "Suggestion"] {
// FIXME: Really we should ask JsonToDatabase to perform these deletes rather than
// just asking it for the list
for entityName in JsonToDatabase.managedObjectEntitiesToClearOnLogout() {
do {
try self.deleteAllObjects(forEntity: entityName, context: self.workerManagedObjectContext)
} catch {
......
......@@ -8,7 +8,7 @@ class GithubEmoji {
for emoji in GithubEmoji.emojis {
var currentNode = root
for character in emoji.characters {
for character in emoji {
var nextNode = currentNode.children[character] ?? Node()
nextNode.solutions.append(emoji)
currentNode.children[character] = nextNode
......@@ -22,7 +22,7 @@ class GithubEmoji {
func search(_ query: String) -> [String] {
var node = tree
for character in query.lowercased().characters {
for character in query.lowercased() {
if let nextNode = node.children[character] {
node = nextNode
} else {
......
......@@ -13,6 +13,16 @@ class JsonToDatabase {
private let adminGroupCollectionFactory: ModelFactory<AdminGroupCollection>
private let userSuggestionCollectionFactory: ModelFactory<UserSuggestionCollection>
public static func managedObjectEntitiesToClearOnLogout() -> [String] {
return [ "Room",
"User",
"Group",
"UserRoomCollection",
"UserGroupCollection",
"AdminGroupCollection",
"UserSuggestionCollection"]
}
init (context: NSManagedObjectContext) {
self.context = context
roomFactory = ModelFactory(entityName: "Room", context: context)
......@@ -37,8 +47,8 @@ class JsonToDatabase {
func upsertRooms(_ roomsJson: [JsonObject]) throws -> [Room] {
let jsonById = reduceById(roomsJson)
let roomIds = Array(jsonById.keys)
let groupIds = roomsJson.flatMap { $0["groupId"] as? String }
let userIds = roomsJson.flatMap { ($0["user"] as? JsonObject)?["id"] as? String }
let groupIds = roomsJson.compactMap { $0["groupId"] as? String }
let userIds = roomsJson.compactMap { ($0["user"] as? JsonObject)?["id"] as? String }
// fetch all the db objects in one go
// the dicts are mutable so that they can be updated with any newly
......@@ -193,7 +203,7 @@ class JsonToDatabase {
room.name = json["name"] as! String
room.url = json["url"] as! String
// uri isnt present on one to ones for some reason
room.uri = json["uri"] as? String ?? String(room.url.characters.dropFirst())
room.uri = json["uri"] as? String ?? String(room.url.dropFirst())
room.avatarUrl = json["avatarUrl"] as! String
room.topic = json["topic"] as? String
room.oneToOne = json["oneToOne"] as? Bool ?? false
......
......@@ -40,7 +40,7 @@ class AutocompleteDataSource: NSObject, UITableViewDataSource, UITableViewDelega
return
}
let prefix = String(text.characters.first ?? Character(""))
let prefix = String(text.first ?? Character(""))
switch prefix {
case "@":
......@@ -48,7 +48,7 @@ class AutocompleteDataSource: NSObject, UITableViewDataSource, UITableViewDelega
// we keep the old results while we wait for the server to respond, but only if it looks like the user is adding letters or backspacing
suggestions = text.hasPrefix(previousText) || previousText.hasPrefix(text) ? suggestions : []
let partialName = String(text.characters.dropFirst())
let partialName = String(text.dropFirst())
getUserSuggestions(partialName, completionHandler: { (userSuggestions) in
guard text == self.previousText else {
// someone typed too fast!
......@@ -58,7 +58,7 @@ class AutocompleteDataSource: NSObject, UITableViewDataSource, UITableViewDelega
})
case ":":
isAutocompleting = true
let partialEmoji = String(text.characters.dropFirst())
let partialEmoji = String(text.dropFirst())
suggestions = getEmojiSuggestions(partialEmoji)
default:
isAutocompleting = false
......@@ -127,7 +127,7 @@ class AutocompleteDataSource: NSObject, UITableViewDataSource, UITableViewDelega
}
private func userSearch(_ query: String, completionHandler: @escaping ([User]) -> Void) {
if (query.characters.count > 0) {
if (query.count > 0) {
NetworkIndicator.sharedInstance.visible = true
restService.searchUsers(inRoom: roomId, query: query, completionHandler: { (error, ids) in
NetworkIndicator.sharedInstance.visible = false
......
......@@ -19,7 +19,7 @@ class CommunitiesViewController: UITableViewController, HintViewDelegate {
let bundle = Bundle.main
hintView = bundle.loadNibNamed("HintView", owner: self, options: nil)!.first as? HintView
hintView?.button.setTitle("Find a room to join a Community!", for: UIControlState())
hintView?.button.setTitle("Find a room to join a Community!", for: UIControl.State())
hintView?.delegate = self
viewWhenEmpty = bundle.loadNibNamed("LoadingView", owner: self, options: nil)!.first as? UIView
}
......@@ -99,7 +99,7 @@ class CommunitiesViewController: UITableViewController, HintViewDelegate {
(tabBarController as! GitterTabBarController).switchTabs(.search)
}
func managedObjectContextDidSave(_ notification: Notification) {
@objc func managedObjectContextDidSave(_ notification: Notification) {
if let userInfo = (notification as NSNotification).userInfo {
let insertedObjects = userInfo[NSInsertedObjectsKey] as? Set<NSManagedObject> ?? []
let updatedObjects = userInfo[NSUpdatedObjectsKey] as? Set<NSManagedObject> ?? []
......
......@@ -78,7 +78,7 @@ class CreateCommunityViewController: UIViewController, WKNavigationDelegate, UIN
}
if !url.path.hasPrefix(roomThatWillNeverBeDeleted) {
let roomName = String(url.path.characters.dropFirst())
let roomName = String(url.path.dropFirst())
decisionHandler(.cancel)
dismiss(animated: true, completion: {
self.delegate?.didCreateRoom(withName: roomName)
......
......@@ -18,7 +18,7 @@ class GitterTabBarController: UITabBarController, UITabBarControllerDelegate {
override func loadView() {
super.loadView()
UITabBarItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName: Colors.rubyColor()], for: .selected)
UITabBarItem.appearance().setTitleTextAttributes(convertToOptionalNSAttributedStringKeyDictionary([convertFromNSAttributedStringKey(NSAttributedString.Key.foregroundColor): Colors.rubyColor()]), for: .selected)
UITabBar.appearance().tintColor = Colors.rubyColor()
delegate = self
......@@ -50,7 +50,7 @@ class GitterTabBarController: UITabBarController, UITabBarControllerDelegate {
scrollToTopOfVisibleTableView()
}
func managedObjectContextDidSave(_ notification: Notification) {
@objc func managedObjectContextDidSave(_ notification: Notification) {
let userInfo = (notification as NSNotification).userInfo!
let insertedObjects = userInfo[NSInsertedObjectsKey] as? Set<NSManagedObject> ?? []
let updatedObjects = userInfo[NSUpdatedObjectsKey] as? Set<NSManagedObject> ?? []
......@@ -236,3 +236,14 @@ enum GitterTab: Int {
case people = 2
case communities = 3
}
// Helper function inserted by Swift 4.2 migrator.
fileprivate func convertToOptionalNSAttributedStringKeyDictionary(_ input: [String: Any]?) -> [NSAttributedString.Key: Any]? {
guard let input = input else { return nil }
return Dictionary(uniqueKeysWithValues: input.map { key, value in (NSAttributedString.Key(rawValue: key), value)})
}
// Helper function inserted by Swift 4.2 migrator.
fileprivate func convertFromNSAttributedStringKey(_ input: NSAttributedString.Key) -> String {
return input.rawValue
}
......@@ -108,7 +108,7 @@ class MembersViewController: UITableViewController, UISearchResultsUpdating {
}
func updateSearchResults(for searchController: UISearchController) {
if let query = searchController.searchBar.text , query.characters.count > 0 {
if let query = searchController.searchBar.text , query.count > 0 {
isSearching = true
NetworkIndicator.sharedInstance.visible = true
......
......@@ -21,7 +21,7 @@ class PeopleViewController: UITableViewController, NSFetchedResultsControllerDel
fetchedResultsController?.delegate = self
hintView = Bundle.main.loadNibNamed("HintView", owner: self, options: nil)!.first as? HintView
hintView?.button.setTitle("👩👱❓ 🔍❗️", for: UIControlState())
hintView?.button.setTitle("👩👱❓ 🔍❗️", for: UIControl.State())
hintView?.delegate = self
try! fetchedResultsController?.performFetch()
......
......@@ -74,7 +74,7 @@ class PickRoomNameViewController: UITableViewController {
@IBAction func textFieldDidChange(_ sender: UITextField) {
linkedRepo = nil
name = (sender.text ?? "").characters.count > 0 ? sender.text : nil
name = (sender.text ?? "").count > 0 ? sender.text : nil
}
override func numberOfSections(in tableView: UITableView) -> Int {
......
......@@ -28,7 +28,7 @@ class RoomListViewController: UITableViewController, NSFetchedResultsControllerD
notificationCenter.addObserver(self, selector: #selector(self.didFinishRefresh), name: NSNotification.Name(rawValue: "snapshotReceived"), object: nil)
viewWhenEmpty = Bundle.main.loadNibNamed("LoadingView", owner: self, options: nil)!.first as? UIView
hintView = Bundle.main.loadNibNamed("HintView", owner: self, options: nil)!.first as? HintView
hintView?.button.setTitle("No Conversations?", for: UIControlState())
hintView?.button.setTitle("No Conversations?", for: UIControl.State())
hintView?.delegate = self
}
......@@ -166,7 +166,7 @@ class RoomListViewController: UITableViewController, NSFetchedResultsControllerD
bayeuxService.requestSnapshot()
}
func didFinishRefresh() {
@objc func didFinishRefresh() {
refreshControl?.endRefreshing()
viewWhenEmpty = hintView
if (tableView.backgroundView != nil && tableView.backgroundView != hintView) {
......
......@@ -20,7 +20,7 @@ class RoomSearchDataSource: NSObject, UITableViewDataSource {
return
}
guard query.characters.count > 0 else {
guard query.count > 0 else {
results = []
previousQuery = query
return
......
......@@ -70,10 +70,10 @@ class RoomViewController: UIViewController, NSDiscardableContent, WKNavigationDe
fatalError("roomId is required")
}
notificationCenter.addObserver(self, selector: #selector(self.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
notificationCenter.addObserver(self, selector: #selector(self.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
notificationCenter.addObserver(self, selector: #selector(self.keyboardWillChangeFrame), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
notificationCenter.addObserver(self, selector: #selector(self.textViewDidChange), name: NSNotification.Name.UITextViewTextDidChange, object: nil)
notificationCenter.addObserver(self, selector: #selector(self.keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
notificationCenter.addObserver(self, selector: #selector(self.keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
notificationCenter.addObserver(self, selector: #selector(self.keyboardWillChangeFrame), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
notificationCenter.addObserver(self, selector: #selector(self.textViewDidChange), name: UITextView.textDidChangeNotification, object: nil)
room = getRoomModel(roomId!)
// get full room model as some propeties are missing in the live collection
......@@ -170,7 +170,7 @@ class RoomViewController: UIViewController, NSDiscardableContent, WKNavigationDe
}
@IBAction func moreButtonTapped(_ sender: UIBarButtonItem) {
let options = UIAlertController(title: nil, message: nil, preferredStyle: UIAlertControllerStyle.actionSheet)
let options = UIAlertController(title: nil, message: nil, preferredStyle: UIAlertController.Style.actionSheet)
options.addAction(UIAlertAction(title: "Notification Settings", style: .default, handler: onNotificationSettingsTapped))
options.addAction(UIAlertAction(title: "Mark All as Read", style: .default, handler: onMarkAllReadOptionTapped))
if (!room!.oneToOne) {
......@@ -200,7 +200,7 @@ class RoomViewController: UIViewController, NSDiscardableContent, WKNavigationDe
return gestureRecognizer == webViewTapGesture
}
func didTapWebView(_ gestureRecognizer: UIGestureRecognizer) {
@objc func didTapWebView(_ gestureRecognizer: UIGestureRecognizer) {
let textView = textInputbar.textView
if (textView.isFirstResponder) {
......@@ -211,7 +211,7 @@ class RoomViewController: UIViewController, NSDiscardableContent, WKNavigationDe
}
}
func keyboardWillShow(_ notification: Notification) {
@objc func keyboardWillShow(_ notification: Notification) {
guard !ignoreKeyboard else {
return
}
......@@ -227,7 +227,7 @@ class RoomViewController: UIViewController, NSDiscardableContent, WKNavigationDe
}, completion: nil)
}
func keyboardWillHide(_ notification: Notification) {
@objc func keyboardWillHide(_ notification: Notification) {
guard !ignoreKeyboard else {
return
}
......@@ -243,7 +243,7 @@ class RoomViewController: UIViewController, NSDiscardableContent, WKNavigationDe
}, completion: nil)
}
func keyboardWillChangeFrame(_ notification: Notification) {
@objc func keyboardWillChangeFrame(_ notification: Notification) {
guard !ignoreKeyboard else {
return
}
......@@ -332,12 +332,12 @@ class RoomViewController: UIViewController, NSDiscardableContent, WKNavigationDe
}
}
func didPressSend() {
@objc func didPressSend() {
let textView = textInputbar.textView as SLKTextView
// accept any autocorrects without losing focus
textView.text = textView.text + " "
textView.text = String(textView.text.characters.dropLast())
textView.text = String(textView.text.dropLast())
sendMessage(textView.text)
......@@ -346,7 +346,7 @@ class RoomViewController: UIViewController, NSDiscardableContent, WKNavigationDe
private func canSend(_ text: String) -> Bool {
let nonWhiteSpaceText = text.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
let isEmpty = nonWhiteSpaceText.characters.count == 0
let isEmpty = nonWhiteSpaceText.count == 0
return !isEmpty
}
......@@ -424,13 +424,13 @@ class RoomViewController: UIViewController, NSDiscardableContent, WKNavigationDe
}
}
func onFakeWebsocketConnectionEstablished(_ timer:Timer) {
@objc func onFakeWebsocketConnectionEstablished(_ timer:Timer) {
fakeLoadingTimer?.invalidate()
UIApplication.shared.isNetworkActivityIndicatorVisible = false;
}
private func shrinkTitleIfNecessary(_ title: String) -> String? {
return title.characters.count > titleLengthLimit ? title.components(separatedBy: "/").last : title
return title.count > titleLengthLimit ? title.components(separatedBy: "/").last : title
}
private func onNotificationSettingsTapped(_ action: UIAlertAction) {
......@@ -458,7 +458,7 @@ class RoomViewController: UIViewController, NSDiscardableContent, WKNavigationDe
}
private func onLeaveOptionTapped(_ action: UIAlertAction!) {
let leaveAlert = UIAlertController(title: "Are you sure?", message: nil, preferredStyle: UIAlertControllerStyle.actionSheet)
let leaveAlert = UIAlertController(title: "Are you sure?", message: nil, preferredStyle: UIAlertController.Style.actionSheet)
leaveAlert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
leaveAlert.addAction(UIAlertAction(title: "Leave \"\(room!.name)\"", style: .destructive, handler: { (action: UIAlertAction!) in
self.restService?.leaveRoom(self.room!.id, completionHandler: { (error, didSaveNewData) in
......@@ -526,19 +526,19 @@ class RoomViewController: UIViewController, NSDiscardableContent, WKNavigationDe
}
private func getKeyboardAnimationDuration(from notification: Notification) -> Double {
return ((notification as NSNotification).userInfo![UIKeyboardAnimationDurationUserInfoKey]! as AnyObject).doubleValue
return ((notification as NSNotification).userInfo![UIResponder.keyboardAnimationDurationUserInfoKey]! as AnyObject).doubleValue
}
private func getKeyboardAnimationOptions(from notification: Notification) -> UIViewAnimationOptions {
let animationCurve = ((notification as NSNotification).userInfo![UIKeyboardAnimationCurveUserInfoKey]! as AnyObject).uintValue
private func getKeyboardAnimationOptions(from notification: Notification) -> UIView.AnimationOptions {
let animationCurve = ((notification as NSNotification).userInfo![UIResponder.keyboardAnimationCurveUserInfoKey]! as AnyObject).uintValue
// trust me on this...
let animationCurveOption = UIViewAnimationOptions(rawValue: animationCurve! << 16)
let animationCurveOption = UIView.AnimationOptions(rawValue: animationCurve! << 16)
return [ animationCurveOption, .beginFromCurrentState ]
}
private func getKeyboardHeight(from notification: Notification) -> CGFloat {
let frame = ((notification as NSNotification).userInfo![UIKeyboardFrameEndUserInfoKey]! as AnyObject).cgRectValue
let frame = ((notification as NSNotification).userInfo![UIResponder.keyboardFrameEndUserInfoKey]! as AnyObject).cgRectValue
let normalisedFrame = view.convert(frame!, to: nil)
let croppedFrame = normalisedFrame.intersection(view.bounds)
var height = croppedFrame.size.height
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment