Μετάβαση στο κύριο περιεχόμενο

Ενσωμάτωση iOS SDK

Εγγενές iOS SDK για παρακολούθηση συμβάντων, διαχείριση συνεδριών χρηστών, αποστολή push notifications και εμφάνιση μηνυμάτων εντός εφαρμογής.

Δυνατότητες

  • Ελαφρύ - Ελάχιστο αποτύπωμα
  • Γρήγορο - Βελτιστοποιημένο για απόδοση
  • Υποστήριξη εκτός σύνδεσης - Ουρά συμβάντων βασισμένη σε SQLite
  • Αυτόματη επανάληψη - Exponential backoff σε αποτυχίες
  • Ομαδοποίηση - Αποτελεσματική ομαδοποίηση συμβάντων (50 συμβάντα / 5 δευτ.)
  • Μηνύματα εντός εφαρμογής - native και HTML μηνύματα, 5 τύποι, με frequency capping
  • Push Notifications - Apple Push Notification Service (APNS)
  • Απόρρητο πρώτα - Συμβατό με GDPR, σέβεται τη συγκατάθεση χρήστη
  • iOS 14+ - Υποστήριξη σύγχρονων εκδόσεων iOS

Απαιτήσεις

  • iOS 14.0+
  • Xcode 15.0+
  • Swift 5.9+

Εγκατάσταση

Swift Package Manager

Το SDK διανέμεται ως πακέτο Swift. Προσθέστε το ακόλουθο στο Package.swift:

dependencies: [
.package(url: "https://github.com/joryio/joryio-ios.git", from: "1.0.0")
]

Το πακέτο παρέχει δύο products. Συνδέστε όποιο χρειάζεται η εφαρμογή σας:

.target(
name: "YourApp",
dependencies: [
.product(name: "Joryio", package: "joryio-ios"), // tracking, ταυτότητα, push
.product(name: "JoryioUI", package: "joryio-ios"), // + εμφάνιση in-app μηνυμάτων
]
)

CocoaPods

pod 'Joryio/UI'   # τα πάντα, μαζί με την in-app εμφάνιση
# pod 'Joryio' # μόνο tracking, ταυτότητα και push - χωρίς WebKit
Ποιο από τα δύο;

Το JoryioUI εξαρτάται από το Joryio, οπότε συνδέοντας το product UI τα παίρνετε και τα δύο.

Πάρτε μόνο το Joryio όταν η εφαρμογή δεν χρειάζεται in-app μηνύματα ή όταν ένας έλεγχος ασφαλείας αντιτίθεται στη σύνδεση web view. Προσοχή: η προεπιλογή στο CocoaPods είναι το Joryio χωρίς UI - το pod 'Joryio' δεν θα εμφανίζει in-app μηνύματα μέχρι να το αλλάξετε σε pod 'Joryio/UI'.

Ή στο Xcode:

  1. File → Add Package Dependencies
  2. Εισαγάγετε: https://github.com/joryio/joryio-ios.git
  3. Επιλέξτε έκδοση και προσθέστε στον target

Γρήγορη εκκίνηση

1. Αρχικοποιήστε το SDK

Στο AppDelegate.swift:

import Joryio

func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {

// Initialize with your SDK key
Joryio.shared.initialize(
sdkKey: "jry_sdk_ios_YOUR_SDK_KEY",
apiHost: "api-eu1.joryio.com"
)

return true
}
Εύρεση του κλειδιού SDK

Βρείτε το κλειδί SDK στο dashboard του Joryio στις Ρυθμίσεις → Εφαρμογές → [Η εφαρμογή σας] → SDK Keys.

2. Παρακολουθήστε συμβάντα

// Basic event
Joryio.shared.track("Button Tapped")

// Event with properties
Joryio.shared.track("Product Viewed", properties: [
"product_id": "abc123",
"product_name": "Wireless Headphones",
"price": 99.99,
"category": "Electronics"
])

// Screen view
Joryio.shared.trackScreen("ProductDetail", properties: [
"product_id": "abc123"
])

3. Αναγνωρίστε χρήστες

// Identify a user
Joryio.shared.identify("user-123")
Joryio.shared.setAttributes([
"email": "user@example.com",
"name": "John Doe",
"plan": "premium"
])

// Set attributes later
Joryio.shared.setAttribute("last_purchase", value: Date())
Joryio.shared.incrementAttribute("lifetime_value", by: 99.99)

// On logout
Joryio.shared.reset()

Αυτόματα δεδομένα συνεδρίας

