0% found this document useful (0 votes)
12 views12 pages

iOS_Intermediate

The document provides a comprehensive overview of various iOS development topics, including Table Views, Collection Views, API integration, Core Data, SwiftUI, background tasks, notifications, unit testing, gesture recognizers, app navigation patterns, and the delegation pattern. Each section includes code examples and explanations to help developers understand and implement these concepts effectively. This resource serves as a valuable guide for both beginners and experienced developers in building responsive and efficient iOS applications.

Uploaded by

Thanh Pham Minh
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
0% found this document useful (0 votes)
12 views12 pages

iOS_Intermediate

The document provides a comprehensive overview of various iOS development topics, including Table Views, Collection Views, API integration, Core Data, SwiftUI, background tasks, notifications, unit testing, gesture recognizers, app navigation patterns, and the delegation pattern. Each section includes code examples and explanations to help developers understand and implement these concepts effectively. This resource serves as a valuable guide for both beginners and experienced developers in building responsive and efficient iOS applications.

Uploaded by

Thanh Pham Minh
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
Download as pdf or txt
You are on page 1/ 12

Intermediate Print

Table Views and Collection Views Tutorial


Table Views and Collection Views are fundamental components in iOS development that enable the
display and management of large data sets in a structured and efficient way. Table Views present data
in a single-column list format, while Collection Views offer a more flexible grid-based layout, allowing
developers to create complex interfaces. Both components support dynamic data management, user
interaction, and custom cell design, making them essential for developing engaging and responsive
applications.
Copy
Table View Example
// UITableViewController subclass

class MyTableViewController: UITableViewController {


let data = ["Item 1", "Item 2", "Item 3"]

override func viewDidLoad() {


super.viewDidLoad()
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) ->


Int {
return data.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) ->


UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = data[indexPath.row]
return cell
}
}

Collection View Example


// UICollectionViewController subclass

class MyCollectionViewController: UICollectionViewController {


let items = ["Item A", "Item B", "Item C"]

override func viewDidLoad() {


super.viewDidLoad()
}

override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection


section: Int) -> Int {
return items.count
}

override func collectionView(_ collectionView: UICollectionView, cellForItemAt


indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for:
indexPath)
cell.contentView.backgroundColor = .blue
// Configure cell with item
return cell
}
}

Working with APIs (JSON Parsing) Tutorial


Working with APIs (JSON Parsing) involves requesting data from a web service or server and then
decoding the JSON response into a usable format within your iOS application. This process usually
utilizes URLSession to handle network requests and the Codable protocol to easily map the JSON data
to Swift structs or classes. Understanding how to perform these operations is crucial for integrating
external data into your apps.
Copy
Fetching JSON data from a REST API
import Foundation

struct Post: Codable {


let title: String
let body: String
}

func fetchPosts() {
let url = URL(string: "https://jsonplaceholder.typicode.com/posts")!
let task = URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else { return }
do {
let posts = try JSONDecoder().decode([Post].self, from: data)
print(posts)
} catch {
print("Failed to decode JSON: \(error.localizedDescription)")
}
}
task.resume()
}

Parsing JSON with Codable


struct User: Codable {
let id: Int
let name: String
let email: String
}

func fetchUsers() {
let url = URL(string: "https://jsonplaceholder.typicode.com/users")!
let task = URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else { return }
do {
let users = try JSONDecoder().decode([User].self, from: data)
for user in users {
print("User: \(user.name), Email: \(user.email)")
}
} catch {
print("Error parsing JSON: \(error)")
}
}
task.resume()
}

Using Core Data for Persistence Tutorial


Core Data is a powerful framework provided by Apple for managing the model layer of an application. It
allows developers to manage object graphs, persist data to storage, and perform queries on that data
efficiently. Core Data abstracts the underlying data storage mechanics, enabling developers to focus on
the object model and relationships without getting bogged down in the details of data persistence.
Copy
Basic Core Data Setup
// AppDelegate.swift
import CoreData

