Home Blog

ios – xcode run kotlin multiplatform mission can’t set up iosApp on IPhone16


Xcode run kotlin multiplatform mission to put in iosApp on IPhone16, tips on how to mounted it ?

I had obtain a clean kmp mission , and put in efficiently on IPhone16. After putting in the iOS app on an actual machine (iPhone 15), it was instantly uninstalled. Xcode reported the error proven within the screenshot.

and it may be archived to AppStore.

enter image description here

无法安装“KotlinAppProject”
Area: IXUserPresentableErrorDomain
Code: 1
Restoration Suggestion: Software is lacking the application-identifier entitlement.
Person Data: {
    DVTErrorCreationDateKey = "2025-08-03 11:32:01 +0000";
    IDERunOperationFailingWorker = IDEInstallCoreDeviceWorker;
}
--
Failed to put in the app on the machine.
Area: com.apple.dt.CoreDeviceError
Code: 3002
Person Data: {
    NSURL = "file:///Customers/HOX4SGH/Library/Developer/Xcode/DerivedData/iosApp-gbaojemzkfyvhrbgladtchqcvlfq/Construct/Merchandise/Debug-iphoneos/KotlinAppProject.app";
}
--
无法安装“KotlinAppProject”
Area: IXUserPresentableErrorDomain
Code: 1
Failure Cause: 请稍后再试。
Restoration Suggestion: Software is lacking the application-identifier entitlement.
--
Software is lacking the application-identifier entitlement.
Area: MIInstallerErrorDomain
Code: 63
Person Data: {
    FunctionName = "-[MIInstallableBundle _validateApplicationIdentifierForNewBundleSigningInfo:error:]";
    LegacyErrorString = ApplicationVerificationFailed;
    SourceFileLine = 1130;
}
--

Occasion Metadata: com.apple.dt.IDERunOperationWorkerFinished : {
    "device_identifier" = "00008140-000435313CF2801C";
    "device_isCoreDevice" = 1;
    "device_model" = "iPhone17,3";
    "device_osBuild" = "18.5 (22F76)";
    "device_platform" = "com.apple.platform.iphoneos";
    "device_thinningType" = "iPhone17,3";
    "dvt_coredevice_version" = "443.24";
    "dvt_coresimulator_version" = "1010.15";
    "dvt_mobiledevice_version" = "1784.120.3";
    "launchSession_schemeCommand" = Run;
    "launchSession_state" = 1;
    "launchSession_targetArch" = arm64;
    "operation_duration_ms" = 5069;
    "operation_errorCode" = 1;
    "operation_errorDomain" = IXUserPresentableErrorDomain;
    "operation_errorWorker" = IDEInstallCoreDeviceWorker;
    "operation_name" = IDERunOperationWorkerGroup;
    "param_debugger_attachToExtensions" = 0;
    "param_debugger_attachToXPC" = 1;
    "param_debugger_type" = 3;
    "param_destination_isProxy" = 0;
    "param_destination_platform" = "com.apple.platform.iphoneos";
    "param_diag_113575882_enable" = 0;
    "param_diag_MainThreadChecker_stopOnIssue" = 0;
    "param_diag_MallocStackLogging_enableDuringAttach" = 0;
    "param_diag_MallocStackLogging_enableForXPC" = 1;
    "param_diag_allowLocationSimulation" = 1;
    "param_diag_checker_tpc_enable" = 1;
    "param_diag_gpu_frameCapture_enable" = 0;
    "param_diag_gpu_shaderValidation_enable" = 0;
    "param_diag_gpu_validation_enable" = 0;
    "param_diag_guardMalloc_enable" = 0;
    "param_diag_memoryGraphOnResourceException" = 0;
    "param_diag_mtc_enable" = 1;
    "param_diag_queueDebugging_enable" = 1;
    "param_diag_runtimeProfile_generate" = 0;
    "param_diag_sanitizer_asan_enable" = 0;
    "param_diag_sanitizer_tsan_enable" = 0;
    "param_diag_sanitizer_tsan_stopOnIssue" = 0;
    "param_diag_sanitizer_ubsan_enable" = 0;
    "param_diag_sanitizer_ubsan_stopOnIssue" = 0;
    "param_diag_showNonLocalizedStrings" = 0;
    "param_diag_viewDebugging_enabled" = 1;
    "param_diag_viewDebugging_insertDylibOnLaunch" = 1;
    "param_install_style" = 2;
    "param_launcher_UID" = 2;
    "param_launcher_allowDeviceSensorReplayData" = 0;
    "param_launcher_kind" = 0;
    "param_launcher_style" = 99;
    "param_launcher_substyle" = 0;
    "param_runnable_appExtensionHostRunMode" = 0;
    "param_runnable_productType" = "com.apple.product-type.software";
    "param_structuredConsoleMode" = 1;
    "param_testing_launchedForTesting" = 0;
    "param_testing_suppressSimulatorApp" = 0;
    "param_testing_usingCLI" = 0;
    "sdk_canonicalName" = "iphoneos18.5";
    "sdk_osVersion" = "18.5";
    "sdk_variant" = iphoneos;
}
--


