Mga Espesyalidad ng Swift sa mobile development: ano ito, mga pangunahing tampok at paano ito gumagana

May-akda: IT Sectr Nai-publish: 2026-06-25 Oras ng pagbabasa: 17 min

Ang Swift ay programming language ng Apple na pinagsasama ang kapangyarihan ng Objective-C sa kaligtasan ng mga modernong wika. Hindi tulad ng maraming iba pang mga wika, nag-aalok ang Swift ng mga natatanging konstruksyon: mga uri ng halaga na may awtomatikong pagkopya, Actors na may paghihiwalay sa antas ng compiler, Property Wrappers para sa muling paggamit ng lohika ng pag-aari, at Protocol Oriented Programming bilang alternatibo sa klasikong pamana. Ayon sa Dokumentasyon ng Apple Swift, ang mga tampok na ito ay ginagawang mas ligtas at mahusay ang code.

Mga Pangunahing Punto

  • Struct — uri ng halaga, kinokopya sa pagtatalaga, hindi sumusuporta sa pamana. Class — uri ng sanggunian, ipinapasa sa pamamagitan ng sanggunian, sumusuporta sa pamana at deinit.
  • Actor — uri ng sanggunian na ligtas sa thread na may paghihiwalay sa antas ng compiler. Pinipigilan ng compiler ang sabay-sabay na pag-access sa nababagong estado mula sa iba't ibang mga gawain.
  • Property Wrappers — @Published, @State, @Binding nag-encapsulate ng lohika ng pag-aari sa SwiftUI at Combine, inaalis ang boilerplate code.
  • Generics ay nagpapahintulot sa pagsulat ng type-safe na mga function at istraktura nang hindi nakatali sa isang tiyak na uri. Ang Protocol Oriented Programming ay gumagamit ng extension + protocol sa halip na class hierarchy.
  • Enum na may kaugnay na mga halaga — isang makapangyarihang tool para sa pagmomodelo ng mga estado. Ang bawat kaso ay maaaring mag-imbak ng isang arbitraryong hanay ng data ng iba't ibang uri.

Struct vs Class sa Swift: mga uri ng halaga at mga uri ng sanggunian

Sa Swift, ang struct ay isang uri ng halaga, habang ang class ay isang uri ng sanggunian. Ang pangunahing pagkakaiba na ito ay tumutukoy sa pag-uugali sa panahon ng pagtatalaga, pagpasa sa mga function, at pamamahala ng memorya. Ang struct ay kinokopya nang buo sa bawat pagtatalaga, ang class ay ipinapasa sa pamamagitan ng sanggunian — ang pointer lamang sa heap object ang kinokopya.

Semantika ng Halaga ng Struct

Awtomatikong ipinapatupad ng Struct ang semantika ng halaga — ang bawat instance ay independyente. Ang pagbabago ng pag-aari ng struct ay posible lamang sa pamamagitan ng var, at ang mga pamamaraan na nagbabago ng mga pag-aari ay dapat markahan bilang mutating. Hindi sinusuportahan ng Struct ang pamana ngunit maaaring sumunod sa mga protocol. Ang standard library ng Swift ay gumagamit ng struct para sa String, Array, Dictionary, Int, Bool — lahat ng pangunahing uri ay mga uri ng halaga.

swift
struct User {
    let id: Int
    var name: String

    mutating func updateName(_ newName: String) {
        name = newName
    }
}

var user1 = User(id: 1, name: "Alice")
var user2 = user1
user2.updateName("Bob")
// user1.name === "Alice", user2.name === "Bob"
// Buong kopya — mga independyenteng instance

Semantika ng Sanggunian ng Class

Ang Class ay naka-imbak sa heap at sumusuporta sa pagkakapantay-pantay ng sanggunian. Maraming mga variable ang maaaring sumangguni sa parehong bagay, ang mga pagbabago sa pamamagitan ng isang sanggunian ay nakikita sa lahat ng iba pa. Sumusuporta ang Class sa pamana, nagpapahintulot sa pag-override ng pamamaraan (override), may deinit para sa paglilinis ng mga mapagkukunan. Sa Swift, ang class ay mas madalas na ginagamit kaysa sa struct — inirerekomenda ng Apple na magsimula sa struct at lumipat sa class lamang kapag kailangan ang pamana o semantika ng sanggunian.