Το iOS SDK εμπλουτίζει τα συμβάντα Session Start με δεδομένα συσκευής και περιβάλλοντος:

  • $device_id
  • $platform (ios)
  • $model
  • $os_name / $os_version
  • $app_version / $build_number
  • $bundle_id
  • $screen_width / $screen_height
  • $locale
  • $language / $languages
  • $timezone
  • country (ISO-3166-1 alpha-2, προέρχεται από IP κατά την έναρξη συνεδρίας)

Push Notifications

Ενεργοποιήστε push notifications για αποστολή στοχευμένων μηνυμάτων μέσω Apple Push Notification Service (APNS).

1. Ρύθμιση στο AppDelegate

import Joryio

class AppDelegate: UIResponder, UIApplicationDelegate {

func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// Initialize SDK
Joryio.shared.initialize(
sdkKey: "jry_sdk_ios_YOUR_KEY",
apiHost: "api-eu1.joryio.com"
)

// Request push permissions
Task {
let granted = await Joryio.shared.requestPushPermissions()
if granted {
print("Push notifications enabled")
}
}

return true
}

// Handle device token registration
func application(
_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
Joryio.shared.didRegisterForRemoteNotifications(deviceToken: deviceToken)
}

// Handle registration failure
func application(
_ application: UIApplication,
didFailToRegisterForRemoteNotificationsWithError error: Error
) {
Joryio.shared.didFailToRegisterForRemoteNotifications(error: error)
}

// Handle received push notification
func application(
_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
) {
Joryio.shared.didReceiveRemoteNotification(userInfo, completionHandler: completionHandler)
}
}

2. Ρύθμιση APNS στο dashboard

Για να στείλετε push notifications, ρυθμίστε τα διαπιστευτήρια APNS:

  1. Μεταβείτε στις Ρυθμίσεις → Εφαρμογές → [Η εφαρμογή σας]
  2. Ανοίξτε την καρτέλα Push Notifications
  3. Ανεβάστε το πιστοποιητικό APNS (.p12) ή κλειδί ελέγχου ταυτότητας (.p8)
  4. Εισαγάγετε Team ID και Key ID (για .p8)
  5. Επιλέξτε περιβάλλον (Development/Production)

3. Δυνατότητες push

// Check if push is enabled
let isEnabled = await Joryio.shared.isPushEnabled()

// Get device token
if let token = Joryio.shared.getDeviceToken() {
print("Device token: \(token)")
}

// Badge management
Joryio.shared.updateBadgeCount(5)
Joryio.shared.clearBadge()

// Unregister from push
Joryio.shared.unregisterFromPushNotifications()

Μηνύματα εντός εφαρμογής

Εμφανίστε στοχευμένα μηνύματα εντός εφαρμογής σε χρήστες με βάση τη συμπεριφορά και τα γνωρίσματά τους.

Tokens παράδοσης (delivery tokens)

Όταν ο διακομιστής σερβίρει μια επιλέξιμη καμπάνια, εκδίδει επίσης ένα υπογεγραμμένο token παράδοσης μικρής διάρκειας. Το SDK το επιστρέφει όταν αναφέρει εμφάνιση, κλικ ή απόρριψη, και ο διακομιστής επαληθεύει την υπογραφή πριν καταγράψει οτιδήποτε.

Δεν χρειάζεται να κάνετε τίποτα - το SDK το χειρίζεται για εσάς. Τεκμηριώνεται επειδή αλλάζει τι συμβαίνει σε έναν client που δεν στέλνει token:

POST /v1/in-app/track   (no deliveryToken)
{ "success": false, "error": "A delivery token is required" }

Το token είναι αυτό που κάνει μια εμφάνιση αξιόπιστη: χωρίς αυτό, οποιοσδήποτε κατέχει το SDK key - το οποίο περιλαμβάνεται σε κάθε εφαρμογή και σελίδα - θα μπορούσε να αναφέρει εμφανίσεις και κλικ για μια καμπάνια που δεν εμφανίστηκε ποτέ, και τα δεδομένα σας θα τα μετρούσαν.

Αν οι εμφανίσεις in-app σταματήσουν να καταγράφονται, ελέγξτε ότι η εφαρμογή έχει χτιστεί με τρέχουσα έκδοση του SDK: μια έκδοση από πριν υπάρξουν τα tokens παράδοσης δεν στέλνει token και ο διακομιστής θα απορρίψει τις εμφανίσεις της.

Αυτόματος συγχρονισμός καμπανιών

Το SDK συγχρονίζει αυτόματα καμπάνιες από τον διακομιστή όταν:

  • Η εφαρμογή εισέρχεται στο προσκήνιο
  • Λαμβάνεται push notification

