In the last lesson, we got our skeleton project off of GitHub and we managed to link up an IBAction
with a single button on our Main.storyboard and that's the first button, this red button here, so
that whenever it's pressed the words "I got pressed" get printed into the debug console.
We're now pretty certain that our IBAction is linked to that red button and we can trigger some bit
of functionality to happen when we press on the button.
Now, of course, the actual functionality we want is to make it play a Xylophone note, but we don't know
how to do that yet.
Now, I could simply tell you, "Well, here's step A,
this is what you do," but it doesn't answer the question of, "Well, how did I know how to do it?"
Instead, I want to show you how we can use the Application Programming Interface Documentation which
is quite a mouthful, but essentially, just refers to the components that Apple have already built into
iOS that we can simply tap into and use, because Application Programming Interface takes like a whole
second to say
that people often refer to it as the API.
So the API for your TV would be something like turning the volume up and down or switching the TV on
and off or changing the channel number.
So the API docs for your TV would then be the instruction manual which you probably throw away.
But luckily for us, the Apple API Docs are hosted online and you can find them at developer.apple.com
and then in documentation.
So this is basically the instruction manual for programming
iOS apps. Nut just like most manuals, they're so information-dense.
And if you dig into each of these, you'll find that they have endless links after links after links and
it's really hard figuring out exactly what you need to do from the documentation.
Just like when my mom has a problem with her TV, she'll always call up tech support which is, basically,
me, instead of reading the actual instruction manual for her TV.
Well, programmers also don't usually start with the API Documentation,
instead, we tend to use the programmer's tech support which is StackOverflow. Now StackOverflow is basically
a Q-and-A website like Yahoo Answers or Quora,
but for people who code. So let's say I had a question and because programmers are programmers, there
are some crazy questions on here and some brilliant answers.
If you ever wanted to know what is the most efficient way of pairing socks from a pile, well, you could
search on StackOverflow and you'll see that somebody has asked this question six years ago with three
thousand upvotes.
That was a really popular question and we have a bunch of answers, in fact, two whole pages of answers
here. And the top answer got a lot of upvotes, as well as the checkmark which means that the original
person who asked the question has accepted this as the answer.
So if you ever want to know how to sort your socks in the fastest way possible, well, apparently, you could
use a hashing algorithm. Now because there are literally millions of things that you can make your iPhone
app do,
it will be impossible to remember all the names of those things that you need to use or the exact code
that you would need to write,
even things like how to change an image in an image view. You don't need to memorize the code ImageView.image.
You could just look it up. And in the answer,
people often provide a code snippet where they show you the answer or how to achieve what you want to
do.
So in this case, here's your ImageViewOutlet.image
= your Image, and then we would be able to set the image view. Whenever you want to solve a
problem in programming or when you want your code to do something specific,
then I recommend following this five-step process which we're going to go through by trying to figure
out how we can get our app to play sound.
Step 1 involves Google.
Step 2 involves going to StackOverflow.
Step 3,
implementing the code that you find there.
Step 4, looking up what the code means in the docs.
And step 5, customizing the code for your needs.
And we're gonna go through this step by step.
So let's start with the first one.
Now, ask any experienced programmer and they will tell you that a large part of getting good at programming
involves getting good at Googling. And two people with the same resources, say, a computer that's connected
to the internet don't always end up with the same solutions.
And some people might not even find a solution.
So when you're doing mobile app programming, I recommend following this search structure.
So, first, what I want my app to do.
Secondly, which programming language am I using.
And third,
which resource do I want to come up.
In our case, our search query will look something like this, Play sound using Swift on StackOverflow.
So let's try it out. In Google,
I'm gonna put in those exact search terms "play sound Swift using stackoverflow," and what we're looking
for is a website that starts out with stackoverflow.com.
So we're basically leveraging the power of Google's search engine to find the most relevant result on
StackOverflow.
Now you saw that we could also just search for our query in StackOverflow itself, but I find that Google
is far better at search algorithms than any other company.
Google looks at how often a search term leads to a click of a link, and then whether if the person stays
there, which means that they found the right resource for that search term, or whether if they head back
which means that they didn't find the right one and they have to look through the list.
So step one, basically, ensures that you get a more relevant result.
And once we found the StackOverflow answer that seems to most closely match what we want to do, in this
case, the question is how to play a sound using Swift?
That sounds pretty close to what we want to achieve, right?
Well, then we can go ahead and head over to StackOverflow and take a look at the question and answer
there.
This takes us onto step two, exploring the question-answer
on StackOverflow itself. And in this case, it's a good idea to take a look at the question to assess
whether if your own query is similar to what this person is asking for. In this case, they want to play
a sound using Swift and they had some code that worked previously, but it doesn't work in newer versions
of Swift.
So they want to know how do you do it now.
So if we scroll down, you can see that there are total of 13 answers that have been provided. And people
will often compete for highly voted questions because it means that their answers will get more exposure
and they're more likely to collect reputation points.
So every time you upvote somebody's answer or accept their answer as the correct answer, they get
reputation points which you can see down here.
And this is kind of like a game fight system to incentivize programmers to help each other, so that they
can gain reputation. And as you get better in your skills, it's a good idea to pass it forward, and help
people with what you know. And, also, when you go to job interviews as a programmer, by mentioning a really
high reputation on StackOverflow,
it also counts for a lot.
So it helps to help others.
Now, over here in the accepted answer, so the one with the green tick, you can see that they've provided
code snippets for how to implement this functionality of playing sound using various different versions
of Swift.
So it's Swift 2.3, 3, and 4.
I recommend looking for the latest version and anything from Swift 4 onward, so Swift 4,
5.2.
These are all pretty similar.
As long as you see something that is Swift 4 or Plus, then you should be all right
implementing the code. The order of the answers are presented in a specific way.
The first one that you will see is often the accepted answer.
So the one with the green tick on it.
And if you scroll down, you'll see the answers ordered by the number of upvotes,
at least this is the default order system. Now, because everything in development and programming moves
on so quickly,
just because the person asking the question accepted this answer back in, say, 2013, it doesn't mean that
it's still the best answer.
I always recommend students to take a look, not just at the top answer, but the top three to see if there's
something that's more relevant to today.
So now that we've found our answer on StackOverflow, it's time to go to step 3 and implement the sample
code in our app.
In this case, I'm actually going to use the top answer.
Not only was it accepted, but it's also got a whole bunch of different versions and it seems to be the
most compatible with where we are today.
Let's try and use this code snippet to implement it in our code and try to get our app to be able to
play sound.
So the first line of code I see here is this
import AVFoundation.
I'm going to put that into our project just below where we are importing UIKit.
I'm going to import the AVFoundation module.
Now, these modules are essentially the libraries of code that Apple is written to allow us to interact
with different parts of the hardware and to perform different tasks.
So in this case, the AVFoundation refers to the audiovisual foundational module.
Now that we've added the capability of interacting with the audio hardware, which is what this line does,
it's time to actually set up our audio player.
Notice how here we're creating a variable code player
and we're setting it to be a AVAudioPlayer
in our code.
So we're gonna create a variable code player and then we're going to add a colon to specify the data
type of our player which is gonna be AVAudioPlayer,
and then we add a question mark at the end.
Now, we're going to ignore this for now.
I'm going to explain it in a huge amount of detail later on. But for now, let's focus on trying to get
our sound playing ability to work first.
The next thing I'm going to do is I'm actually just going to copy this entire thing wholesale,
the rest of the code that's in the code snippet, and simply paste it into our project just above the
last closing brace,
so right about here.
Now, once I pasted it in here,
now we're going to have to do a little bit of modification because we don't actually have a resource
code sound name,
and with the extension of mp3 because we have sounds that are named like this C.wave, D.wave.
So we have to change these.
So I'm going to change this to a capital C, which looks exactly the same as the sound file, and I'm going
to change the extension to wave which is W-A-V, not W-A-V-E.
So now I've modified the sample code in the StackOverflow code snippet to work with our resource
and I'm going to leave everything else as it is. But because this play sound lists in a separate block of
code, I'm going to trigger it inside all keyPressed IBAction. So I'm going to delete that print statement
and instead, call this playSound functionality, so that when we press the red key, this block gets triggered
and it looks for this thing called playSound. It finds it right here, and then it executes all the code
in this block.
So let's hit run and see if it works. All right,
so here's my app and I'm gonna press on the top button, and you can hear that a sound is being played.
So now that we've achieved our first three steps, we've managed to implement the solution we found from
StackOverflow.
We're now ready to head over to step four which is to look at the Apple API Docs to understand what
the code does. I'm firstly going to delete all of the existing comments
that the person who provided the solution has put in there so that we only have the code, and then
I'm gonna head over to the API Documentation, and you can find that by heading over to
developerapple.com/documentation.
I'm going to search for that thing that we imported which was called AVFoundation to see what it does.
And the first result is the AVFoundation module that comes up. And this, as you can see, allows us to
work with audiovisual assets.
So, for example, our sound file to control cameras, to process audio, and to configure audio interactions.
So it seems to do a lot of things. And you can see that the documentation is split into different topics:
Playback and Editing, Media capture, Audio, et cetera. If we read through this, you can see that there's one part
that allows us to play, record, mix, and process audio. Playing or audio is pretty much what we wanted to
do, right?
So if we click through on this link, you can see that it gives you more details on how to play sound
using AVFoundation.
And it says that for playback of a single track, use AVAudioPlayer. And if we take a look at our code,
well, the AVAudioPlayer is exactly what we're using to play our sound.
Now, if we move down in our code, we can see that we've got this thing called a Bundle.
Now what exactly is a bundle?
So let's try and understand that by looking inside the documentation and searching for a Bundle.
Now if you click on the first link with the capital B for Bundle, then you can see that it's simply a
representation of the code and resources stored on the disk. And in our case, we're using the main Bundle
to locate our sound file resource. So if we ignore all the sort of programming keywords in pink, you can
see that we're essentially creating this constant code URL which is looking for a resource code
C.wave in all resources,
so the disk area allocated for our app. And then the next thing in our code that we're using, the next
sort of word that's really unfamiliar, is the AVAudiosession.
I'm going to copy this and look for it inside the docs by, again, going to the search bar and typing it.
And once we're here, then we're going to look for this thing called setCategory. What does setCategory actually do?
On this page AVAudiosession, I'm going to hit command F to find this set category. And if you
look through, you'll see where it tells us all about it.
So here, we could click through to this link and learn more about this setCategory and what it does.
Here we have a bit of discussion on how it works and you can find out that there's actually a whole
bunch of categories that we might want to use.
And the one that we're using is something called playback.
So on this page, we can see this ambient which means that the sound playback is nonprimary,
so your app can be used successfully with the sound turned off.
So then there's other types like solo ambient or record playback.
And this is one that we're using which is saying that the category for playing recorded music or other
sounds are central to the successful use of your app. Given that it's a musical app, then playing all sounds,
playing those notes is pretty central to the success of our app.
It's not just like background music in a game with some sound effects.
It's actually really important for that sound to come through.
So by setting in that category, even if the user had their phone on silent, we will still be able to get
our sound played because we're saying it is that important.
And if you read through the documentation, the entire documentation on AVAaudioSession, which is what
I did, then you'll find that there's this paragraph that explains to you that when in iOS, when the device
is locked, the apps audio is silenced. In iOS setting, the Ring/Silent switch to silent, silences any
audio being played by the app.
So this is the default audio session. And we had to use this line of code to change that default audio
session to a new category so that we can actually get our playback happening even if the phone is in
silent mode.
So notice how we're always researching the parts of the code that are sort of purple in color.
Well, that's because by the end of the course, you will know full well what each of the pink parts do
because these are these swift programming concepts. But you won't know all of the purple parts because
these come from Apple's Application Programming Interface Documentation.
So there are a myriad of things that you can do in there, anywhere from playing video to recording sound,
and it's not possible to cover all of the things that you can do.
But once you've understood how the programming works and you know how to search and find the answers
to your problems, then you'll be able to research through the code just as we're doing right now. If you
continue through this process of researching what each of these things do by using the documentation
from Apple, then you'll get a pretty good idea of what our code is doing right here.
We're basically grabbing hold of this C.wav file in our app resources right here, and then we're
making sure that our sound gets played even if the phone is on silent.
And then we tell our audio player that this is the file that we want to play C.wav,
and then we actually play it. And if there were any errors, then we actually catch those areas and print
it out. Now, this is a good time for a quick tip.
Now, when you search for things in the Apple Developer Documentation, you get the full documentation and
it is large.
Very often when I'm using something new that I've never come across before, I tend to try and read the
entire page on it and look through the links and try to get a overview of what I'm doing with my code.
But when you're just trying to look up things quickly to see what they do,
you can also simply hold down the option key on your keyboard and click on various things in your code.
So as soon as I've got my option key held down, I've got this crosshair that shows up,
and now if I hover over things such as my AVAudioPlayer or my Bundle, or AVudioSession,
so basically anything that's not programming,
so not the pink words which are to do with swift programming keywords, but the purple parts which come
from Apple's APIs, then we can click on it and it will show us the quick documentation.
So it's kind of like a shortened version of this.
It only contains the top part. And you can get a quick idea about what each part does or take a look
at it in detail in the developer docs.
So that's just a neat trick for you.
Now, we're finally ready to move on to the last step which is to customize your code. Now reading the
documentation can be quite a long and laborious process. But once you've implemented the code and gotten
it to work, then the documentation can be really helpful to help you figure out what each of these moving
parts are doing and what their roles are.
Once you've more or less understood what each line of code is, therefore, well, then it's time to make
it your own.
Because not everything that's in the code is necessary and the person who wrote the highest upvoted
answer is not Steve Jobs, right?
So they might also be wrong or they might be doing things that you don't actually need.
And this step is probably the hardest part yet because it requires a little bit more knowledge of Swift
programming and you'll be able to do this yourself once you've finished the course.
But for now, I'm going to vastly simplify the code, so that we deal with the harder programming concepts
after we've mastered the foundation parts.
If you open up the README file here, I want you to copy all the code that's inside the replacement
code, and go ahead and copy it and replace everything that's currently inside your ViewController with
this new code.
Now this, of course, relies on the fact that your IBAction was indeed called keyPressrf and it was spelled
exactly the same way.
Be sure to head into the IBAction and right-click on your button just to make sure that that is exactly
the same as this,
so that when you run your app, it doesn't crash, and we're going to simplify all of the code that we had
before
down to just these few lines.
Now, it's much simpler.
But we've gotten a little bit less functionality than before,
but it's fine for our needs.
We're still using the AVFoundation library from Apple.
We're still creating a new AVAudioPlayer, and then we're setting
our URL to be the location of our C.wav sound file in our project, and then we put this file
into our player just like loading up our CD player with a CD.
And finally, we tell it to play the sound.
Now, remember, because we took away the parts which allow our sound to be played when the phone is on
silent,
if you run this app right now and your phone is on silent on your physical device, then it will not make
a sound.
But as long as you switch it back onto normal, then it will be fine. And this is all of the code that
we got from our searching and our documentation reading, and we now have code that we understand, as well
as having implemented for our purposes.
Now, all that's left to do is to understand more of the Swift programming concepts behind this code, for
example, functions and what it's doing in our code. For all of that and more, I'll see you on the next lesson.