swift
class Car {
    let model: String
    var speed: Int

    init(model: String, speed: Int) {
        self.model = model
        self.speed = speed
    }

    func accelerate(_ amount: Int) {
        speed += amount
    }
}

let car1 = Car(model: "Tesla", speed: 0)
let car2 = car1
car2.accelerate(50)
// car1.speed === 50, car2.speed === 50
// Parehong sanggunian — nakikita ang mga pagbabago kahit saan

Ang pagpili sa pagitan ng struct at class ay depende sa semantika ng data. Para sa mga pagsasaayos, modelo ng data at estado gamitin ang struct — mas ligtas at mas predictable ang pagkopya. Para sa mga bagay na may pagkakakilanlan (session ng gumagamit, koneksyon sa database) at kapag kailangan ang pamana, gamitin ang class.

Actor — kaligtasan ng thread sa Swift

Actor ay isang uri ng sanggunian na nagpoprotekta sa nababagong estado mula sa sabay-sabay na pag-access. Ginagarantiya ng Swift compiler na ang mga variable ng actor ay maaaring ma-access lamang mula sa parehong konteksto ng actor — anumang panlabas na pag-access ay nagdudulot ng error sa compilation. Pinipigilan nito ang data races sa antas ng wika, nang walang manu-manong pag-lock.

Paghihiwalay ng Actor

Lahat ng mga pag-aari at pamamaraan ng actor ay nakahiwalay bilang default. Ang pagtawag sa isang pamamaraan ng actor mula sa labas ay nangangailangan ng await — inililipat ng Swift ang pagpapatupad sa actor at pabalik. Isinasabay ng Actor ang pag-access nang sunud-sunod: ang mga kahilingan mula sa iba't ibang mga gawain ay nakapila. Ginagarantiya nito ang pare-parehong estado sa loob ng actor. Ang mga hindi nakahiwalay na pamamaraan (nonisolated) ay maaaring tawagan nang walang await ngunit hindi maaaring ma-access ang mga nababagong pag-aari.

swift
actor BankAccount {
    private var balance: Double

    init(initialBalance: Double) {
        balance = initialBalance
    }

    func deposit(amount: Double) {
        balance += amount
    }

    func withdraw(amount: Double) throws {
        guard balance >= amount else {
            throw BankError.insufficientFunds
        }
        balance -= amount
    }

    nonisolated func accountInfo() -> String {
        return "Bank Account"
    }
}

let account = BankAccount(initialBalance: 1000)
await account.deposit(amount: 500)
// balance = 1500 — atomic, walang kondisyon ng karera

Ang Actor ay kapaki-pakinabang para sa mga tagapamahala ng estado, cache at mga serbisyo sa network kung saan maraming mga gawain ang sabay-sabay na nagbabasa at nagsusulat ng data. Hindi tulad ng manu-manong pag-synchronize sa pamamagitan ng NSLock o DispatchQueue, ang actor ay sinusuri sa oras ng compilation — imposibleng magkamali. Ang mga error sa paghihiwalay ay lilitaw sa oras ng compilation, hindi sa runtime.

Property Wrappers: @Published, @State, @Binding

Property Wrapper ay isang anotasyon na nagdaragdag ng pag-uugali sa isang pag-aari nang hindi binabago ang deklarasyon nito. Ang SwiftUI at Combine ay nagbibigay ng mga built-in na wrapper para sa pamamahala ng estado ng mga view. Ang compiler ay bumubuo ng code na bumabalot sa pag-access sa pag-aari, nagdaragdag ng lohika ng pagmamasid, pag-synchronize o pagbabago.

@Published at @State

@Published ay ginagamit sa mga klase na sumusunod sa ObservableObject upang awtomatikong mag-publish ng mga pagbabago. Ang mga subscriber ng Combine ay tumatanggap ng mga abiso sa bawat update. @State ay ang lokal na estado ng isang SwiftUI view. Awtomatikong iginuhit muli ng SwiftUI ang view kapag nagbago ang @State. @Binding ay lumilikha ng dalawang-daanang koneksyon sa pagitan ng isang magulang at anak na view nang hindi nagmamay-ari ng data.

swift
import SwiftUI
import Combine

@main
struct CounterApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

class CounterViewModel: ObservableObject {
    @Published var count: Int = 0

