VNUHCM
Bài trước Bài kế tiếp
  • Nội dung học
  • Trợ giúp
    Bạn có thắc mắc khi đang học?
    Hướng dẫn cách học Những câu hỏi thường gặp Email cho giáo vụ
    • Tiếng Việt
    • English
    • Thông tin Thành viên
    • Khoá học đăng ký
    • Đăng xuất
  • Cohota
  • HƯỚNG DẪN HỌC TẬP

  • Xem chi tiết >>
    Bạn đã hoàn thành 0% khoá học
  • HƯỚNG DẪN SINH VIÊN ĐĂNG NHẬP HỆ THỐNG
    • Hướng dẫn đăng nhập
    • Hướng dẫn vào khóa học
  • Introduction
    • Welcome
  • Unit 1: Values
    • Introduction - Unit 1: Values
    • Get Started With Values
    • Play with Values
    • Playground Basics
    • Naming and Identifiers
    • Simulation
    • Strings
    • Constants and Variables
    • Word Games
    • Build a PhotoFrame App
    • Design for People
  • Episode 1: The TV Club
    • Introduction - Episode 1: The TV Club
    • Searching for Content
    • Sharing Personal Information
    • Ordering Online
    • Reflection: Episode 1
  • Unit 2: Algorithms
    • Introduction - Unit 2: Algorithms
    • Get Started with Algorithms
    • Play with Programs
    • Functions
    • Types
    • Parameters and Results
    • Making Decisions
    • BoogieBot
    • Data Visualization
    • Build a QuestionBot App
    • Design an Experience
  • Episode 2: The Viewing Party
    • Introduction - Episode 2: The Viewing Party
    • Accessing the Show
    • Streaming on the Network
    • Reflection: Episode 2
  • Unit 3: Organizing Data
    • Introduction - Unit 3: Organizing Data
    • Get Started with Organizing Data
    • Play with Complex Data
    • Instances, Methods, and Properties
    • Arrays and Loops
    • Structures
    • Enums and Switch
    • Testing Code
    • Processing Data
    • Pixel Art
    • Password Security
    • Visualization Revisited
    • Build a BouncyBall App
    • Design a Prototype
  • Episode 3: Sharing Photos
    • Introduction - Episode 3: Sharing Photos
    • Capturing Images
    • Posting on Social Media
    • Reflection: Episode 3
  • Unit 4: Building Apps
    • Introduction - Unit 4: Building Apps
    • Get Started with App Development
    • Play with App Components
    • Color Picker
    • ChatBot
    • Rock, Paper, Scissors
    • MemeMaker
    • Build an ElementQuiz App
    • Design for Impact
  • Appendix
    • Episode Technical Concepts
    • Glossary
Tổng quan điểm khóa học
Đánh giá

Tiến độ
Tên tiêu chí Trọng số (%) Điểm Tiến độ (%)
Unit 4: Building Apps

Get Started with App Development

Unit 4: Building Apps|Get Started

Take a minute to look back at your progress in this course. You’ve become proficient at using Swift to create algorithms to solve problems. You’ve learned about some of the basic functions of computers. And you’ve gotten a taste for how Xcode is used to build apps.

Now it’s time to put all this knowledge to work to build real apps! By the end of this unit, you’ll have built several apps from the ground up.

Apps

Apps can be described by their behavior—the inputs they accept, how they accept them, and the nature of the outputs they produce. Apps receive all kinds of input: touches on their screens, files, sensor input (such as from a camera), data from the internet. Inputs can even come from other programs.

For example, you can use the Share sheet in your Photos app to send a photo to another editing app, or to include it in a message to your friend. When it comes to output, apps can return images, sounds, music, text, tactile sensations, and animations.

While a user might describe an app in terms of its behavior, a developer might also describe it by explaining how its code and the underlying algorithms work together to accomplish its function. Developers have to design their apps to work for a wide variety of inputs and situations—the output of a program depends on its input and the state it’s in.

For example, what happens when an email app is offline, when its users write in a language that displays text from right to left, or when a message is addressed to a nonexistent email account? What if users have low vision and require accessibility accommodations such as VoiceOver? Good app designers anticipate the variety of ways their apps will be used, and will write code to handle those circumstances.

Explore this:

Think of an app that you use every day.

  • What kinds of inputs does it use?
  • What kinds of outputs does it produce?
  • What are all the different situations that the app designer might have had to account for when designing it?

Events

Most of your programming so far has been in playgrounds, where code executes from start to finish. But apps receive much of their input in the form of events that they don’t control. An event might represent a user action such a tap or swipe, or other actions such as an incoming phone call or data arriving from the network. Much of the code you write for an app is event-based, executing in response to a constantly changing environment.