lazy var persistentContainer: NSPersistentContainer = {


let container = NSPersistentContainer(name: "ModelName")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()

func saveContext() {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}

Creating and Saving an Entity


// Saving a new entity
let context = (UIApplication.shared.delegate as!
AppDelegate).persistentContainer.viewContext
let newItem = Item(context: context)
newItem.name = "New Item"
newItem.timestamp = Date()

do {
try context.save()
} catch {
print("Failed to save the item: \(error)")
}

Fetching Data
// Fetching data from Core Data
let fetchRequest = NSFetchRequest<Item>(entityName: "Item")

do {
let items = try context.fetch(fetchRequest)
for item in items {
print("Item: \(item.name ?? "No Name")")
}
} catch {
print("Failed to fetch items: \(error)")
}

Using SwiftUI Basics Tutorial


Using SwiftUI Basics introduces developers to a modern declarative framework for building user
interfaces across all Apple platforms. SwiftUI allows for a simpler way to create intuitive UI designs with
less code, focusing on the view structure and state management. It integrates seamlessly with existing
UIKit, along with support for features such as animations, bindings, and accessibility.
Copy
Basic Text Display
import SwiftUI

struct ContentView: View {


var body: some View {
Text("Hello, World!")
.font(.largeTitle)
.padding()
}
}

struct ContentView_Previews: PreviewProvider {


static var previews: some View {
ContentView()
}
}

Simple Button Action


import SwiftUI

struct ContentView: View {


@State private var count = 0

var body: some View {


VStack {
Text("Counter: \(count)")
.font(.largeTitle)
.padding()
Button(action: {
count += 1
}) {
Text("Increment")
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(8)
}
}
}
}

struct ContentView_Previews: PreviewProvider {


static var previews: some View {
ContentView()
}
}

List View Example


import SwiftUI

struct ContentView: View {


let items = ["Item 1", "Item 2", "Item 3"]

var body: some View {


List(items, id: \.$self) { item in
Text(item)
}
}
}

struct ContentView_Previews: PreviewProvider {


static var previews: some View {
ContentView()
}
}

Background Tasks and Notifications Tutorial


Background tasks in iOS allow applications to perform operations while they are not in the foreground,
enhancing user experience by keeping the app responsive. Notifications, both local and remote, enable
the app to communicate important information to users, even when the app is not active. This subtopic
covers the implementation of background tasks using the BackgroundTasks framework and the creation
and handling of notifications with UserNotifications framework.
Copy
Background Task Example
import BackgroundTasks

func scheduleBackgroundTask() {
let taskRequest = BGAppRefreshTaskRequest(identifier: "com.example.app.refresh")
taskRequest.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60) // 15 minutes from
now
do {
try BGTaskScheduler.shared.submit(taskRequest)
} catch {
print("Could not schedule app refresh: \(error)")
}
}

func handleAppRefresh(task: BGAppRefreshTask) {


scheduleBackgroundTask() // schedule the next refresh
let queue = OperationQueue()
queue.maxConcurrentOperationCount = 1
queue.addOperation {
// Perform your background task here
task.setTaskCompleted(success: true)
}
}

Local Notification Example


import UserNotifications

func scheduleLocalNotification() {
let content = UNMutableNotificationContent()
content.title = "Hello!"
content.body = "This is a local notification."
content.sound = UNNotificationSound.default

let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)


let request = UNNotificationRequest(identifier: "LocalNotification", content: content,
trigger: trigger)

UNUserNotificationCenter.current().add(request) { (error) in
if let error = error {
print("Error scheduling notification: \(error)")
}
}
}

Handling Notifications
import UserNotifications

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions
launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
UNUserNotificationCenter.current().delegate = self
return true
}
}

extension AppDelegate: UNUserNotificationCenterDelegate {


func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response:
UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
// Handle the notification response
completionHandler()
}
}

advertisement
Unit Testing in Xcode Tutorial
Unit testing in Xcode is a crucial practice that allows developers to validate the functionality of
individual components of their iOS applications. By writing tests for individual functions or methods,
developers can ensure that the code behaves as expected and can quickly identify when changes
introduce bugs. XCTest is the framework provided by Apple for writing unit tests in Xcode, supporting
assertions to verify results and offering a way to automate testing processes.
Copy
Testing a Simple Function
import XCTest

class MathTests: XCTestCase {


func testAddition() {
let sum = add(2, 3)
XCTAssertEqual(sum, 5, "Expected 2 + 3 to equal 5")
}

func add(_ a: Int, _ b: Int) -> Int {


return a + b
}
}

