iOS Platform Guide

This guide covers iOS-specific features, optimizations, and advanced configurations for social.plus UIKit. For basic installation, see our Installation Guide.
Prerequisites: iOS 12.0+, Xcode 12+, Swift 5.0+. Ensure you’ve completed the basic installation before following these advanced guides.

Advanced Installation Options

🔧 Custom Build Configurations

Configure UIKit for different build environments:
// AppDelegate.swift - Debug setup
#if DEBUG
AmityUIKitManager.setup(
    apiKey: "YOUR_DEBUG_API_KEY",
    region: .US,
    httpSettings: AmityHTTPSettings(
        enableLogging: true,
        logLevel: .verbose
    )
)
#endif

🎯 Performance Optimizations

Memory Management

// Implement proper memory management
class ChatViewController: UIViewController {
    private var amityViewController: AmityChatViewController?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupAmityChat()
    }
    
    private func setupAmityChat() {
        amityViewController = AmityChatViewController()
        addChild(amityViewController!)
        view.addSubview(amityViewController!.view)
        amityViewController!.didMove(toParent: self)
    }
    
    deinit {
        // Clean up resources
        amityViewController?.willMove(toParent: nil)
        amityViewController?.view.removeFromSuperview()
        amityViewController?.removeFromParent()
    }
}

Image Caching Configuration

// Configure image caching for better performance
AmityUIKitManager.configure { settings in
    settings.imageCacheSettings = AmityImageCacheSettings(
        memoryLimit: 50 * 1024 * 1024, // 50MB
        diskLimit: 200 * 1024 * 1024,   // 200MB
        diskAge: 60 * 60 * 24 * 7       // 1 week
    )
}

iOS-Specific Features

📱 Native iOS Integrations

Push Notifications

import UserNotifications

class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        
        // Setup UIKit
        AmityUIKitManager.setup(apiKey: "YOUR_API_KEY", region: .US)
        
        // Configure push notifications
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { granted, error in
            if granted {
                DispatchQueue.main.async {
                    application.registerForRemoteNotifications()
                }
            }
        }
        
        return true
    }
    
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        // Register device token with Amity
        AmityUIKitManager.registerDeviceToken(deviceToken)
    }
}

Background App Refresh

// Configure background refresh for real-time updates
func applicationDidEnterBackground(_ application: UIApplication) {
    AmityUIKitManager.enterBackground()
}

func applicationWillEnterForeground(_ application: UIApplication) {
    AmityUIKitManager.enterForeground()
}

Scene Delegate Support

// SceneDelegate.swift - iOS 13+ multi-window support
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?
    
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let windowScene = (scene as? UIWindowScene) else { return }
        
        window = UIWindow(windowScene: windowScene)
        
        // Setup UIKit for this scene
        let mainViewController = MainViewController()
        window?.rootViewController = UINavigationController(rootViewController: mainViewController)
        window?.makeKeyAndVisible()
    }
}

🎨 iOS Design System Integration

Dynamic Type Support

// Configure UIKit to support Dynamic Type
AmityUIKitManager.configure { settings in
    settings.accessibilitySettings = AmityAccessibilitySettings(
        supportDynamicType: true,
        minimumFontSize: 12.0,
        maximumFontSize: 24.0
    )
}

Dark Mode Support

// Automatic dark mode detection
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection)
    
    if traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) {
        // Update UIKit theme based on system appearance
        let isDarkMode = traitCollection.userInterfaceStyle == .dark
        AmityUIKitManager.setTheme(isDarkMode ? .dark : .light)
    }
}

Safe Area Handling

// Proper safe area integration
class ContainerViewController: UIViewController {
    private let amityViewController = AmityFeedViewController()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        addChild(amityViewController)
        view.addSubview(amityViewController.view)
        
        amityViewController.view.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            amityViewController.view.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            amityViewController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            amityViewController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            amityViewController.view.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
        ])
        
        amityViewController.didMove(toParent: self)
    }
}

Advanced Customization

🎭 Custom Theming

Brand Color Integration

// Custom color scheme
let customTheme = AmityTheme()
customTheme.primaryColor = UIColor(red: 0.2, green: 0.4, blue: 0.8, alpha: 1.0)
customTheme.secondaryColor = UIColor(red: 0.1, green: 0.2, blue: 0.4, alpha: 1.0)
customTheme.backgroundColor = UIColor.systemBackground
customTheme.textColor = UIColor.label