System Data

macOS Model 15.5 (Construct 24F74)
Xcode 16.4 (23792) (Construct 16F6)
Timestamp: 2025-08-03T19:32:01+08:00

Flutter iOS app UI proven on startup earlier than splash


I’m constructing an app for ios/android utilizing flutter. When the app begins, the move is:

important.dart
native splash displaying dev emblem (throughout which app begin up occurs)
authgate
app widget (extracted this from important to cut back how a lot work important was doing)
flutter splash displaying app emblem (throughout which permissions are referred to as)
touchdown display screen

The problem I’m seeing is when the iOS app begins, it briefly flashes the final seen UI display screen BEFORE the native splash display screen. e.g. If I used to be viewing the settings display screen within the app then stop the app, subsequent time I begin the app, the very first thing I see earlier than the native splash display screen is a flash of the settings display screen.

I simply wished to know if anybody has skilled that earlier than, and the way they resolved it.

I’ve googled for hours and can’t discover something related, nor can I discover something in flutter documentation. It appears I’ve managed to do one thing in begin up that created this challenge that nobody else will get? It’s driving me insane. On condition that this happens previous to native splash, I assume it’s a snapshot specific to iOS because it doesn’t occur within the android app, and whereas it’s not a breaking challenge, it doesn’t look nice from a consumer perspective.

I’ve tried including a white background to cover snapshot, as an alternative I received native splash then white display screen then native splash once more so eliminated the white background.
Added UIApplication.shared.ignoreSnapshotOnNextApplicationLaunch() to AppDelegate with no change in behaviour

1. Most important.dart