Οι συγχρονισμοί περιορίζονται σε έναν το πολύ ανά διάστημα συγχρονισμού. Καλέστε syncInAppCampaigns() για συγχρονισμό σε άλλες στιγμές, όπως μετά την αναγνώριση χρήστη ή την ενημέρωση γνωρισμάτων.

Μη αυτόματος έλεγχος καμπάνιας

// Manually sync campaigns from server
await Joryio.shared.syncInAppCampaigns()

// Manually trigger campaign evaluation
await Joryio.shared.evaluateInAppCampaigns()

// Reset displayed campaigns (for testing)
Joryio.shared.resetDisplayedCampaigns()

Δύο είδη περιεχομένου

Κάθε καμπάνια φτάνει σε μία από δύο μορφές περιεχομένου και το SDK αποδίδει την καθεμία διαφορετικά:

ΠεριεχόμενοΤι είναιΠώς αποδίδεται
NativeΔομημένα δεδομένα - τίτλος, κείμενο, εικόνα, κουμπιάΠραγματικά UIKit views, με το χρώμα τόνου, το Dynamic Type, τη σκοτεινή λειτουργία και το VoiceOver της εφαρμογής σας. Χωρίς web view.
HTMLΚώδικας HTML, CSS και JavaScript γραμμένος από τον συντάκτηΈνα WKWebView μέσα στο μήνυμα.

Ενεργοποίηση μηνυμάτων HTML

Τα μηνύματα HTML είναι απενεργοποιημένα από προεπιλογή. Ένα μήνυμα HTML εκτελεί JavaScript γραμμένη από τον συντάκτη μέσα στην εφαρμογή σας, οπότε η ενεργοποίηση είναι απόφαση της ομάδας της εφαρμογής - όχι κάτι που ενεργοποιείται από μια πλατφόρμα μάρκετινγκ:

let config = JoryioConfig(
inApp: InAppConfig(allowHtmlJsInAppMessages: true) // προεπιλογή: false
)

Joryio.shared.initialize(
sdkKey: "jry_sdk_ios_YOUR_KEY",
apiHost: "api-eu1.joryio.com",
config: config
)

Αφήνοντάς το απενεργοποιημένο δεν απενεργοποιείτε τα in-app μηνύματα. Τα native μηνύματα συνεχίζουν να εμφανίζονται, επειδή είναι δεδομένα που αποδίδουν τα ίδια τα views του SDK - χωρίς κανέναν διερμηνέα. Οι καμπάνιες HTML παραλείπονται και καταγράφονται.

Αν η πολιτική ασφαλείας σας απαγορεύει την εκτέλεση συντεταγμένου HTML εντός της διεργασίας, αφήστε το απενεργοποιημένο και συντάξτε τις καμπάνιες σας ως native μηνύματα.

tvOS

Το tvOS δεν διαθέτει καθόλου web view, οπότε τα μηνύματα HTML δεν εμφανίζονται ποτέ εκεί, ανεξάρτητα από αυτή τη ρύθμιση. Συντάξτε native μηνύματα για στόχους tvOS.

Απόδοση των μηνυμάτων μόνοι σας

Το SDK σχεδιάζει τα native μηνύματα για εσάς, αλλά μπορείτε να αναλάβετε πλήρως - η ίδια διέξοδος που άλλοι προμηθευτές ονομάζουν custom view factory. Υλοποιήστε το InAppMessagePresenter και αναθέστε το:

Joryio.shared.inAppPresenter = MyPresenter()

Η αυτόματη ανίχνευση τρέχει μόνο όταν το inAppPresenter είναι nil, οπότε το δικό σας αντικαθιστά τον ενσωματωμένο renderer αντί να συγκρούεται μαζί του.

Ο presenter λαμβάνει την καμπάνια με το content ήδη έτοιμο - το Liquid αποδίδεται στον διακομιστή και τα native πεδία φτάνουν ως απλό κείμενο. Καταγράψτε ό,τι εμφανίζετε με Joryio.shared.trackInAppImpression(campaignId, action:).

Το όνομα της κλάσης διαφέρει ανά package manager

Δεν το ρυθμίζετε, αλλά αξίζει να το ξέρετε όταν κάτι δεν εμφανίζεται. Το SDK βρίσκει τον ενσωματωμένο renderer με το όνομά του κατά την εκτέλεση, και το module στο οποίο ζει αυτό το όνομα εξαρτάται από τον τρόπο ενσωμάτωσης:

πώς πακετάρεταικλάση που αναζητά το SDK
SwiftPMτο JoryioUI είναι δικό του targetJoryioUI.DefaultInAppMessagePresenter
CocoaPodsτο Joryio/UI είναι subspec, και τα subspecs μοιράζονται το module του podJoryio.DefaultInAppMessagePresenter

Δοκιμάζονται και τα δύο ονόματα. Αν δεν εμφανίζεται ποτέ μήνυμα, αναζητήστε την προειδοποίηση "No in-app presenter found" - σημαίνει ότι το προϊόν UI δεν είναι συνδεδεμένο (pod 'Joryio/UI' ή το προϊόν JoryioUI στο SwiftPM), όχι ότι η καμπάνια δεν έφτασε. Απ' έξω τα δύο μοιάζουν ίδια.

Ο δικός σας presenter δεν χρειάζεται τίποτα από αυτά: αναθέστε τον και η ανίχνευση δεν τρέχει καθόλου.

Τύποι μηνυμάτων

Το SDK υποστηρίζει 5 τύπους μηνυμάτων:

  1. Modal - Στο κέντρο της οθόνης με σκίαση
  2. Banner - Στο επάνω μέρος της οθόνης
  3. Slide-Up - Μικρή ειδοποίηση από κάτω
  4. Full-Screen - Μήνυμα που καταλαμβάνει την οθόνη
  5. Custom - Η εφαρμογή σας αποφασίζει τη θέση

Frequency Capping

Τα μηνύματα τηρούν τους κανόνες επικοινωνίας σε επίπεδο workspace και τα όρια συχνότητας σε επίπεδο καμπάνιας:

  • Μέγιστες εμφανίσεις ανά χρονικό παράθυρο
  • Ελάχιστη καθυστέρηση μεταξύ μηνυμάτων
  • Όρια συχνότητας ανά καμπάνια

Επιλογές ρυθμίσεων

Προσαρμόστε τη συμπεριφορά του SDK με JoryioConfig:

JoryioConfig(
// User Identification
userId: String?, // Initialize with known user ID
anonymousId: String?, // Custom anonymous ID

// Batching & Performance
batchSize: Int, // Default: 50
flushInterval: TimeInterval, // Default: 5.0 seconds
sendImmediately: Bool, // Default: false
maxQueueSize: Int, // Default: 1000

// Session Management
sessionTimeout: TimeInterval, // Default: 1800 (30 minutes)
trackSessionStart: Bool, // Default: true

// Storage
persistQueue: Bool, // Default: true

// Network & Retry
maxRetries: Int, // Default: 3
retryBackoffMs: Double, // Default: 1000.0
requestTimeout: TimeInterval, // Default: 10.0

// Privacy & GDPR
respectDoNotTrack: Bool, // Default: true
optOut: Bool, // Default: false
trackingConsent: TrackingConsent, // Default: .granted

// Debugging
enableDebug: Bool, // Default: false
logLevel: LogLevel // Default: .error
)

Προηγμένες δυνατότητες

Διαχείριση γνωρισμάτων χρήστη

// Set multiple attributes
Joryio.shared.setAttributes([
"age": 28,
"city": "San Francisco",
"premium": true
])

// Set single attribute
Joryio.shared.setAttribute("language", value: "en")

// Increment numeric attribute
Joryio.shared.incrementAttribute("page_views", by: 1)
Joryio.shared.incrementAttribute("total_spent", by: 29.99)

// Remove attribute
Joryio.shared.unsetAttribute("temporary_flag")

Έλεγχοι απορρήτου

// Stop collecting. PERSISTED - survives an app restart.
Joryio.shared.optOut()

// Opt back in
Joryio.shared.optIn()

// Check opt-out status
if Joryio.shared.isUserOptedOut() {
print("User has opted out")
}

// Delete everything the SDK stored on this device.
// SEPARATE from optOut(): "stop collecting" and "delete what you have" are
// different requests. This is the one an erasure request needs. It does NOT
// opt the user out - call optOut() as well if that is also intended.
Joryio.shared.wipeData()

// Get identity info
let (userId, anonymousId) = Joryio.shared.getIdentity()
print("User: \(userId ?? "anonymous"), Anonymous ID: \(anonymousId)")

What optOut() does, precisely:

stops collectionyes - track, identify and setAttributes all become no-ops
survives a restartyes - the flag is stored on the device and read before anything is collected
drops what is already queuedyes - queued events and un-acked attribute writes are discarded, not delivered later
tells the serveryes - one final $tracking_opted_out profile attribute, best-effort, sent while sending is still permitted
deletes stored datano - use wipeData()