AmityUIKitManager.setCustomTheme(customTheme)

Typography Customization

// Custom fonts
let customTypography = AmityTypography()
customTypography.headingFont = UIFont(name: "YourCustomFont-Bold", size: 18) ?? UIFont.systemFont(ofSize: 18, weight: .bold)
customTypography.bodyFont = UIFont(name: "YourCustomFont-Regular", size: 16) ?? UIFont.systemFont(ofSize: 16)
customTypography.captionFont = UIFont(name: "YourCustomFont-Light", size: 14) ?? UIFont.systemFont(ofSize: 14, weight: .light)

AmityUIKitManager.setCustomTypography(customTypography)

🔧 Component Customization

Custom Navigation Bar

class CustomFeedViewController: AmityFeedViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Customize navigation bar
        navigationItem.title = "My Social Feed"
        navigationController?.navigationBar.prefersLargeTitles = true
        
        // Add custom buttons
        let profileButton = UIBarButtonItem(
            image: UIImage(systemName: "person.circle"),
            style: .plain,
            target: self,
            action: #selector(showProfile)
        )
        navigationItem.rightBarButtonItem = profileButton
    }
    
    @objc private func showProfile() {
        let profileVC = AmityUserProfileViewController()
        present(profileVC, animated: true)
    }
}

Custom Cell Layouts

// Register custom cell classes
class CustomizedFeedViewController: AmityFeedViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Register custom post cell
        registerCustomPostCell(CustomPostTableViewCell.self, forCellType: .text)
        registerCustomPostCell(CustomImagePostTableViewCell.self, forCellType: .image)
    }
}

class CustomPostTableViewCell: AmityPostTableViewCell {
    override func setupCustomLayout() {
        super.setupCustomLayout()
        
        // Add custom UI elements
        contentView.backgroundColor = UIColor.systemGray6
        contentView.layer.cornerRadius = 12
        contentView.layer.masksToBounds = true
    }
}

Debugging & Troubleshooting

🐛 Common iOS Issues

📊 Performance Monitoring

// Monitor UIKit performance
class PerformanceMonitor {
    static func trackComponentLoad(componentName: String) {
        let startTime = CFAbsoluteTimeGetCurrent()
        
        // Component loading logic
        
        let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
        print("Component \(componentName) loaded in \(timeElapsed) seconds")
    }
}

// Usage
PerformanceMonitor.trackComponentLoad(componentName: "AmityFeedViewController")

Production Deployment

🚀 App Store Preparation

Info.plist Configuration

<!-- Required permissions -->
<key>NSCameraUsageDescription</key>
<string>This app uses camera to capture photos for posts and profile pictures</string>

<key>NSPhotoLibraryUsageDescription</key>
<string>This app accesses photo library to select images for posts</string>

<key>NSMicrophoneUsageDescription</key>
<string>This app uses microphone for voice messages and video calls</string>

Build Configuration

// Production-ready configuration
#if !DEBUG
AmityUIKitManager.setup(
    apiKey: "PRODUCTION_API_KEY",
    region: .US,
    httpSettings: AmityHTTPSettings(
        enableLogging: false,
        logLevel: .error,
        enableCrashReporting: true
    )
)
#endif

📈 Analytics Integration

// Custom analytics tracking
extension AmityUIKitManager {
    static func trackUserAction(_ action: String, parameters: [String: Any] = [:]) {
        // Your analytics service integration
        Analytics.track(action, properties: parameters)
    }
}

// Usage in custom view controllers
class AnalyticsEnabledFeedViewController: AmityFeedViewController {
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        AmityUIKitManager.trackUserAction("feed_viewed")
    }
}

Resources & Best Practices

// MVVM pattern with UIKit
class FeedViewModel: ObservableObject {
    @Published var posts: [AmityPost] = []
    private let amityDataSource = AmityFeedDataSource()
    
    func loadPosts() {
        amityDataSource.loadPosts { [weak self] posts in
            DispatchQueue.main.async {
                self?.posts = posts
            }
        }
    }
}

class FeedViewController: UIViewController {
    private let viewModel = FeedViewModel()
    private let amityFeedView = AmityFeedView()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupBindings()
        viewModel.loadPosts()
    }
    
    private func setupBindings() {
        viewModel.$posts.sink { [weak self] posts in
            self?.amityFeedView.updatePosts(posts)
        }.store(in: &cancellables)
    }
}

🔗 Additional Resources

Need Help? Join our iOS developers community for platform-specific discussions and support.