All right. 1
So, now that we've gotten all the serious parts of our coding out of the way, we've got our messages being 2
saved to our Firebase Firestore, we've got our login and registration routes planned out and working, 3
now it's time to tackle some of those small user experience problems and improve the look and feel of 4
our app. 5
And one glaringly obvious problem that our app has at the moment is that when the user taps in this 6
text field, the keyboard 7
if it rises up will completely cover the text field as well as the send button. 8
Now, on the simulator, we can toggle the keyboard up and down using command K. But the user who's using 9
a physical iPhone cannot do this. 10
Now, what is the solution? 11
Well, the easiest thing would be to figure out what is the height of the keyboard, and then to lift this 12
section here with the text field and the send button up to the top so that it rises up to about here, 13
and it's no longer overlapped by the keyboard. But, unfortunately, especially if you're somebody who has 14
a keen eye for detail, you'll notice that different iPhones have different sized keyboards. 15
So that means that if we use a set or hardcoded number to lift this section up, then it will look a 16
little bit weird depending on which iPhone the app is being run on. 17
What can we do instead? 18
Well, we could instead listen for notifications from the operating system when it's going to bring up 19
the keyboard, then see which keyboard, and then write a lot of code to be able to check to see which height 20
it is and adapt our code accordingly. 21
But there's a much simpler solution because we now know how to use third party libraries. 22
So because this is such a commonly needed functionality, whenever you create text fields, it's likely 23
that you'll need some sort of way of moving it up, so that it doesn't get obscured by the keyboard. 24
Lots of people have already written their solutions to it and they've packaged it into a module so that 25
they can reuse it themselves when they're building new apps. And some of these developers are kind enough 26
to share their solutions with the rest of us and we can tap into this functionality without very much 27
work at all. 28
So the package that we're going to be using in this lesson is something called IQKeyboardManagerSwift. 29
And this is a package that's developed by Mr. Qurashi. 30
And the best feature of it is it works codeless, so we don't actually have to write any code. 31
We don't have to change anything about our app. 32
It simply works in the background and lifts our text field so that it doesn't get obscured by the keyboard 33
in all orientations and on all devices. 34
If we scroll down, you can see that there's actually many ways of installing this particular package. 35
And the most commonly used one is probably doing it via CocoaPods. And you already know how to do this. 36
So if you wanted to, you can actually go ahead and incorporate this pod into your project right now. 37
But because this developer has also enabled insulation with the Swift Package Manager, I thought it might 38
be a good opportunity for me to show you how you can add a package with this Swift Package Manager as 39
long as the project supports it. 40
Notice how if we go to the GitHub repository for this project, you can see that on this main page of 41
files, there is a file called Package.swift. 42
This means that this package is able to work with this Swift Package Manager. 43
However, most third party libraries, including the Firebase modules that we incorporated, don't have this 44
feature enabled yet. 45
So it's only for a small subsect of third party libraries that we can actually use the native Swift Package 46
Manager. 47
But how would we go about installing it? 48
Well, if you find a project in GitHub that has a Package.swift file in its main directory, 49
so notice how this is the GitHub domain, 50
this is the user name, 51
and then this is their package name, 52
there's nothing that's coming after here, 53
right? 54
So we're in the root directory of this package. 55
What you need to do is go ahead and just copy this URL, and then head over to your project, go to file, 56
Swift Packages, Add Package Dependency. 57
And now we're going to choose the projects that we want to add the package to. 58
So we're not going to add it to our Pods. 59
We're going to add it directly to our Flash Chat project. And this is also a good point to mention that 60
while the Swift Package Manager is supposed to work alongside CocoaPods or Carthage, or any of the other 61
third party library managers, at the moment, at this current moment in time, so end of October 2019, 62
I'm finding that if you first saw CocoaPods and you add your Swift packages in the xcworkspace to 63
your project, you have far fewer problems than if you do it the other way round. 64
Say, you start off with a normal project, you add the Swift Package, and then you try to add a pod file 65
and install pods onto that project, 66
you get a lot of weird errors that the Xcode team seems to need to work out. 67
So what I recommend is if you're going to use both CocoaPods and Swift Package Manager, then go ahead 68
and install the pods first before you do the package manager side. 69
But in most cases, you'll find that anything that's available on Swift Package Manager is also available 70
on CocoaPods. 71
But the reverse is not true, 72
there's far more third party libraries on CocoaPods than on Swift Package Manager at least right now. 73
So now that we've selected our project, let's go ahead and hit Next, and then we're going to paste in 74
that URL that we got earlier on which points to the IQKeyboardManager repository on GitHub. 75
So click Next and it's gonna go ahead and find the project. 76
And now it asked for what rules you want to apply to your package. 77
So in this case, we're going to update this particular module. 78
So when the developer of IQKeyboardManager pushes out updates, we're also going to update our project 79
to use the latest version of the keyboard manager up to the next major version. 80
So at the moment, we're on 6.5.3 which supports the latest version of Swift and iOS13, 81
and we're going to say that we want to update to using the next major version which i 82
7.0.0. 83
And the reason why you might want to limit your updates to major versions is that, let's say, 84
that IQKeyboardManager updates to 8.0. 85
Then it's very likely that it also entails an update in the Swift version, 86
so it might be Swift 6 or Swift 7. 87
And unless you're using the same version of Swift, then your project might break. 88
You can also be even more careful and change to up to next minor update in which case 6.5 89
goes to 6.6, 90
or you can say the exact version that I'm working with right now. 91
This is the least likely to break. 92
But in our case, I recommend going with the next major update. 93
That way we'll be able to benefit from the updates and bug fixes that gets brought to the package when 94
iOS and Xcode inevitably changes. 95
Now it's going to download that module and incorporate it into our project as a library. 96
So go ahead and click Finish. 97
And now when you take a look inside the left-side pane, you'll notice that down at the bottom, we've got 98
our Swift Packaged Dependencies is added and we've got our keyboard manager right there. 99
That's it. 100
That's all we have to do. We didn't have to go into Terminal and we didn't have to do anything extra. 101
This is why it's a really nice way of incorporating third party libraries into your projects in Xcode 102
because it's inbuilt to the existing tooling. 103
But unfortunately, right now, there's just not enough coverage and there aren't enough developers who 104
are making libraries for the Swift Package Manager. 105
I think in two years or three years, the situation will probably change and we'll end up with a much 106
easier way of using these third party dependencies. 107
So, now that we've incorporated the IQKeyboardManager package, all we have to do to enable it is to 108
go to our AppDelegate.swift file, import the IQKeyboardManagerSwift module, and then inside 109
our didFinishLaunchingWithOptions, 110
go ahead and enable the keyboard manager. 111
Now, even though it's not showing that down here under the Swift Package Manager, you basically have to 112
do the same thing whether if you're using CocoaPods or Carthage, or Source code, or SPM. 113
So let's go ahead and open up our AppDelegate.swift, and then import that module which was called 114
IQKeyboardManagersSwift, and down here just below where we've created our Firestore database, 115
we're going to go ahead and tap into the IQKeyboardManager.shared.enable, and set it to true. 116
And we're now ready to go ahead and run our app. And now that we've enabled this third party library, 117
notice what happens when I tap in the text field, it automatically scrolls up the rest of my screen and 118
brings the text field to within view of my keyboard. 119
And if you want, you can even do some more customizations with IQKeyboardManager. 120
So for example, I don't really want this toolbar up here where it says done, 121
it seems a little bit extra. So what I can do is I can go over to the properties and functions of the 122
IQKeyboardManager, 123
so these are all the things that you can do with the keyboard manager, and one of those things is to 124
disable the AutoToolbar. 125
This basically relates to this little area right here. 126
And if I don't want it, then in the same place where I enabled my IQKeyboardManager, I'm going to tap 127
into the keyboard manager and tap into the shared keyboard manager, and go to the enableAutoToolbar 128
property, and set it to false. 129
So, now if I run my app again, you can see that when the keyboard comes up, it doesn't go as high because 130
we've gotten rid of that toolbar. 131
Now, the final thing I'd like to be able to do is to be able to dismiss the keyboard if I click away 132
from it. 133
And right now, if I click anywhere on my table view, nothing actually really happens. But if I take a look 134
at the keyboard manager's documentation right here, you can see that there is a property called 135
shouldResignOnTouchOutside. And this resigns the text field, which means the text field is no longer selected, 136
it kind of deselects the text field effectively if touched outside of the text field. 137
So that means when we tap anywhere other than the text field, it's going to dismiss our keyboard. 138
Let's give that a go shouldResignOnTouchOutside. 139
And I want to pose this as a challenge to you. 140
Can you implement this behavior? 141
Pause the video and write the code so that when we click away from the text field, our keyboard is dismissed. 142
I'll give you a few seconds to pause the video before I show you the solution. 143
Ready? 144
Here's the solution. Again, same as before, 145
and then the property that we copied over just now, and then turn it to true. So now when I tap on the 146
text field, my keyboard responds and pops open. But if I tap away from the text field, it dismisses the 147
keyboard which is a really nice behavior that we've gotten for pretty much just a single line of code. 148
And that's the solution to the challenge. 149
The very last thing I've noticed is that our cell, because it's created from our reusable message cell 150
here, it's still allowing selection which is what's causing this gray background to show up. 151
So we have to select our cell and go to the Attributes Inspector and disable the user interaction checkbox 152
right here. 153
And then, now even if we select these cells, they won't turn gray, like as if it'll do something when we click on 154
it. 155
So that's it. 156
That's all you had to do in order to get this brilliant behavior. 157
This automatic animation, we're basically getting with no code at all, and it means that we can focus 158
on creating the custom parts of our app making our app different from other apps using our creativity, 159
rather than doing a lot of this boilerplate and routine stuff that we might need in a lot of apps. 160
In the next lesson, 161
we're going to be tying up some loose ends 162
and we're going to see how we can get our app to display a different format of message if it came from a 163
recipient versus if it's a message that we sent. For all of that and more, 164
I'll see you on the next lesson.