Repository: flutter
Issue: Could not find or use auto-linked framework 'Flutter' in Xcode extension target
Labels: platform-ios,tool,d: api docs,t: xcode,P2,team-ios,triaged-ios

Hi everyone!

Im trying to use a `Notification Service Extension `on iOS to show rich push notifications. Also i created a local notification plugin called [Awesome Notifications](https://pub.dev/packages/awesome_notifications) and im want to reuse this logic inside the Target extension.

Just for better comprehension, what im trying  to do is exactly what One Signal did for their plugin:
https://documentation.onesignal.com/docs/flutter-sdk-setup#step-3---add-an-ios-service-extension-ios-apps-only

When I created the app for the first time, without the target extension, and add the target extension later, everything compiles and runs ok on the real device. But, when the project is cleaned or I tried to compile with release mode, im starting to get compilation erros about some unknown Flutter symbols, such as:

![image](https://user-images.githubusercontent.com/40064496/167436087-9083818f-eeb8-4f42-a660-4994ab9c11ed.png)

What I realized was the Flutter engine wasn't compiled at the moment when the target extension is being built, because the main app depends on target extension, so the target extension must be built first. But the flutter library is only compiled on main app/target.

This way, these flutter symbols are not getting recognized on the target extension for cases where the project was cleaned and is being recreated from ground up (something that happens on each `pod install` or `flutter run --release`). But, if the app was already built once without the target extension, the compiler becomes able to find the flutter symbols from cached files, and it compiles the whole project successfully.

How do I correctly use my flutter plugin's native classes inside a target extension? There is a way to create a pod file modification to do that automatically for each build?

This is my pod.file:
```Pod
# Uncomment this line to define a global platform for your project
platform :ios, '10.0'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'

project 'Runner', {
  'Debug' => :debug,
  'Profile' => :release,
  'Release' => :release,
}

def flutter_root
  generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
  unless File.exist?(generated_xcode_build_settings_path)
    raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
  end

  File.foreach(generated_xcode_build_settings_path) do |line|
    matches = line.match(/FLUTTER_ROOT\=(.*)/)
    return matches[1].strip if matches
  end
  raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end

require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)

flutter_ios_podfile_setup

target 'Runner' do
  use_frameworks!
  use_modular_headers!

  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end

target 'AwesomeServiceExtension' do
  use_frameworks!
  use_modular_headers!

  flutter_install_ios_engine_pod File.dirname(File.realpath(__FILE__))
  pod 'awesome_notifications_fcm', :path => '.symlinks/plugins/awesome_notifications_fcm/ios'
  #flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['ENABLE_BITCODE'] = 'NO'
      if target.name.start_with? 'Awesome'
        config.build_settings['APPLICATION_EXTENSION_API_ONLY'] = 'NO'
      end
    end
    flutter_additional_ios_build_settings(target)
  end
end
```

## Steps to Reproduce

To make it compile successfully:
1. Run the app without target extensions
2. Add the notification service target extension
3. modify pod.file to include the plugin library into the new target extension:
```
target 'AwesomeServiceExtension' do
  use_frameworks!
  use_modular_headers!

  flutter_install_ios_engine_pod File.dirname(File.realpath(__FILE__))
  pod 'awesome_notifications_fcm', :path => '.symlinks/plugins/awesome_notifications_fcm/ios'
  #flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['ENABLE_BITCODE'] = 'NO'
      if target.name.start_with? 'Awesome'
        config.build_settings['APPLICATION_EXTENSION_API_ONLY'] = 'NO'
      end
    end
    flutter_additional_ios_build_settings(target)
  end
end
```
4. add the plugin import (this case 'awesome_notifications') inside the extension source code file: 
![image](https://user-images.githubusercontent.com/40064496/167435320-17f426e1-0708-499a-a2cc-7d53d0c1c210.png)

5. Rerun the app without clean it.


But, to make the errors appears:
1 . Redo the steps above without running the app previously, excluding the target extension (step 1)

## Logs

```terminal
Xcode's output:
↳
    Writing result bundle at path:
        /var/folders/6d/c48hfkfd7rnfnk8sc9gpc8km0000gn/T/flutter_tools.O0p66k/flutter_ios_build_temp_dirpFtrWY/temporary_xcresult_bundle

    ld: warning: Could not find or use auto-linked framework 'Flutter'
    Undefined symbols for architecture arm64:
      "_OBJC_CLASS_$_FlutterCallbackCache", referenced from:
          objc-class-ref in awesome_notifications(DartBackgroundExecutor.o)
          objc-class-ref in awesome_notifications_fcm(DartFcmBackgroundExecutor.o)
      "_OBJC_CLASS_$_FlutterEngine", referenced from:
          objc-class-ref in awesome_notifications(DartBackgroundExecutor.o)
          objc-class-ref in awesome_notifications_fcm(DartFcmBackgroundExecutor.o)
      "_OBJC_CLASS_$_FlutterMethodChannel", referenced from:
          objc-class-ref in awesome_notifications(SwiftAwesomeNotificationsPlugin.o)
          objc-class-ref in awesome_notifications(DartBackgroundExecutor.o)
          objc-class-ref in awesome_notifications_fcm(SwiftAwesomeNotificationsFcmPlugin.o)
          objc-class-ref in awesome_notifications_fcm(DartFcmBackgroundExecutor.o)
      "_OBJC_CLASS_$_FlutterStandardTypedData", referenced from:
          objc-class-ref in awesome_notifications(SwiftAwesomeNotificationsPlugin.o)
      "_OBJC_CLASS_$_FlutterError", referenced from:
          objc-class-ref in awesome_notifications(SwiftAwesomeNotificationsPlugin.o)
          objc-class-ref in awesome_notifications(DartBackgroundExecutor.o)
          objc-class-ref in awesome_notifications_fcm(SwiftAwesomeNotificationsFcmPlugin.o)
          objc-class-ref in awesome_notifications_fcm(DartFcmBackgroundExecutor.o)
    ld: symbol(s) not found for architecture arm64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    note: Using new build system
    note: Planning
    note: Build preparation complete
    note: Building targets in dependency order
    /Users/carda/Documents/GitHub/Plugins/awesome_notifications_fcm/example/ios/Pods/Pods.xcodeproj: warning: The iOS deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 15.4.99.
    (in target 'Toast' from project 'Pods')

    Result bundle written to path:
        /var/folders/6d/c48hfkfd7rnfnk8sc9gpc8km0000gn/T/flutter_tools.O0p66k/flutter_ios_build_temp_dirpFtrWY/temporary_xcresult_bundle


Could not build the precompiled application for the device.
Error (Xcode): Undefined symbol: _OBJC_CLASS_$_FlutterCallbackCache


Error (Xcode): Undefined symbol: _OBJC_CLASS_$_FlutterEngine


Error (Xcode): Undefined symbol: _OBJC_CLASS_$_FlutterMethodChannel


Error (Xcode): Undefined symbol: _OBJC_CLASS_$_FlutterStandardTypedData


Error (Xcode): Undefined symbol: _OBJC_CLASS_$_FlutterError



Error running application on iPhone de Rafael.
```

My flutter doctor:
```
[✓] Flutter (Channel stable, 2.10.5, on macOS 12.3.1 21E258 darwin-arm, locale en-BR)
    • Flutter version 2.10.5 at /Users/carda/Desenvolvimento/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 5464c5bac7 (3 weeks ago), 2022-04-18 09:55:37 -0700
    • Engine revision 57d3bac3dd
    • Dart version 2.16.2
    • DevTools version 2.9.2

[✓] Android toolchain - develop for Android devices (Android SDK version 32.0.0)
    • Android SDK at /Users/carda/Library/Android/sdk
    • Platform android-32, build-tools 32.0.0
    • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.11+0-b60-7772763)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 13.3.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • CocoaPods version 1.11.3

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2021.1)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.11+0-b60-7772763)

[✓] VS Code (version 1.66.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.40.0

[✓] Connected device (2 available)
    • iPhone de Rafael (mobile) • 00008020-000C05010C53802E • ios            • iOS 15.4.1 19E258
    • Chrome (web)              • chrome                    • web-javascript • Google Chrome 101.0.4951.54

[✓] HTTP Host Availability
    • All required HTTP hosts are available

• No issues found!
```

</details>