The $tracking_opted_out attribute is a record, not enforcement: it lands on the profile so campaigns can exclude on it. Server-side suppression is a separate setting.

σημείωση

Ενημερώθηκε στα Αγγλικά - μετάφραση σε εκκρεμότητα.

Μη αυτόματη αποστολή ουράς

// Flush immediately (e.g., before app termination)
Joryio.shared.flush()

// Check queue size
let queueSize = Joryio.shared.getQueueSize()
print("Pending events: \(queueSize)")

Βέλτιστες πρακτικές

1. Παρακολουθήστε ουσιαστικά συμβάντα

Εστιάστε σε συμβάντα που είναι σημαντικά για την επιχείρησή σας:

// Good: Specific, actionable events
Joryio.shared.track("Trial Started", properties: ["plan": "premium"])
Joryio.shared.track("Feature Used", properties: ["feature": "export"])

// Avoid: Overly generic events
Joryio.shared.track("Button Tapped") // Too generic

2. Χειριστείτε τον κύκλο ζωής χρήστη

// On login
func handleLogin(userId: String, userInfo: UserInfo) {
Joryio.shared.identify(userId)
Joryio.shared.setAttributes([
"email": userInfo.email,
"name": userInfo.name
])
}

// On logout
func handleLogout() {
Joryio.shared.reset()
}

// On signup
func handleSignup(userId: String, userInfo: UserInfo) {
Joryio.shared.alias(userId)
Joryio.shared.identify(userId)
Joryio.shared.setAttributes(userInfo.attributes)
}

3. Αποστολή σε κρίσιμα συμβάντα

override func applicationWillTerminate(_ application: UIApplication) {
Joryio.shared.flush()
}

Αντιμετώπιση προβλημάτων

Τα συμβάντα δεν εμφανίζονται

  1. Ελέγξτε ότι το κλειδί SDK είναι σωστό: jry_sdk_ios_*
  2. Ενεργοποιήστε debug logging: enableDebug: true
  3. Ελέγξτε τα logs της κονσόλας για σφάλματα
  4. Επαληθεύστε τη συνδεσιμότητα δικτύου
  5. Καλέστε flush() για άμεση αποστολή

Το push δεν λειτουργεί

  1. Επαληθεύστε ότι το πιστοποιητικό APNS έχει μεταφορτωθεί στο dashboard
  2. Ελέγξτε ότι το device token έχει καταχωριστεί
  3. Βεβαιωθείτε για τα σωστά entitlements στο Xcode
  4. Δοκιμάστε στο σωστό περιβάλλον (development ή production)

Σφάλματα build

  1. Βεβαιωθείτε για target ανάπτυξης iOS 14.0+
  2. Εκκαθαρίστε τον φάκελο build: Cmd+Shift+K
  3. Ενημερώστε τις εξαρτήσεις Swift Package

Παρακολούθηση E-Commerce

Το iOS SDK περιλαμβάνει ενσωματωμένο e-commerce tracker για συμβάντα προϊόντων, καλαθιού, checkout και παραγγελιών. Δείτε τον δια-SDK οδηγό E-Commerce Tracking για το πλήρες API με παραδείγματα Swift.

Επόμενα βήματα

Attribute delivery

setAttributes is durable. A write is queued until the server acknowledges it, so an attribute set while the device is offline is delivered when connectivity returns rather than dropped.

  • Retried on the next setAttributes, on foreground, and before an in-app sync.
  • Batched - a burst of calls becomes one request (800ms window). A single write still goes out promptly.
  • Persisted in the platform's encrypted store (iOS Keychain, Android EncryptedSharedPreferences), so a write survives the process being killed. Cleared the moment the server acks, and purged by optOut() and wipeData().

Attributes are also used for in-app targeting. The server profile is authoritative: only writes the server has not yet acknowledged can override it, which is what keeps two devices belonging to the same contact from disagreeing about who that contact is.

σημείωση

Ενημερώθηκε στα Αγγλικά - μετάφραση σε εκκρεμότητα.

The SDK registers for remote notifications whether or not the user grants the notification permission. On iOS the two are separate: registering yields a device token without consent, and that token can only ever deliver background (silent) pushes - it cannot display anything the user has not authorised.

This is what lets an in-app message reach a user who declined notifications, and it means a token already exists if they later enable notifications in Settings. Airship and OneSignal behave the same way. Disclose it in your privacy policy.

In-App Messaging

Display targeted in-app messages to users based on their behavior and attributes.

σημείωση

Ενημερώθηκε στα Αγγλικά - μετάφραση σε εκκρεμότητα.