    func increment() {
        count += 1
    }
}

struct ContentView: View {
    @State private var greeting: String = "Kumusta"
    @StateObject private var viewModel = CounterViewModel()

    var body: some View {
        VStack {
            CounterDisplay(count: $viewModel.count)
            Text(greeting)
            Button("Dagdagan", action: viewModel.increment)
        }
    }
}

struct CounterDisplay: View {
    @Binding var count: Int

    var body: some View {
        Text("Bilang: \(count)")
    }
}

Ang mga custom na Property Wrappers ay nilikha gamit ang @propertyWrapper at isang istraktura na may wrappedValue field. Ito ay nagpapahintulot sa muling paggamit ng lohika: pagpapatunay, normalisasyon, pag-iimbak ng UserDefaults. Ang Property Wrappers ay makabuluhang binabawasan ang boilerplate code at ginagawang tahasan ang intensyon ng developer sa pamamagitan ng anotasyon.

swift
@propertyWrapper
struct Clamped<T: Comparable> {
    private var value: T
    let range: ClosedRange<T>

    init(wrappedValue: T, range: ClosedRange<T>) {
        self.range = range
        self.value = min(max(wrappedValue, range.lowerBound), range.upperBound)
    }

    var wrappedValue: T {
        get { value }
        set { value = min(max(newValue, range.lowerBound), range.upperBound) }
    }
}

struct Settings {
    @Clamped(range: 0...100) var volume: Int = 50
}

var s = Settings()
s.volume = 150
// s.volume === 100 — awtomatikong nilimitahan ang halaga

Generics at Protocol Oriented Programming

Generics ay isang makapangyarihang mekanismo ng Swift para sa pagsulat ng flexible na code nang hindi nawawala ang kaligtasan ng uri. Ang mga generic na function at uri ay gumagana sa anumang uri na nakakatugon sa mga hadlang. Ang Protocol Oriented Programming (POP) ay isang paradigm ng Swift kung saan ang protocol + extension ay pumapalit sa klasikong pamana ng klase, na nagbibigay ng komposisyon ng pag-uugali.

Mga Generic na Hadlang at Kaugnay na Uri

Pinapayagan ng Swift na paghigpitan ang mga generic na parameter sa mga protocol (where clauses). Ang protocol na may kaugnay na uri ay ang generic na katumbas para sa mga protocol: ang konkretong uri ay tinutukoy sa oras ng pagsunod. Ito ang batayan para sa type-safe na mga koleksyon at algorithm. Ang standard library ng Swift ay aktibong gumagamit ng Generics: Array, Dictionary, Optional — lahat ay generic na uri.

swift
protocol Cacheable {
    associatedtype Key: Hashable
    associatedtype Value

    func get(_ key: Key) -> Value?
    mutating func set(_ value: Value, for key: Key)
}

struct MemoryCache<K: Hashable, V>: Cacheable {
    private var storage: [K: V] = [:]

    typealias Key = K
    typealias Value = V

    func get(_ key: K) -> V? {
        return storage[key]
    }

    mutating func set(_ value: V, for key: K) {
        storage[key] = value
    }
}

func firstMatch<T: Equatable>(in array: [T], target: T) -> Int? {
    for (index, item) in array.enumerated() {
        if item == target {
            return index
        }
    }
    return nil
}

let numbers = [10, 20, 30, 40]
let index = firstMatch(in: numbers, target: 30)
// index === 2 — isang generic na pamamaraan para sa lahat ng uri ng Equatable

Protocol Extension at Default na Implementasyon

Ang protocol extension ay isang pangunahing mekanismo ng POP. Sa isang extension, maaaring magbigay ng default na implementasyon ng mga pamamaraan ng protocol. Ang mga uri na sumusunod sa protocol ay nakakakuha ng implementasyong ito ng libre at maaaring i-override ito kung kinakailangan. Ito ay nagpapahintulot sa pagbuo ng hierarchy ng pag-uugali nang walang pamana ng klase — isang alternatibo sa maramihang pamana, na hindi umiiral sa Swift.

swift
protocol Drivable {
    var speed: Double { get set }
    func drive()
}

extension Drivable {
    func drive() {
        if speed > 0 {
            print("Nagmamaneho sa \(speed) km/h")
        }
    }
}

