Importing a static library (Rust .a) to Flutter project in iOS - ios

I have followed the instructions from here and here
And although the .a library and the functions work as expected on Debug (simulator and real device), when I Archive and test through TestFlight the Flutter App begins with a grey background (which I read that it means some kind of error).
If I go ahead and remove all calls of the Rust lib then the Testflight opens normally.
Note: I have also added the .a library as a Linked framework from the XCode and I have included the .h file to the bridging-header.h of the project.
I have also
run flutter build --release
cleared the derived data
pods cache
even re-made the iOS folder
from scratch.
Is there something else that I'm missing here?

I managed to make it work by creating a Flutter plugin flutter create -t plugin then I imported the .a file on the /iOS folder and included all the rust functions on the .h file inside /iOS/Classes (these are automatically created).
Then add a sample function for each of the rust functions inside the .Swift file in /iOS/Classes
And make sure to include
flutter:
plugin:
pluginClass: ApproverRustPlugin
On your .yaml file of the plugin.
Also include these on the plugin .podspec file
s.public_header_files = 'Classes**/*.h'
s.source_files = 'Classes/**/*'
s.static_framework = true
s.vendored_libraries = "**/*.a"
Once all these are done. Make sure to include your plugin (assuming it exists on the same folder as the main App) on the main app .yaml file.
dependencies:
flutter:
sdk: flutter
approver_rust:
path: "./approver_rust"
For reference:
Pod::Spec.new do |s|
s.name = 'approver_rust'
s.version = '0.0.1'
s.summary = 'A new flutter plugin project.'
s.description = <<-DESC
A new flutter plugin project.
DESC
s.homepage = 'http://example.com'
s.license = { :file => '../LICENSE' }
s.author = { 'Your Company' => 'email#example.com' }
s.source = { :path => '.' }
s.public_header_files = 'Classes**/*.h'
s.source_files = 'Classes/**/*'
s.static_framework = true
s.vendored_libraries = "**/*.a"
s.dependency 'Flutter'
s.platform = :ios, '9.0'
# Flutter.framework does not contain a i386 slice.
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
s.swift_version = '5.0'
end

Related

What should be the Podspec file for using local .xcframework in React Native library?

I created a React Native library that is a wrapper for using the native iOS framework in the React Native Projects. Earlier I was using .framework & it was working fine. Now I am facing an issue in using this library with .xcframework instead of .framework.
I added this library as a dependency to the project & then on running pod install getting the below error:
[!] [Xcodeproj] Generated duplicate UUIDs:
When I opened the project & try to build it, it builds successfully for the device but fails on the simulator.
Below is the Podspec file that I am using in the library project:
Pod::Spec.new do |s|
s.name = "react-native-myLibrary"
s.version = "1.0.0"
s.summary = "react-native-myLibrary"
s.description = <<-DESC
react-native-myLibrary
DESC
s.homepage = "https://github.com/geektimecoil/react-native-onesignal"
s.license = "MIT"
s.author = { "author" => "author#domain.cn" }
s.platform = :ios, "10.0"
s.source = { :http => 'file:' + __dir__ + '/' }
s.source_files = "**/*.{h,m,swift}"
s.requires_arc = true
s.vendored_frameworks = 'MyLibrary.xcframework'
s.dependency "React"
end
On searching for the solution I found that this error is caused by s.source_files = "**/*.{h,m,swift}". So, I commented this line & run pod install again. The error was gone but no dependency is being added to the Project target. Can anyone provide me the Podspec file to use for local .xcframework in React Native Library. Thanks in advance!
I was able to fix this issue using:
s.source_files = "ios/*.{h,m,swift}"
s.vendored_frameworks = 'ios/Frameworks/MyLibrary.xcframework'
& also by updating the Framework Search Paths from the Build Settings to $(inherited).
Try this:
s.preserve_paths = 'MyFraemwork.xcframework/*'
s.source_files = 'MyFraemwork.xcframework/ios-arm64_armv7/PicUPSDKv3.framework/Headers/*.{h,m,swift}'