Future important() async {
  WidgetsFlutterBinding.ensureInitialized();
  tz.initializeTimeZones();
  await Future.delayed(const Period(seconds: 2));

  await Firebase.initializeApp(choices: DefaultFirebaseOptions.currentPlatform);
  await SystemChrome.setPreferredOrientations([
    DeviceOrientation.portraitUp,
  ]);

  await Hive.initFlutter();
  Hive.registerAdapter(MedicationAdapter());  // TypeID 0
  Hive.registerAdapter(DoseEntryAdapter()); // TypeID 1
  Hive.registerAdapter(HealthProfessionalAdapter()); // TypeID 2
  Hive.registerAdapter(DiscussionItemAdapter()); // TypeID 3
  Hive.registerAdapter(AppointmentAdapter()); // TypeID 4
  Hive.registerAdapter(UserProfileAdapter()); // TypeID 5
  Hive.registerAdapter(TodoItemAdapter()); // TypeID 7
  Hive.registerAdapter(DiaryEntryAdapter()); // TypeID 8
  Hive.registerAdapter(SelectedTrackersAdapter()); // TypeID 11
  Hive.registerAdapter(SelectedGoalsAdapter()); // TypeID 70
  Hive.registerAdapter(GpsActivityEntryAdapter()); // TypeID 60
  Hive.registerAdapter(WeightEntryAdapter()); // TypeID 50
  Hive.registerAdapter(WeightGoalAdapter()); // TypeID 31
  Hive.registerAdapter(ActivityGoalAdapter()); // TypeID 28
  Hive.registerAdapter(DailyGoalProgressAdapter()); // TypeID 33
  Hive.registerAdapter(WeeklyWeightEntryAdapter()); // TypeID 32
  Hive.registerAdapter(MenstrualCycleEntryAdapter()); // TypeID 43
  Hive.registerAdapter(WorkoutActivityAdapter()); // TypeID 41
  Hive.registerAdapter(MeditationGoalAdapter()); // TypeID 98
  Hive.registerAdapter(DailyMeditationProgressAdapter()); // TypeID 97

  await Hive.openBox('settings');
  await Hive.openBox('medicationAlertsSent');
  await Hive.openBox('menstrualCycleBox');
  await Hive.openBox('gps_activities');
  await Hive.openBox('gpsActivity');

  await NotificationService.initialize();
  await LocalisationSettingsService.init();

  // Load saved locale
  last savedLocaleCode = LocalisationSettingsService.getSelectedLocale();
  last initialLocale = savedLocaleCode != null ? Locale(savedLocaleCode) : null;

  runApp(
    MultiProvider(
      suppliers: [
        ChangeNotifierProvider(create: (_) => ThemeNotifier()),
        ChangeNotifierProvider(create: (_) => LocaleNotifier()..setLocale(initialLocale)),
      ],
      youngster: const MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  const MyApp({tremendous.key});

  @override
  Widget construct(BuildContext context) {
    last themeNotifier = Supplier.of(context);
    last localeNotifier = Supplier.of(context);

    return MaterialApp(
        title: 'Pebbl',
        navigatorKey: navigatorKey,
        theme: AppTheme.lightTheme,
        darkTheme: AppTheme.darkTheme,
        themeMode: themeNotifier.themeMode,
        debugShowCheckedModeBanner: false,
        residence: const NativeSplashWrapper(),
        locale: localeNotifier.locale,
        localizationsDelegates: const [
          AppLocalizations.delegate,
          GlobalMaterialLocalizations.delegate,
          GlobalCupertinoLocalizations.delegate,
          GlobalWidgetsLocalizations.delegate,
        ],
        supportedLocales: AppLocalizations.supportedLocales,
        localeResolutionCallback: (locale, supportedLocales) {
          for (var supportedLocale in supportedLocales) {
            if (supportedLocale.languageCode == locale?.languageCode &&
                supportedLocale.countryCode == locale?.countryCode) {
              return supportedLocale;
            }
          }
          return const Locale('en', 'GB');
        }
    );
  }
}

2.  Native splash wrapper

import 'package deal:flutter/materials.dart';
import 'package deal:pebbl/screens/login/auth_gate.dart'; // ✅ Now this works

class NativeSplashWrapper extends StatefulWidget {
  const NativeSplashWrapper({tremendous.key});

  @override
  State createState() => _NativeSplashWrapperState();
}

class _NativeSplashWrapperState extends State {
  bool _ready = false;

  @override
  void initState() {
    tremendous.initState();
    _init();
  }

  Future _init() async {
    await Future.delayed(const Period(milliseconds: 100));
    if (mounted) {
      setState(() {
        _ready = true;
      });
    }
  }

  @override
  Widget construct(BuildContext context) {
    if (!_ready) {
      return const Scaffold(
        backgroundColor: Coloration(0xFFF5F5F5),
        physique: Middle(
          youngster: Picture(
            picture: AssetImage('belongings/photographs/pebbl_logo.png'),
            width: 200,
            top: 200,
          ),
        ),
      );
    }
    return const AuthGate();
  }
}
3. Pubspec.yaml (snippet for flutter native splash)

flutter_native_splash:
  colour: "#F5F5F5"
  picture: belongings/photographs/dev_logo.png
  fullscreen: true
  android: true
  ios: true

  android_12:
    picture: belongings/photographs/android12_dev_logo.png
4. Auth gate

import 'package deal:flutter/materials.dart';
import 'package deal:firebase_auth/firebase_auth.dart';
import 'package deal:pebbl/screens/login/splash_screen.dart';
import 'package deal:pebbl/screens/login/login_screen.dart';
import 'package deal:pebbl/widgets/pebbl_app.dart'; // We’ll extract PebblApp too (see beneath)

class AuthGate extends StatelessWidget {
  const AuthGate({tremendous.key});

  @override
  Widget construct(BuildContext context) {
    return StreamBuilder(
      stream: FirebaseAuth.occasion.authStateChanges(),
      builder: (context, authSnapshot) {
        last isLoggedIn = authSnapshot.hasData;
        last display screen = isLoggedIn ? SplashScreen() : const LoginScreen();
        return PebblApp(initialScreen: display screen);
      },
    );
  }
}
5. Pebbl app widget

import 'package deal:flutter/materials.dart';
import 'package deal:pebbl/screens/touchdown/landing_screen.dart';
import 'package deal:pebbl/companies/notification_service.dart';
import 'package deal:pebbl/utils/logger.dart';
import 'package deal:pebbl/important.dart'; // for navigatorKey

class PebblApp extends StatefulWidget {
  last Widget initialScreen;

  const PebblApp({tremendous.key, required this.initialScreen});

  @override
  State createState() => _PebblAppState();
}

class _PebblAppState extends State with WidgetsBindingObserver {
  @override
  void initState() {
    tremendous.initState();
    WidgetsBinding.occasion.addObserver(this);
  }

  @override
  void dispose() {
    WidgetsBinding.occasion.removeObserver(this);
    tremendous.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.resumed) {
      last payload = NotificationService.getAndClearPendingPayload();
      if (payload != null) {
        Logger.log('App resumed. Routing to payload: $payload');
        navigatorKey.currentState?.pushAndRemoveUntil(
          MaterialPageRoute(builder: (_) => LandingScreen(payload: payload)),
              (route) => false,
        );
      }
    }
  }

  @override
  Widget construct(BuildContext context) {
    return GestureDetector(
      onTap: () => FocusScope.of(context).unfocus(),
      youngster: widget.initialScreen,
    );
  }
}
6. Splash display screen

import 'package deal:flutter/basis.dart';
import 'package deal:pebbl/utils/logger.dart';
import 'dart:io';
import 'package deal:device_info_plus/device_info_plus.dart';
import 'package deal:flutter/materials.dart';
import 'package deal:firebase_auth/firebase_auth.dart';
import 'package deal:package_info_plus/package_info_plus.dart';
import 'package deal:pebbl/screens/touchdown/landing_screen.dart';
import 'package deal:pebbl/screens/login/login_screen.dart';
import 'package deal:permission_handler/permission_handler.dart';
import 'package deal:pebbl/companies/notification_service.dart';
import 'package deal:geolocator/geolocator.dart';

class SplashScreen extends StatefulWidget {
  last String? payloadOverride;

  const SplashScreen({tremendous.key, this.payloadOverride});

  @override
  State createState() => _SplashScreenState();
}

class _SplashScreenState extends State with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation _animation;
  String _version = '';

  @override
  void initState() {
    tremendous.initState();
    _controller = AnimationController(
      period: const Period(seconds: 2),
      vsync: this,
    )..ahead();

    _animation = CurvedAnimation(
      mother or father: _controller,
      curve: Curves.easeInOut,
    );

    _init();
  }

  Future _init() async {
    strive {
      last data = await PackageInfo.fromPlatform();
      setState(() {
        _version = 'v${data.model}+${data.buildNumber}';
      });
      if (kDebugMode) {
        Logger.log('✅ Bundle data loaded');
      }
    } catch (e) {
      if (kDebugMode) {
        Logger.log('❌ Bundle data failed: $e');
      }
      _version = 'v1.0.0';
    }

    // 🔒 iOS location permission verify
    strive {
      if (Platform.isIOS) {
        last serviceEnabled = await Geolocator.isLocationServiceEnabled();
        if (kDebugMode) {
          Logger.log('✅ [iOS] Location service enabled: $serviceEnabled');
        }
        if (serviceEnabled) {
          var permission = await Geolocator.checkPermission();
          if (kDebugMode) {
            Logger.log('✅ [iOS] Location permission standing: $permission');
          }
          if (permission == LocationPermission.denied) {
            permission = await Geolocator.requestPermission();
            if (kDebugMode) {
              Logger.log('✅ [iOS] Location permission requested: $permission');
            }
          }
        }
      }
    } catch (e) {
      if (kDebugMode) {
        Logger.log('iOS Location permission request failed: $e');
      }
    }

    // ✅ Android 13+ notification permission
    strive {
      if (Platform.isAndroid) {
        last androidInfo = await DeviceInfoPlugin().androidInfo;
        if (kDebugMode) {
          Logger.log('✅ Android SDK: ${androidInfo.model.sdkInt}');
        }
        if (androidInfo.model.sdkInt >= 33) {
          last standing = await Permission.notification.request();
          if (kDebugMode) {
            Logger.log('✅ Notification permission: $standing');
          }
          if (!standing.isGranted) {
            if (kDebugMode) {
              Logger.log('Notification permission denied');
            }
            // Optionally present a dialog right here
          }
        }
      }
    } catch (e) {
      if (kDebugMode) {
        Logger.log('Notification permission request failed: $e');
      }
    }

    // ✅ Android location permissions: foreground and background
    strive {
      if (Platform.isAndroid) {
        // ✅ 1. Test and request notification permission (Android 13+)
        last notifStatus = await Permission.notification.standing;
        if (!notifStatus.isGranted) {
          if (kDebugMode) {
            Logger.log('🔔 Requesting notification permission...');
          }
          last notifResult = await Permission.notification.request();
          if (kDebugMode) {
            Logger.log('🔔 Notification permission outcome: $notifResult');
          }
        }

        // ✅ 2. Test foreground location permission
        if (kDebugMode) {
          Logger.log('📍 Checking foreground location permission...');
        }
        var fgStatus = await Permission.location.standing;
        if (kDebugMode) {
          Logger.log('📍 Foreground location permission standing: $fgStatus');
        }

        if (!fgStatus.isGranted) {
          if (kDebugMode) {
            Logger.log('📍 Requesting foreground location permission...');
          }
          fgStatus = await Permission.location.request();
          if (kDebugMode) {
            Logger.log('📍 Foreground location permission outcome: $fgStatus');
          }
        }

        // ✅ 3. Test background location permission (if foreground granted)
        if (fgStatus.isGranted) {
          if (kDebugMode) {
            Logger.log('📍 Checking background location permission...');
          }
          var bgStatus = await Permission.locationAlways.standing;
          if (kDebugMode) {
            Logger.log('📍 Background location permission standing: $bgStatus');
          }

          if (!bgStatus.isGranted) {
            if (kDebugMode) {
              Logger.log('📍 Requesting background location permission...');
            }
            bgStatus = await Permission.locationAlways.request();
            if (kDebugMode) {
              Logger.log('📍 Background location permission outcome: $bgStatus');
            }
          } else {
            if (kDebugMode) {
              Logger.log('✅ Background location permission already granted');
            }
          }
        } else {
          if (kDebugMode) {
            Logger.log('❌ Foreground location denied, skipping background request');
          }
        }
      }
    } catch (e) {
      if (kDebugMode) {
        Logger.log('❗ Permission request failed: $e');
      }
    }


    await Future.delayed(const Period(seconds: 2));
    if (!mounted) return;

    last consumer = FirebaseAuth.occasion.currentUser;
    if (kDebugMode) {
      Logger.log('SplashScreen: currentUser = ${consumer?.uid}');
    }
    last payload = widget.payloadOverride ??
        NotificationService.getInitialPayload() ??
        NotificationService.consumePendingPayload();
    if (kDebugMode) {
      Logger.log('SplashScreen init: Firebase consumer: ${consumer?.uid}, payload: $payload');
    }
    if (kDebugMode) {
      Logger.log('SplashScreen: payload resolved = $payload');
    }

    if (consumer != null) {
      strive {
        if (kDebugMode) {
          Logger.log('Calling rescheduleAllReminders...');
        }
        await NotificationService.rescheduleAllReminders()
            .timeout(const Period(seconds: 5));
        if (kDebugMode) {
          Logger.log('rescheduleAllReminders accomplished');
        }
      } catch (e) {
        if (kDebugMode) {
          Logger.log('rescheduleAllReminders failed or timed out: $e');
        }
      }
    }

    if (!mounted) return;

    Navigator.of(context).pushReplacement(
      MaterialPageRoute(
        builder: (_) => consumer == null
            ? const LoginScreen()
            : LandingScreen(payload: payload),
      ),
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    tremendous.dispose();
  }

  @override
  Widget construct(BuildContext context) {
    return Scaffold(
      backgroundColor: const Coloration(0xFFF5F5F5),
      physique: Column(
        mainAxisAlignment: MainAxisAlignment.heart,
        youngsters: [
          const Spacer(),
          FadeTransition(
            opacity: _animation,
            child: Center(
              child: Image.asset(
                'assets/images/pebbl_logo.png',
                width: 200,
                height: 200,
              ),
            ),
          ),
          const Spacer(),
          Padding(
            padding: const EdgeInsets.only(bottom: 20),
            child: Text(
              _version,
              style: const TextStyle(color: Colors.black54),
            ),
          ),
        ],
      ),
    );
  }
}
AppDelegate

import UIKit
import Flutter
import UserNotifications
import AVFAudio
import GoogleMaps // 👈 Add this import for Maps

@important
@objc class AppDelegate: FlutterAppDelegate {
  //lazy var flutterEngine = FlutterEngine(identify: "my_engine")
  override func software(
    _ software: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {

    UIApplication.shared.ignoreSnapshotOnNextApplicationLaunch()

// Begin engine (plugins auto-register when the engine is hooked up to the view)
    //flutterEngine.run()
    // Arrange audio playback class
    do {
      strive AVAudioSession.sharedInstance().setCategory(
        .playback,
        mode: .default,
        choices: [.mixWithOthers]
      )
      strive AVAudioSession.sharedInstance().setActive(true)
    } catch {
      print("Didn't set audio session class.")
    }

    // ✅ Register Google Maps API key
    GMSServices.provideAPIKey("key") // 👈 Change along with your precise key

    // Guarantee notification faucets are delivered to Flutter
    UNUserNotificationCenter.present().delegate = self

    return tremendous.software(software, didFinishLaunchingWithOptions: launchOptions)

  func applicationWillResignActive(_ software: UIApplication) {
      // Add a white view over the window earlier than backgrounding
      let whiteView = UIView(body: window?.bounds ?? .zero)
      whiteView.backgroundColor = UIColor.white
      whiteView.tag = 999 // So we are able to take away it later
      window?.addSubview(whiteView)
  }

  func applicationDidBecomeActive(_ software: UIApplication) {
      // Take away the white view when app turns into energetic
      if let whiteView = window?.viewWithTag(999) {
          whiteView.removeFromSuperview()
      }
  }
  }
}
SceneDelegate

import UIKit
import Flutter

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
  var window: UIWindow?

  func scene(_ scene: UIScene,
             willConnectTo session: UISceneSession,
             choices connectionOptions: UIScene.ConnectionOptions) {

    guard let windowScene = (scene as? UIWindowScene) else { return }

    let window = UIWindow(windowScene: windowScene)

    //let appDelegate = UIApplication.shared.delegate as! AppDelegate
    //let flutterEngine = appDelegate.flutterEngine

    let flutterViewController = FlutterViewController()

    GeneratedPluginRegistrant.register(with: flutterViewController.engine)

    window.rootViewController = flutterViewController
    self.window = window
    window.makeKeyAndVisible()
  }
}

ios – Learn how to repair the gestureRecognizer over PDFKit breaking the paging within the new ios26 model?


I had mission going nice, the place i wanted to do stuff with pdfs, drawing on prime them and so on. Since apple is all closed sourced i wanted to turn out to be a bit hacky. In any case, i’ve an issue because the new ios 26 replace which breaks the behaviour. I simplified the code very a lot right into a demo mission, the place you possibly can rapidly see what’s mistaken.

When swiping left to go to the subsequent web page, it does change the web page and so on within the pdf Doc, however visually nothing occurs. I’m caught on the primary web page. I dont know what to do, tried plenty of issues, however nothing works. Anybody expert sufficient to assist me out?

import UIKit
import PDFKit
import SwiftUI

class PDFViewController: UIViewController {
    
    var pdfView: PDFView!
    var gestureHandler: GestureHandler!

    override func viewDidLoad() {
        tremendous.viewDidLoad()
        setupPDFView()
        setupGestureHandler()
        loadPDF()
    }
    
    personal func setupPDFView() {
        pdfView = PDFView(body: view.bounds)
        
        // Your actual configuration
        pdfView.autoScales = true
        pdfView.pageShadowsEnabled = false
        pdfView.backgroundColor = .white
        pdfView.displayMode = .singlePage
        
        view.addSubview(pdfView)
        
        // Setup constraints
        pdfView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            pdfView.topAnchor.constraint(equalTo: view.topAnchor),
            pdfView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            pdfView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            pdfView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
        ])
    }
  
  personal func setupGestureHandler() {
          gestureHandler = GestureHandler(pdfView: pdfView)
          gestureHandler.setupSwipeGestures(on: view)
      }
    
    personal func loadPDF() {
        if let path = Bundle.principal.path(forResource: "sonate12", ofType: "pdf"),
           let doc = PDFDocument(url: URL(fileURLWithPath: path)) {
            pdfView.doc = doc
        } else {
            print("Couldn't discover sonate12.pdf in bundle")
        }
    }
}