Explore this:

Think about how a restaurant runs.

The front of the house is where customers eat, and the back of the house is where food is prepared by chefs. Servers operate in both environments. They take orders from customers and convey them as inputs to the kitchen, and they deliver output (food) from the kitchen to the customers.

The kitchen doesn’t control what happens in the front of the house.

  • What kinds of events do the chefs respond to?
  • How are the events generated, and at what frequency?
  • How are they conveyed to the kitchen?
  • Is there a standard way to communicate them?
  • What kinds of assumptions can the back of the house make about the kinds and frequency of events during a typical day?

The customers don’t control what happens in the kitchen—at least not directly.

  • How are customers affected by the output of a kitchen?
  • How might customers create new events in reaction to outputs?

Identify some typical flows of events and outputs in the normal course of the day at a restaurant—ones that are repeated many times.

You’ve already done some event-based programming in this course, and you’ll get a lot more experience in this unit. There are multiple ways your code might be invoked in response to events. In the section below, you can review two examples that you’ve already practiced, and get introduced to two new ones.

Function Callbacks

Callback is a general term for any code that executes in response to events. You used a specific style—assigning a function to a callback property—to handle events such as collisions and user touches in the BouncyBall game.

Delegates

Delegation is a common pattern for division of labor within an app—a controller-delegate relationship. By delegating the responsibility for a set of tasks to another object, a controller can ignore the details of how they’re accomplished. Its delegate, a faithful assistant, just has to focus on its tasks, responding reliably and efficiently, without being concerned about the broader context.

You used the delegation pattern in the QuestionBot project—though you didn’t use the term then. Your responseTo(question:) function was called when the app needed to respond to the user entering their question.

Data Sources

Data sources are similar to delegates. They’re also typically managed by controllers and respond to the demands of the app. Whereas delegates perform tasks for a controller, data sources are meant to supply data to a controller. As the name implies, a data source primarily works with the types and instances that form the backbone of the content inside the app.

You’ll encounter data sources in an upcoming app project.

Outlets and Actions

When you develop an app, you write Swift code and you build your UI in a storyboard—you’ve done a little bit of both in past projects. In order for the two to work together, they must be connected. In the next lesson, you’ll learn how to connect your Swift code to the items in a storyboard using Outlets and Actions.

While it’s possible to write apps without function callbacks, delegates, and data sources, you’ll be hard-pressed to find an iOS app that doesn’t use outlets and actions.

Debugging

You’ve probably already discovered lots of ways to make programming mistakes. Sometimes, the Swift compiler will instantly tell you when you’ve made an error. You’ve learned over time what these error messages mean and how to fix them. Those easy-to-spot errors are called syntax errors (or sometimes compile-time errors) because they involve checking the written code without running it.

But sometimes you don’t see the result of the errors in your code until you run an app. Everything goes smoothly, and then—bam!—your app crashes. This kind of error is a run-time error. Every language defines its own run-time errors. You’ve already seen some of the ones defined by Swift, such as out-of-bounds array indices, division by zero, and integer overflow.

The most perplexing error is when your app runs without crashing, but doesn’t work correctly. These logic errors are among the most difficult to solve, because you get no direct clues from Xcode, Swift, or iOS to help you fix them.

So if you know you have a bug, how do you find it?

When you debug your code, you become a detective. And in a plot twist, you’re also the victim and the perpetrator! You have to look for clues and reason backwards to find the culprit. This process will feel challenging at first. Don’t worry—doing something the first time is always tough. But the more you encounter bugs, the more easily you’ll be able to find and correct them.

Below are a few of the mistakes you’ll probably make. Even seasoned programmers make them, so don’t feel bad. These errors just come with the territory.

You might create a run-time error if you:

  • Misuse an index in a loop or an array by over- or undercounting (an off-by-one error).
  • Make a mistake in Interface Builder.

Or you might encounter a logic error if you:

  • Make a simple typo, like putting a + where you should have had a -.
  • Copy and paste code that follows a common pattern, but forget to alter the part that differs.
  • Set a variable to the wrong value.
  • Set a variable at the wrong time—too early or too late.
  • Forget to insert or remove an item from an array.

You’ll discover other ways to create bugs too, and you’ll add them to this list of things to look for when hunting for clues. When you begin debugging, just ask yourself questions. Your answers will lead you to more questions—and eventually to the bug itself.

Logic errors are the trickiest bugs to solve, because they can arise from your misunderstanding of the algorithm. You may write your code perfectly, avoiding all the common slipups, yet still fall into a trap. To fix a logic error, you’ll have to go all the way back to your thought process when you designed your code in the first place.

