> For the complete documentation index, see [llms.txt](https://docs.ecommerce.seb.ee/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ecommerce.seb.ee/seb-docs-draft/seb-docs-public-et/integratsioon/mobiilne-sdk/ios-sdk/sdk-kasutamine/objective-c-ja-swiftui.md).

# Objective-C ja SwiftUI

Kutsuge SDK-d välja Objective-C-st, SwiftUI-st ja asünkroonsest koodist ning kasutage completion-ploki asemel delegaati.

Kasuta seda juhendit, kui sinu väljakutsekoht ei ole puhas Swift `UIViewController`.

Avalik API on läbivalt Objective-C-ga ühilduv, mis teeb Objective-C toe võimalikuks ja välistab ainult Swiftile või ainult SwiftUI-le suunatud kasutusliidese. Allpool olevad sillad katavad selle vahe.

***

## Objective-C

Objective-C-s kannavad tüübid üht `EGW` eesliidet. `PaymentKit` on `EGWPaymentKit`, `Configuration` on `EGWConfiguration`, ja nii edasi.

### Majutatud kassaleht

```objc
@import EGWPay;

EGWConfiguration *configuration =
    [[EGWConfiguration alloc] initWithApiBaseURL:[NSURL URLWithString:@"https://your-backend.example.com"]
                                     environment:EGWEnvironmentSandbox];

EGWPaymentKit *paymentKit = [[EGWPaymentKit alloc] initWithConfiguration:configuration];

EGWPaymentRequest *request =
    [[EGWPaymentRequest alloc] initWithPaymentId:paymentId
                                 verificationKey:verificationKey
                                     checkoutURL:checkoutURL
                                       returnURL:[NSURL URLWithString:@"myapp://checkout/return"]];

[paymentKit startPayment:request from:self completion:^(EGWPaymentResult *result) {
    switch (result.outcome) {
        case EGWPaymentOutcomeSucceeded:
            [self showReceiptWithReference:result.orderNumber ?: result.paymentId];
            break;
        case EGWPaymentOutcomeFailed:
            [self showFailure:result.error];
            break;
        case EGWPaymentOutcomeCancelled:
            break;
        case EGWPaymentOutcomeUnresolved:
            [self confirmWithBackend:result.paymentId];
            break;
    }
}];
```

### Natiivne kaardivorm

```objc
EGWConfiguration *configuration =
    [[EGWConfiguration alloc] initWithApiBaseURL:[NSURL URLWithString:@"https://your-backend.example.com"]
                              checkoutAPIBaseURL:[NSURL URLWithString:@"https://sandbox-api.example.com"]
                                 checkoutBaseURL:[NSURL URLWithString:@"https://sandbox-checkout.example.com"]
                                     environment:EGWEnvironmentSandbox];

EGWPaymentKit *paymentKit = [[EGWPaymentKit alloc] initWithConfiguration:configuration];

EGWCardInput *card = [[EGWCardInput alloc] init];
card.cardholderName = self.nameField.text;
card.cardNumber = self.numberField.text;
card.expiryMonth = self.expiryField.month;
card.expiryYear = self.expiryField.year;
card.securityCode = self.securityCodeField.text;

EGWCardPaymentRequest *request =
    [[EGWCardPaymentRequest alloc] initWithPaymentId:paymentId
                                     verificationKey:verificationKey];

[paymentKit startCardPayment:request card:card from:self completion:^(EGWPaymentResult *result) {
    // Sama tulemuse käsitlemine nagu eespool.
}];
```

### Delegaadi kasutamine ploki asemel

Mõlemal sisestuspunktil on delegaadipõhine ülekoormus. Delegaati hoitakse nõrga viitega, seega säilita sellele oma tugev viide.

```objc
@interface CheckoutViewController () <EGWPaymentDelegate>
@end

@implementation CheckoutViewController

- (void)pay {
    [self.paymentKit startPayment:self.request from:self delegate:self];
}

- (void)paymentDidFinish:(EGWPaymentResult *)result {
    // Kutsutakse üks kord, peateemas, pärast SDK kasutajaliidese sulgemist.
}

@end
```

Sama paaristus on olemas ka Swiftis: `startPayment(_:from:delegate:)` ja `startCardPayment(_:card:from:delegate:)` võta `PaymentDelegate` ning kutsu `paymentDidFinish(_:)`.

***

## SwiftUI

`startPayment` esitab alates `UIViewController`, mida SwiftUI sulle otse ei anna. Silda see üks kord üle:

```swift
import SwiftUI
import UIKit

/// Avaldab SwiftUI koodile lähima UIKiti vaatekontrolleri.
struct ViewControllerProvider: UIViewControllerRepresentable {
    final class Holder: UIViewController {}

    @Binding var controller: UIViewController?

    func makeUIViewController(context: Context) -> Holder {
        let holder = Holder()
        DispatchQueue.main.async { controller = holder }
        return holder
    }

    func updateUIViewController(_ uiViewController: Holder, context: Context) {}
}
```

Seejärel kasuta seda kõikjal, kus alustad makset:

```swift
struct CheckoutButton: View {
    @State private var presenter: UIViewController?
    let request: PaymentRequest
    let paymentKit: PaymentKit

    var body: some View {
        Button("Maksa") {
            guard let presenter else { return }
            paymentKit.startPayment(request, from: presenter) { result in
                // Käsitle tulemust.
            }
        }
        .background(ViewControllerProvider(controller: $presenter).frame(width: 0, height: 0))
    }
}
```

**Jäta esitluskoht vabaks.** Kui sinu kassakuva ise asub `.sheet` või `.fullScreenCover` sees, võib SDK esitamine sealt ebaõnnestuda. Ava selle asemel kassakuva.

### Sildamine `async-iga`

SDK põhineb lõpetuskutsel. Paki see üks kord ümber:

```swift
func pay(_ request: PaymentRequest, from presenter: UIViewController) async -> PaymentResult {
    await withCheckedContinuation { continuation in
        paymentKit.startPayment(request, from: presenter) { continuation.resume(returning: $0) }
    }
}
```

See on ohutu täpselt seetõttu, et lõpetuskutse käivitub täpselt üks kord. Jätku taasavamine kaks korda põhjustaks kokkujooksmise ning tagasikutse leping välistab selle.

### Kaarditekstiväljade ümberpakkimine

Kaarditekstiväljad on tavalised `UITextField` alamklassid, seega pakitakse need kokku nagu iga teinegi:

```swift
struct CardNumberField: UIViewRepresentable {
    @Binding var text: String

    func makeUIView(context: Context) -> CardNumberTextField {
        let field = CardNumberTextField()
        field.addTarget(context.coordinator,
                        action: #selector(Coordinator.changed),
                        for: .editingChanged)
        return field
    }

    func updateUIView(_ uiView: CardNumberTextField, context: Context) {}

    func makeCoordinator() -> Coordinator { Coordinator(text: $text) }

    final class Coordinator: NSObject {
        @Binding var text: String
        init(text: Binding<String>) { _text = text }
        @objc func changed(_ sender: CardNumberTextField) { text = sender.text ?? "" }
    }
}
```

***

## Järgmised sammud

* [API viide](/seb-docs-draft/seb-docs-public-et/integratsioon/mobiilne-sdk/ios-sdk/viide/api.md) - iga tüüp nii selle Swifti kui ka Objective-C nime all.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.ecommerce.seb.ee/seb-docs-draft/seb-docs-public-et/integratsioon/mobiilne-sdk/ios-sdk/sdk-kasutamine/objective-c-ja-swiftui.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