Testing Asynchronous Code


import XCTest

class AsyncTests: XCTestCase {


var data: String?

func testFetchingData() {
let expectation = self.expectation(description: "Data fetched")
fetchData { result in
self.data = result
expectation.fulfill()
}
waitForExpectations(timeout: 5) { error in
XCTAssertNil(error, "Expectation timed out")
XCTAssertEqual(self.data, "Expected Data")
}
}

func fetchData(completion: @escaping (String) -> Void) {


// Simulate a network request
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
completion("Expected Data")
}
}
}

Testing Performance
import XCTest

class PerformanceTests: XCTestCase {


func testPerformanceExample() {
self.measure {
// Code to measure the time of
let _ = (0..<1_000_000).map { $0 * 2 }
}
}
}

Gesture Recognizers Tutorial


Gesture Recognizers in iOS are essential tools that enable you to detect and respond to user
interactions with touch and gestures, such as taps, swipes, pinches, and rotations. They simplify the
process of adding gesture-driven actions to your app by allowing you to easily manage complex touch
inputs without having to write a lot of custom touch-handling code. This enhances the user experience
and makes your app feel more responsive and intuitive.
Copy
Tap Gesture Recognizer Example
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
view.addGestureRecognizer(tapGesture)

@objc func handleTap(_ sender: UITapGestureRecognizer) {


print("View tapped!")
}

Swipe Gesture Recognizer Example


let swipeGesture = UISwipeGestureRecognizer(target: self, action:
#selector(handleSwipe(_:)))
swipeGesture.direction = .left
view.addGestureRecognizer(swipeGesture)

@objc func handleSwipe(_ sender: UISwipeGestureRecognizer) {


print("Swiped left!")
}

Pinch Gesture Recognizer Example


let pinchGesture = UIPinchGestureRecognizer(target: self, action:
#selector(handlePinch(_:)))
view.addGestureRecognizer(pinchGesture)

@objc func handlePinch(_ sender: UIPinchGestureRecognizer) {


let scale = sender.scale
view.transform = view.transform.scaledBy(x: scale, y: scale)
sender.scale = 1.0
}

App Navigation Patterns Tutorial


App navigation patterns are essential for providing a smooth user experience in iOS applications. They
dictate how users move through the app, encompassing various techniques such as navigation
controllers, tab bars, and modal presentations. Understanding these patterns helps in organizing app
structure and enhancing usability by ensuring that users can easily access different parts of the
application.
Copy
Navigation Controller Example
import UIKit

class MainViewController: UIViewController {


override func viewDidLoad() {
super.viewDidLoad()
title = "Main View"
view.backgroundColor = .white
let goToDetailButton = UIButton(type: .system)
goToDetailButton.setTitle("Go to Detail", for: .normal)
goToDetailButton.addTarget(self, action: #selector(goToDetail), for: .touchUpInside)
goToDetailButton.center = view.center
view.addSubview(goToDetailButton)
}

@objc func goToDetail() {


let detailVC = DetailViewController()
navigationController?.pushViewController(detailVC, animated: true)
}
}

class DetailViewController: UIViewController {


override func viewDidLoad() {
super.viewDidLoad()
title = "Detail View"
view.backgroundColor = .lightGray
}
}

Tab Bar Example


import UIKit

class TabBarController: UITabBarController {


override func viewDidLoad() {
super.viewDidLoad()

let homeVC = HomeViewController()


homeVC.tabBarItem = UITabBarItem(title: "Home", image: UIImage(systemName: "house"),
tag: 0)

let settingsVC = SettingsViewController()


settingsVC.tabBarItem = UITabBarItem(title: "Settings", image: UIImage(systemName:
"gear"), tag: 1)

viewControllers = [homeVC, settingsVC]


}
}

class HomeViewController: UIViewController {


override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
}
}

class SettingsViewController: UIViewController {


override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .gray
}
}

Modal Presentation Example


import UIKit
class MainViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
title = "Main View"
view.backgroundColor = .white

let showModalButton = UIButton(type: .system)


showModalButton.setTitle("Show Modal", for: .normal)
showModalButton.addTarget(self, action: #selector(showModal), for: .touchUpInside)
showModalButton.center = view.center
view.addSubview(showModalButton)
}

@objc func showModal() {


let modalVC = ModalViewController()
modalVC.modalPresentationStyle = .fullScreen
present(modalVC, animated: true, completion: nil)
}
}