Using the framework from one target as a pod in another target locally

I'm having trouble using a framework I wrote in other targets (the same project) using modular imports. I'm using Cocoapods. I'm getting Could not build module: errors while trying to import the module using modular imports (#import CMPComapiFoundation;). I attach a link to the repo for more information.
I did try both local (:path =>) and remote (:git =>) ways of pulling the SDK in Podfile, none of which seems to work. It's worth noting that if added via Cocoapods in a separate project, the code compiles and the SDK can be imported.
SDK's .podspec file:
Pod::Spec.new do |s|
s.name = 'CMPComapiFoundation'
s.version = '1.2.2'
s.license = 'MIT'
s.summary = 'Foundation library for connecting to and consuming COMAPI services'
s.description = <<-DESC
# iOS SDK for Comapi
Client to connect your iOS application with [Comapi](http://comapi.com/) services and add it as a channel to our cloud messaging platform. Written in Objective-C.
For more information about the integration please visit [the website](http://docs.comapi.com/reference#one-sdk-ios).
DESC
s.homepage = 'https://github.com/comapi/comapi-sdk-ios-objc'
s.author = { 'Comapi' => 'support#comapi.com' }
s.source = { :git => 'https://github.com/comapi/comapi-sdk-ios-objc.git', :tag => s.version.to_s }
s.social_media_url = 'https://twitter.com/comapimessaging'
s.ios.deployment_target = '10.0'
s.requires_arc = true
s.source_files = 'Sources/**/*.{h,m}'
s.resources = []
s.dependency 'SocketRocket'
end
And here's the Podfile I'm using for the entire project:
platform :ios, '10.0'
use_frameworks!
def shared
pod 'CMPComapiFoundation', :path => '/Users/dominik.kowalski/Documents/comapi-sdk-ios-objc'
pod 'JWT'
end
target 'CMPComapiFoundation' do
pod 'SocketRocket'
end
target 'CMPComapiFoundationTests' do
shared
end
target 'ComapiFoundationSample' do
shared
end
target 'ComapiFoundationSample-Swift' do
shared
pod 'SnapKit'
end
I expect the test and sample targets to import the modules and compile the code.
Okay I managed to fix it myself. Some header files were missing Target membership, but Xcode gave me misleading hints.

Unable to add iOS dependency to Flutter plugin

I am creating a Flutter plugin. But when I am trying to add a dependency to iOS part of the plugin I am not finding any proper guideline for this. I declared the dependency in the podspec file of my plugin. But the dependency is only available in the example/ios through Pod but I want access that dependency in my ios folder of my plugin. This is my podspec:
#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html
#
Pod::Spec.new do |s|
s.name = 'comet_chat'
s.version = '0.0.1'
s.summary = 'A new Flutter plugin.'
s.description = <<-DESC
A new Flutter plugin.
DESC
s.homepage = 'http://example.com'
s.license = { :file => '../LICENSE' }
s.author = { 'Your Company' => 'email#example.com' }
s.source = { :path => '.' }
s.source_files = 'Classes/**/*'
s.public_header_files = 'Classes/**/*.h'
s.dependency 'Flutter'
s.dependency 'CometChatPro', '1.4.0'
s.ios.deployment_target = '10.0'
s.preserve_paths = 'CometChatPro.framework'
s.xcconfig = { 'OTHER_LDFLAGS' => '-framework CometChatPro' }
s.vendored_frameworks = 'CometChatPro.framework'
end
I followed this issue but it was of no help. How to solve this issue? How can I get my dependency only for the plugin?
There is no way to "only open the plugin's classes", and the dependencies you add in your podspec are only available to your plugin, unless explicitly made it public.
TL;DR
By design, your iOS Flutter plugin will always run when embedded in a Flutter application project. Also, there is a conflict in your podspec; it should never specify the same framework in both dependency and vendored_frameworks.
If you have a CometChatPro.framework folder, copy it in your plugin's ios/Libraries folder and declare its path in your podspec in vendored_frameworks. Personally, I've never used the dependency specifier but there is an example in the flutter-webrtc plugin's implementation.
Either way, the ios/Classes folder of your plugin does have access to the dependencies that you specify in your ios/plugin_name.podpsec file. It just doesn't "know it" when you edit your plugin in any editor other than Xcode (Visual Studio Code, Android Studio, etc).
To develop the Swift or Objective-C classes for your plugin's iOS implementation, you should :
Open the example's Xcode workspace located at example/ios/Runner.xcworkspace.
Edit your plugin's iOS classes by navigating in Xcode to Pods/Development Pods/plugin_name/../../ios/.symlinks/plugins/plugin_name/ios/Classes
Build your project to fix any compiling errors.
If at this point you still don't have access to the framework in your plugin's iOS classes, it means that it wasn't properly setup by Cocoapods. In that case, you'll need to find which Xcode Build Setting is not properly set and then specify these Build Settings in your plugin's podspec, like so:
s.xcconfig = {
'FRAMEWORK_SEARCH_PATHS' => ['${PODS_TARGET_SRCROOT}/Libraries'],
'HEADER_SEARCH_PATHS' => ["${PODS_ROOT}/../.symlinks/plugins/plugin_name/ios/Libraries/CometChatPro.framework/Headers"
}
This explicitly adds the framework to your plugin target's FRAMEWORK_SEARCH_PATHS, and the framework's Headers path to the HEADER_SEARCH_PATH.
When linking vendored_frameworks, you want to make sure that Cocoapods did successfully embed the framework, and that you are building for the right architectures.

Building a Cocoapod with Swift and dependency on Objective-C framework

I know there are already a few questions on this theme here on SO, but very few have accepted answers, and I don't think I have found the exact same problem as mine.
I'm building a Swift pod, and in my code I rely on the Google Maps iOS SDK, which is bundled as a .framework file. The project builds OK in Xcode, however I have troubles publishing the lib to Cocoapods.
I managed to have a Podspec file that almost validates using the pod lib lint command. However, now that I've added the Google-Maps-iOS-SDK pod as a dependency in the Podspec file, it fails with the following message:
$ pod lib lint
[!] The 'Pods' target has transitive dependencies that include static
binaries:
(/private/var/folders/n2/qyjfpk6n7zz_mngtwswlmsy00000gn/T/CocoaPods/Lint/Pods/Google-Maps-iOS-SDK/GoogleMaps.framework)
$
Is this expected? Why can't I add the Google Maps iOS SDK as a pod reference in my own Swift-based pod?
Here's the Podspec:
Pod::Spec.new do |s|
s.name = '(name)'
s.version = '1.0.0'
s.summary = '(summary)'
s.platforms = { :ios => '8.0', :osx => '10.10' }
s.ios.deployment_target = '8.0'
s.osx.deployment_target = '10.10'
s.license = { :type => 'BSD', :file => 'LICENSE' }
s.source_files = 'Sources/*.{h,swift}', '*.framework'
s.source = { :git => "https://github.com/(Github repo).git", :tag => "1.0.0" }
s.requires_arc = true
s.frameworks = "Foundation", "CoreLocation"
s.author = { 'Romain L' => '(email)' }
s.dependency 'Google-Maps-iOS-SDK'
end
If I don't include the Google Maps iOS SDK as a dependency, then pod lib lint fails in the Bridging Header, and complains it cannot find <GoogleMaps/GoogleMaps.h> (file not found).
I'm stuck, and I don't know if it's a bug from Cocoapods 0.36 (still in Beta) or if I'm doing something wrong.
Thanks for your help!
I finally found another thread on SO dealing with similar problems: Linker errors in a Swift project with Google Maps for iOS added via CocoaPods.
It appears that the errors were due to a combination of bad Podspec file (on the Google Maps iOS SDK side), and bugs in Cocoapods 0.36 Beta.
It's actually possible to workaround the issues by using #fz.'s revised Podspec file for Google Maps: https://stackoverflow.com/a/28471830/145997. Another article that also was of great interest to understand how the vendored_frameworks setting works in Podspec is: http://codereaper.com/blog/2014/creating-a-pod-with-crashreporter/.
So, to correctly import the Google Maps iOS SDK in a Pod project, first use the following Podfile:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
# altered version of Google's Podspec
pod 'Google-Maps-iOS-SDK', :podspec => "https://raw.githubusercontent.com/Reflejo/GoogleMapsPodspec/master/Google-Maps-iOS-SDK.podspec.json"
use_frameworks! # don't forget this!
I'm now able to reference Google Maps classes from my Swift code simply by doing import GoogleMaps. And, to distribute the Pod, my final Podspec now resembles the following:
Pod::Spec.new do |s|
s.name = 'MyPod'
s.version = '1.0.0'
s.homepage = "https://github.com/..."
s.summary = '(pod summary)'
#s.screenshot = ""
s.author = { 'Romain L' => '(email)' }
s.license = { :type => 'BSD', :file => 'LICENSE' }
s.social_media_url = "https://twitter.com/_RomainL"
s.platforms = { :ios => '8.0' }
s.ios.deployment_target = '8.0'
s.source_files = 'MyCode/*.{h,swift}'
s.module_name = 'MyPod'
s.source = { :git => "https://github.com/....git", :tag => "1.0.0" }
s.requires_arc = true
s.libraries = "c++", "icucore", "z" # required for GoogleMaps.framework
s.frameworks = "AVFoundation", "CoreData", "CoreLocation", "CoreText", "Foundation", "GLKit", "ImageIO", "OpenGLES", "QuartzCore", "SystemConfiguration", "GoogleMaps" # required for GoogleMaps.framework
s.vendored_frameworks = "Dependencies/GoogleMaps.framework" # Put the Google-provided framework in that subfolder of your Pod project
#s.dependency 'Google-Maps-iOS-SDK' # Careful! this will cause errors if enabled!
end
I am now able to start a new iOS app in Xcode and use the following Podfile to link against my own pod, itself referencing the Google Maps iOS SDK:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
pod 'MyPod'
use_frameworks! # do not forget this!
Not that easy, but feasible after all! Hoping Google will soon patch its Podspec file for Swift developments, though.

Xcode, cocoapods + nib file, s.resources = ['*.{xib}'] not work

I have one trouble.
I created simple project and in result have next files: ViewController.h, ViewController.m, ViewController.xib, ViewController.podspec and LICENSE.
Structure of ViewController.podspec:
Pod:: Spec.new do |s|
s.name = "ViewController"
s.version = "0.1.0"
s.summary = "Some text"
s.homepage = "setmypage"
s.license = 'MIT'
s.author = { "Oleksii" => "oleksii#site.com" }
s.source = { :path => "." }
s.platform = :ios
s.requires_arc = true
s.source_files = '*.{h,m,xib}'
s.resources = ['*.{xib}']
end
I created simple new project and added folder with Pod.
after I did pod lib lint for my Pod
and do pod install this pod.
Structure Podfile:
platform :ios
pod "ViewController", :path => "testPod/"
pod 'ViewController'
Ok. I had project with my Pod. But when I'd tried to Build my project I received
Unable to run command 'StripNIB ViewController.nib' - this target might include its own product.
What should I do?
I had the same problem. You should not include the xib in the source_files parameter in your podspecs:
s.source_files = '*.{h,m,xib}'
s.resources = ['*.{xib}']
My podspecs was a little bit different than yours because by default cocoapod version 0.39 was setting a wildcard in the source_files which was obviously too inclusive, even if my xib were included as resources (resource_bundle):
s.source_files = 'Pod/Classes/**/*.{h,m}'
s.resource_bundles = {
'MyPodBundle' => ['Pod/Classes/**/*.xib']
}
So make sure you do not include your xib as source_files
The possible cause for this your listing your product's target under target dependencies. In xcode select your target and under Build Phases look at the Dependencies list your products target should not be listed there.
Also check your Bundle Resources and Link Binary with Libraries you can't have your product listed there.

Resources