When hunting down bugs, here are a few helpful strategies you can use.

Output Statements

A simple way to see the values of variables while your program is running is to embed print statements at different points in your code. You can print the value of a variable—or even print "Hey, I'm here!"—inside a function just to make sure you know when and if the function is being called at all. These are quick and simple ways of using output for solving simple problems. However, as your apps become more complex, you’ll probably find the debugger more useful for finding and fixing problems.

Xcode Debugger

Built into Xcode is a robust debugger tool that allows you to set breakpoints—places where program execution will halt. At that point, you can inspect the values of variables, and even see the state of the program’s memory where execution halted.

Visualization

You’ve had experience creating graphical representations of your algorithms and data. Sometimes it’s helpful to return to those when you encounter bugs. Have you made any assumptions that haven’t proven to be true? Try tracing your algorithm through a flowchart, and talk yourself through its steps to see where things might be going awry.

In addition, powerful visualization tools in Xcode can help you spot errors in your code or layout. The code itself might not look right, which is a good visualization of syntax errors.

If your interface doesn’t look right, you can inspect all of its elements in detail while your app runs. You can also analyze the performance of your app in real time using Instruments, an advanced tool that provides other forms of visualization, such as graphs of how hard the processor is working.

A Word of Encouragement

One thing to remember: You can go about debugging bit by bit. Don’t try to solve the problem all at once. If you find one clue, test it by running your code again. If necessary to confirm your suspicion, make small isolated changes in your code, like printing to the console or changing the value of a key variable. Once you’re sure that you’re on the right track, figure out what new questions you can ask.

Finally, don’t be discouraged. Debugging can take persistence and patience. But there’s nothing quite like the feeling of squashing a particularly nasty bug.

Testing

Testing is a great way to minimize the amount of debugging you have to do. You already learned about testing the functions you write in the Testing Code lesson. But there’s another strategy you can use to fight bugs and ensure that your app is reliable: Use the app as much as possible and in as many ways as possible.

Of course, as the developer, you have a blind spot: You know exactly how you’ve designed the app, so you’ll use it exactly as you intend it to be used. As you develop your app, you’ll form habitual use patterns that let you quickly test your code every time you build and run the project. Since users of your app don’t have this insider perspective, they’re likely to do things you can’t anticipate. To thoroughly test your app, you need to stray off the beaten path and see if you can cause some trouble.

When you head off into uncharted territory, don’t just tap and swipe randomly. Try to anticipate all the paths that users can take. Each unique sequence of actions will cause the app to respond in a certain way.

If you’re systematic, you can create a representative sample of the possible pathways through your app, much the same as you would when testing a function. Then, when something breaks, you’ll know how to reproduce it according to the specific sequence of actions you followed. (Remember: Tests that pass now might fail later when you modify your code.)

Try this:

Pick an app that you use every day.

What are its core functions?

Come up with a test plan by creating a list of paths through the app, each representing common user actions. For each path, list the actions that are performed and the expected state along the way. Here’s an example:


Changing the Profile Picture Using the Camera

  1. Tap Settings in the toolbar.
  2. In the Settings screen, tap Edit.
  3. Tap the profile picture.
  4. Select Camera.
  5. Take a selfie.
  6. Tap Use This Photo.
  7. Tap Done.

Expected final state: The app should display the user’s settings, with the new picture appearing at the top left of the screen.


Try each of these paths yourself. Then hand your test plan (and your device, if necessary) to a peer for them to try.

  • Did you write the instructions clearly?
  • Did any of your tests fail?

After you’ve been making and testing apps for a while, you’ll develop empathy for other app developers. The easiest way to fix a bug is to know the exact sequence of actions that caused the app to malfunction and that can be reproduced 100% of the time. And when you encounter a bug in somebody else’s app, you’ll know that’s the kind of feedback that will make a difference.

Giving an app a zero star rating isn’t helpful. Sending the developer a clear description of how to reliably reproduce a bug—along with information about the version of the software and OS you’re using and the device you’re using it on—will give them valuable guidance on how to make their app better. (And using kind language never hurts.)

Reflect on this

Think about App Store reviews you’ve written.

Have you left reviews for an app in the App Store in which you mentioned shortcomings or bugs—or even desired features?

How did you describe your issue?

How might you write a review containing a bug or feature request that’s helpful to the developer of your app?

Try this

Write a review of a favorite app that has a problem you regularly encounter or a feature you’d love to have.

If you want, post the review on the App Store.

Báo lỗi