struct Bicycle: Drivable {
    var speed: Double = 15
}

struct Plane: Drivable {
    var speed: Double = 900

    func drive() {
        print("Lumilipad sa \(speed) km/h")
    }
}

let bike = Bicycle()
bike.drive() // "Nagmamaneho sa 15.0 km/h" — default

let plane = Plane()
plane.drive() // "Lumilipad sa 900.0 km/h" — na-override

Ang POP na may extension ay nagbibigay-daan sa komposisyon sa pamamagitan ng maramihang mga protocol — isang uri ay maaaring sumunod sa maraming mga protocol, na nakakakuha ng kanilang mga implementasyon. Ito ay mas flexible kaysa sa solong pamana ng klase kung saan ang buong hierarchy ay naayos. Ang standard library ng Swift ay binuo sa POP: CustomStringConvertible, Equatable, Hashable, Codable — lahat ay mga protocol na may mga extension.

Enum na may kaugnay na mga halaga at Extension

Enum sa Swift ay isang mas makapangyarihang konstruksyon kaysa sa ibang mga wika. Ang bawat kaso ay maaaring magkaroon ng kaugnay na mga halaga — isang arbitraryong hanay ng data ng anumang uri. Kapag pinagsama sa extension at pattern matching, ang enum ay nagiging batayan para sa pagmomodelo ng mga estado, resulta ng operasyon at finite state machine.

Kaugnay na mga Halaga at Pattern Matching

Ang kaugnay na mga halaga ay nagpapahintulot sa bawat kaso na mag-imbak ng natatanging data. Halimbawa, ang kaso ng loading ay walang data, ang success ay naglalaman ng resulta, ang failure ay naglalaman ng error. Ang pattern matching sa pamamagitan ng switch ay kumukuha ng kaugnay na mga halaga at nagpoproseso ng bawat kaso. Sinusuri ng compiler ang pagkakumpleto (exhaustive switch) — inaalis nito ang mga nakalimutang estado.

swift
enum NetworkResult<T> {
    case loading
    case success(T)
    case failure(Error)
}

enum MediaFile {
    case image(url: URL, width: Int, height: Int)
    case video(url: URL, duration: Double)
    case audio(url: URL, bitrate: Int)
}

func handle(_ result: NetworkResult<String>) {
    switch result {
    case .loading:
        print("Naglo-load...")
    case .success(let data):
        print("Natanggap: \(data)")
    case .failure(let error):
        print("Error: \(error.localizedDescription)")
    }
}

let file = MediaFile.video(url: URL(string: "https://example.com/video.mp4")!, duration: 120)

if case .video(let url, let duration) = file {
    print("Video \(url) tagal \(duration)s")
}

Extension para sa Enum

Pinapayagan ng Swift ang pagdaragdag ng mga pamamaraan, kinakalkulang mga pag-aari at pagsunod sa protocol sa pamamagitan ng extension para sa enum. Hindi ito nangangailangan ng pagbabago sa orihinal na deklarasyon — ang code ay nananatiling malinis at modular. Ang mga pamamaraan sa extension ay maaaring gumana sa kaugnay na mga halaga, kalkulahin ang hinangong data at magpatupad ng lohika ng negosyo.

swift
extension MediaFile {
    var fileName: String {
        switch self {
        case .image(let url, _, _),
             .video(let url, _),
             .audio(let url, _):
            return url.lastPathComponent
        }
    }

    var description: String {
        switch self {
        case .image(_, let w, let h):
            return "Larawan \(w)x\(h)"
        case .video(_, let d):
            return "Video \(d)s"
        case .audio(_, let b):
            return "Audio \(b) kbps"
        }
    }
}

extension MediaFile: Equatable {
    static func == (lhs: MediaFile, rhs: MediaFile) -> Bool {
        return lhs.fileName == rhs.fileName
    }
}

let files: [MediaFile] = [file]
files.forEach { print($0.description) }
// "Video 120.0s"

Ang Enum na may kaugnay na mga halaga + extension ay ang kapalit para sa mga sealed class mula sa Kotlin o discriminated unions mula sa ibang mga wika. Ginagamit ng Swift ang kombinasyong ito para sa Result (isang standard na uri sa standard library), Optional (Optional ay isang enum na may .none at .some) at paghawak ng estado sa SwiftUI. Ginagarantiya ng pattern matching na ang lahat ng estado ay hinahawakan — imposible ang mga error sa runtime.