class ModalViewController: UIViewController {


override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .cyan
let closeButton = UIButton(type: .system)
closeButton.setTitle("Close", for: .normal)
closeButton.addTarget(self, action: #selector(closeModal), for: .touchUpInside)
closeButton.center = view.center
view.addSubview(closeButton)
}

@objc func closeModal() {


dismiss(animated: true, completion: nil)
}
}

Implementing Delegation Pattern Tutorial


The Delegation Pattern is a design pattern that enables one object to share its responsibilities with
another object. In iOS development, it is commonly used to allow one object to communicate
information back to another object, such as a view controller receiving input from its delegate. This
pattern promotes loose coupling by allowing delegates to respond to events without requiring the
delegating object to be aware of the delegate's implementation details.
Copy
Simple Delegation Example
protocol DataReceiverDelegate: AnyObject { func didReceiveData(_ data: String)
} class DataProvider { weak var delegate: DataReceiverDelegate? func
fetchData() { // Simulating data fetch let data = "Hello, World!"
delegate?.didReceiveData(data) } } class ViewController: UIViewController,
DataReceiverDelegate { let dataProvider = DataProvider() override func
viewDidLoad() { super.viewDidLoad() dataProvider.delegate = self
dataProvider.fetchData() } func didReceiveData(_ data: String) {
print(data) // Output: Hello, World! } }
Table View Cell Selection Delegation
import UIKit protocol TableViewCellDelegate: AnyObject { func
didTapCell(withTitle title: String) } class CustomTableViewCell: UITableViewCell {
weak var delegate: TableViewCellDelegate? @IBAction func cellTapped() {
delegate?.didTapCell(withTitle: self.textLabel?.text ?? "") } } class
ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource,
TableViewCellDelegate { let titles = ["Item 1", "Item 2", "Item 3"] @IBOutlet
weak var tableView: UITableView! override func viewDidLoad() {
super.viewDidLoad() tableView.delegate = self tableView.dataSource = self
} func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{ return titles.count } func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell =
tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as!
CustomTableViewCell cell.textLabel?.text = titles[indexPath.row]
cell.delegate = self return cell } func didTapCell(withTitle title:
String) { print("Cell tapped: \(title)") } }

Handling User Input with Forms Tutorial


Handling User Input with Forms in iOS involves using various UI elements such as text fields, sliders,
switches, and buttons to collect data from users. It is essential to validate user input, manage data
effectively, and provide a seamless user experience. This can be achieved through the use of UIKit
components and delegates to respond to user interactions.
Copy
Basic Form Handling
import UIKit

class ViewController: UIViewController {


@IBOutlet weak var nameTextField: UITextField!
@IBOutlet weak var submitButton: UIButton!

override func viewDidLoad() {


super.viewDidLoad()
submitButton.addTarget(self, action: #selector(submitForm), for: .touchUpInside)
}

@objc func submitForm() {


guard let name = nameTextField.text, !name.isEmpty else {
print("Name field is empty")
return
}
print("Hello, \(name)!")
}
}

Using UISlider
import UIKit

class ViewController: UIViewController {


@IBOutlet weak var slider: UISlider!
@IBOutlet weak var valueLabel: UILabel!

override func viewDidLoad() {


super.viewDidLoad()
slider.addTarget(self, action: #selector(sliderValueChanged), for: .valueChanged)
}

@objc func sliderValueChanged(sender: UISlider) {


let value = sender.value
valueLabel.text = "Current Value: \(value)"
}
}

Switch Control Handling


import UIKit

class ViewController: UIViewController {


@IBOutlet weak var toggleSwitch: UISwitch!
@IBOutlet weak var statusLabel: UILabel!

override func viewDidLoad() {


super.viewDidLoad()
toggleSwitch.addTarget(self, action: #selector(switchChanged), for: .valueChanged)
}

@objc func switchChanged(mySwitch: UISwitch) {


statusLabel.text = mySwitch.isOn ? "Switch is ON" : "Switch is OFF"
}
}

You might also like