class GestureHandler {
    
    personal weak var pdfView: PDFView?
    
    init(pdfView: PDFView) {
        self.pdfView = pdfView
    }
    
    func setupSwipeGestures(on view: UIView) {
        // Left swipe - go to subsequent web page
        let leftSwipe = UISwipeGestureRecognizer(goal: self, motion: #selector(handleSwipe(_:)))
        leftSwipe.route = .left
        view.addGestureRecognizer(leftSwipe)
        
        // Proper swipe - go to earlier web page
        let rightSwipe = UISwipeGestureRecognizer(goal: self, motion: #selector(handleSwipe(_:)))
        rightSwipe.route = .proper
        view.addGestureRecognizer(rightSwipe)
    }
    
    @objc personal func handleSwipe(_ gesture: UISwipeGestureRecognizer) {
        guard let pdfView = pdfView,
              let doc = pdfView.doc,
              let currentPage = pdfView.currentPage else {
            print("🚫 No PDF view, doc, or present web page out there")
            return
        }
        
        let currentIndex = doc.index(for: currentPage)
        let totalPages = doc.pageCount
        
        print("📄 Present state: Web page (currentIndex + 1) of (totalPages)")
        print("👆 Swipe route: (gesture.route == .left ? "LEFT (subsequent)" : "RIGHT (earlier)")")
        
        swap gesture.route {
        case .left:
            // Subsequent web page
            guard currentIndex < doc.pageCount - 1 else {
                print("🚫 Already on final web page ((currentIndex + 1)), can not go ahead")
                return
            }
            
            let nextPage = doc.web page(at: currentIndex + 1)
            if let web page = nextPage {
                print("➡️ Going to web page (currentIndex + 2)")
                pdfView.go(to: web page)
              pdfView.setNeedsDisplay()
              pdfView.layoutIfNeeded()
                // Test if navigation truly labored
                DispatchQueue.principal.asyncAfter(deadline: .now() + 0.1) {
                    if let newCurrentPage = pdfView.currentPage {
                        let newIndex = doc.index(for: newCurrentPage)
                        print("✅ Navigation consequence: Now on web page (newIndex + 1)")
                        if newIndex == currentIndex {
                            print("⚠️ WARNING: Web page did not change visually!")
                        }
                    }
                }
            } else {
                print("🚫 Couldn't get subsequent web page object")
            }
            
        case .proper:
            // Earlier web page
            guard currentIndex > 0 else {
                print("🚫 Already on first web page (1), can not return")
                return
            }
            
            let previousPage = doc.web page(at: currentIndex - 1)
            if let web page = previousPage {
                print("⬅️ Going to web page (currentIndex)")
                pdfView.go(to: web page)
              pdfView.setNeedsDisplay()
              pdfView.layoutIfNeeded()
              let bounds = pdfView.bounds
              pdfView.bounds = CGRect(x: bounds.origin.x, y: bounds.origin.y, width: bounds.width + 0.01, peak: bounds.peak)
              pdfView.bounds = bounds

                
                // Test if navigation truly labored
                DispatchQueue.principal.asyncAfter(deadline: .now() + 0.1) {
                    if let newCurrentPage = pdfView.currentPage {
                        let newIndex = doc.index(for: newCurrentPage)
                        print("✅ Navigation consequence: Now on web page (newIndex + 1)")
                        if newIndex == currentIndex {
                            print("⚠️ WARNING: Web page did not change visually!")
                        }
                    }
                }
            } else {
                print("🚫 Couldn't get earlier web page object")
            }
            
        default:
            print("🤷‍♂️ Unknown swipe route")
            break
        }
    }
}


struct PDFViewerRepresentable: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> PDFViewController {
        return PDFViewController()
    }
    
    func updateUIViewController(_ uiViewController: PDFViewController, context: Context) {
        // No updates wanted
    }
}

You may take a look at the code right here as effectively: https://github.com/vallezw/swift-bug-ios26

goal c – iOS Dylib crashes when printed to testflight with CODESIGNING 2 Invalid Web page


It is a prolonged one. I’ve mainly compiled a Rust binary right into a dylib and packaged right into a .xcframework that incorporates per arch .frameworks. This hundreds accurately when run from Xcode into an actual iOS gadget. Nonetheless, when deployed to TestFlight the app crashes.

Here’s what is a bit completely different, the dylib just isn’t absolutely self-contained. It tries to succeed in in an use C features I’ve uncovered in my library code. Calling features which can be simply inside the dylib and simply return works tremendous, however the second it tries to name one of many uncovered features it crashes.

A full in-depth step-by-step of how I packaged the binaries might be present in my web site:

https://ospfranco.com/complete-guide-to-dylibs-in-ios-and-android

After I have a look at the TestFlight crash report there aren’t any symbols however the termination trigger by way of WatchDog is:

Termination Purpose: CODESIGNING 2 Invalid Web page

I’ve declared my features as such:

OBJC_EXTERN void ios_prepare_request(const char *url)
#outline EXPORT __attribute__((visibility("default"), used, retain))
 
extern "C" {
 
EXPORT void ios_prepare_request(const char *url) {
  NSString *urlString = [NSString stringWithUTF8String:url];
  request =
      [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];
}
 
}
 
// Perform used to stop optimization
void force_symbol_registration() {
  // Pressure these symbols to be included within the binary by referencing them
  risky void *ptrs[] = {(void *)ios_prepare_request,};
 
  // Stop compiler from optimizing away the array
  (void)ptrs;
}

And I load my framework as:

  opacity::force_symbol_registration();
 
  // NSBundle *dylib_bundle =
  //     [NSBundle bundleWithIdentifier:@"com.opacitylabs.sdk"];
  // NSString *dylib_path = [dylib_bundle pathForResource:@"sdk" ofType:@""];
 
  // // Load the dynamic library
  // void *deal with = dlopen([dylib_path UTF8String], RTLD_NOW | RTLD_GLOBAL);
  // if (!deal with) {
  //   NSString *errorMessage = [NSString stringWithUTF8String:dlerror()];
  //   *error =
  //       [NSError errorWithDomain:@"OpacitySDKDylibError"
  //                           code:1002
  //                       userInfo:@{NSLocalizedDescriptionKey :
  //                       errorMessage}];
  //   return -1; // or applicable error code
  // }
 
  // Be sure that the principle executable's symbols can be found
  dlopen(NULL, RTLD_NOW | RTLD_GLOBAL);
 
  NSBundle *frameworkBundle =
      [NSBundle bundleWithIdentifier:@"com.opacitylabs.sdk"];
  if (![frameworkBundle isLoaded]) {
    BOOL success = [frameworkBundle load];
    if (!success) {
      NSString *errorMessage = @"Did not load framework";
      *error =
          [NSError errorWithDomain:@"OpacitySDKDylibError"
                              code:1002
                          userInfo:@{NSLocalizedDescriptionKey : errorMessage}];
      return -1;
    }
  }
  • As you may see, I’ve additionally tried dlopen each work when run from Xcode however crash when deployed on testflight.
  • I’ve tried re-signing the xcframework/frameworks on a pre construct step but it surely would not work
  • As acknowledged, I can name the features contained in the dylib, however as soon as they attempt to name my uncovered code it crashes

Is that this achievable in any respect or only a limitation of the iOS sandbox?

ios – Flutter construct fails when operating flutter from distant machine


Replace:
I attempted to explicitly permit the script entry to the keychain. I additionally briefly tried to provide entry to all customers. Each did not change something

I am at present establishing my dev atmosphere for creating an app with flutter. I attempted to set it up in order that i can develop(code) on home windows whereas testing the app on IOS. The movement I am attempting to get working is as follows:

  • code on home windows
  • git commit -> git push
  • `ssh me@my-mac ‘run_flutter.sh’
  • app builds on my mac and begins on my iphone

I at present am capable of construct the app on my mac and it begins on my iphone when i construct straight from my mac, however once I run the very same script by way of ssh from my home windows machine, the construct fails at signing it appears.

When i run the construct with verbose, this will get outputted:

           CodeSign /Customers/me/initiatives/myapp/construct/ios/Debug-iphoneos/Runner.app/Runner.debug.dylib (in goal 'Runner' from undertaking 'Runner')
               cd /Customers/me/initiatives/myapp/ios

               Signing Identification:     "Apple Growth: Me and Myself (A7656WTX4N)"
               Provisioning Profile: "iOS Crew Provisioning Profile: *"
                                     (4647d7e2-7941-45d0-a979-74d3b34f531c)

               /usr/bin/codesign --force --sign 211CD423578576BD70699D85C6340647A7BC686D --timestamp=none --generate-entitlement-der /Customers/me/initiatives/myapp/construct/ios/Debug-iphoneos/Runner.app/Runner.debug.dylib
           /Customers/me/initiatives/myapp/construct/ios/Debug-iphoneos/Runner.app/Runner.debug.dylib: errSecInternalComponent
           Command CodeSign failed with a nonzero exit code


           End result bundle written to path:
                /var/folders/ld/zczp5nks4sv8yffcmxs4thf80000gn/T/flutter_tools.amI6MP/flutter_ios_build_temp_dirNWMU5p/temporary_xcresult_bundle


           ** BUILD FAILED **


           The next construct instructions failed:
                CodeSign /Customers/me/initiatives/myapp/construct/ios/Debug-iphoneos/Runner.app/Runner.debug.dylib (in goal 'Runner' from undertaking 'Runner')
                Constructing workspace Runner with scheme Runner and configuration Debug
           (2 failures)
[   +7 ms] Operating Xcode construct... (accomplished in 6,7s)
[        ] Xcode construct carried out.                                            6,7s
[   +2 ms] executing: /usr/bin/arch -arm64e xcrun xcresulttool get --legacy --path /var/folders/ld/zczp5nks4sv8yffcmxs4thf80000gn/T/flutter_tools.amI6MP/flutter_ios_build_temp_dirNWMU5p/temporary_xcresult_bundle --format json