Mga Madalas Itanong

Paano naiiba ang struct sa class sa Swift?

Struct — uri ng halaga, kinokopya sa pagtatalaga, hindi sumusuporta sa pamana. Class — uri ng sanggunian, ipinapasa sa pamamagitan ng sanggunian, sumusuporta sa pamana, deinit at pagsusuri ng pagkakakilanlan (===). Inirerekomenda ng Apple na magsimula sa struct at lumipat sa class lamang kapag kinakailangan ang semantika ng sanggunian.

Ano ang Actor sa Swift at kailan ito gagamitin?

Actor — uri ng sanggunian na ligtas sa thread. Pinipigilan ng compiler ang sabay-sabay na pag-access sa nababagong estado mula sa iba't ibang konteksto. Gamitin ang Actor para sa mga tagapamahala ng estado, cache at serbisyo na ina-access ng maraming gawain. Ang pagtawag sa mga pamamaraan ng actor ay nangangailangan ng await.

Anong Property Wrappers ang ginagamit sa SwiftUI?

Pangunahin: @State — lokal na estado ng view; @Binding — koneksyon ng data nang walang pagmamay-ari; @Published — pag-publish ng mga pagbabago sa ObservableObject; @StateObject — pagmamay-ari ng ObservableObject; @EnvironmentObject — dependency mula sa kapaligiran. Ang mga custom na wrapper ay ginagawa sa pamamagitan ng @propertyWrapper.

Ano ang Protocol Oriented Programming?

POP — isang paradigm kung saan ang protocol + extension ay tumutukoy sa pag-uugali sa halip na pamana ng klase. Ang isang uri ay sumusunod sa maraming mga protocol, na nakakakuha ng kanilang mga implementasyon nang libre. Ito ay komposisyon sa halip na pamana — mas flexible at ligtas. Ang standard library ng Swift (Equatable, Codable) ay binuo sa POP.

Paano naiiba ang enum sa Swift mula sa enum sa ibang mga wika?

Ang enum sa Swift ay sumusuporta sa kaugnay na mga halaga — bawat kaso ay maaaring mag-imbak ng arbitraryong data ng iba't ibang uri. Kapag pinagsama sa pattern matching (switch), nagbibigay ito ng isang makapangyarihang modelo para sa mga estado, error at Domain-Driven Design. Ang Optional at Result ay standard na Swift enum na may kaugnay na mga halaga.

Buod

  • Struct vs Class — pangunahing pagkakaiba: ang mga uri ng halaga ay kinokopya, ang mga uri ng sanggunian ay ipinapasa sa pamamagitan ng sanggunian. Ang struct ay hindi sumusuporta sa pamana, ang class ay sumusuporta. Inirerekomenda ng Apple ang struct bilang default.
  • Actor — kaligtasan ng thread sa antas ng compiler. Nakahiwalay na nababagong estado, pag-access sa pamamagitan ng await, proteksyon mula sa data races nang walang manu-manong pag-lock.
  • Property Wrappers — @Published, @State, @Binding at custom sa pamamagitan ng @propertyWrapper. Nagbabawas ng boilerplate code at ginagawang tahasan ang intensyon sa pamamagitan ng anotasyon.
  • Generics — type-safe na mga function at uri na may where constraints. Protocol + kaugnay na uri para sa mga abstraction. Ang standard library ng Swift ay ganap na binuo sa generics.
  • Protocol Oriented Programming — komposisyon ng pag-uugali sa pamamagitan ng protocol extension. Ang mga default na implementasyon ay nagpapahintulot sa muling paggamit ng code nang walang pamana ng klase.
  • Enum na may kaugnay na mga halaga — isang makapangyarihang modelo para sa mga estado. Ang bawat kaso ay nag-iimbak ng natatanging data. Ginagarantiya ng pattern matching na ang lahat ng estado ay hinahawakan.
  • Extension — nagdaragdag ng mga pamamaraan, kinakalkulang mga pag-aari at pagsunod sa protocol para sa anumang uri, kabilang ang enum. Ang code ay nananatiling modular at malinis nang hindi binabago ang orihinal na deklarasyon.

Gagawa kami ng mobile application na turnkey

Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.

Pag-usapan ang proyekto