iOS:如何基于可可录依赖项构建静态框架?

发布于 2025-02-06 07:04:03 字数 8715 浏览 0 评论 0 原文

我正在尝试构建一个框架,该框架使用 geopackage-ios a> cocoapods依赖性。然后,我想将此框架静态嵌入到一个或多个应用程序中。

之前已经提出过类似的问题,但我找不到解决问题的方法。这是我到目前为止一直在尝试的方法:

第一种方法:

在这种方法中手动构建,我将使用Xcode创建一个静态库,将CocoApods依赖性添加到其上并构建。但是,这种方法的问题在于,由此产生的框架将不会将可可脚类依赖性嵌入其中。

  1. 从Xcode( file> new> project…> ios:static库)中创建一个新的静态库,名为“ mylibrary”,language swift。
  2. 在项目根目录中创建 podfile ,其中包含以下内容:
target 'MyLibrary' do
    pod 'geopackage-ios', '~> 7.2.1'
end
  1. run pod install 。 (这将安装 geopackage-ios pod和10个根据豆荚。)
  2. 打开新创建的 myLibrary.xcworkspace ,然后添加 bridgingheader.h 具有以下内容的“ mylibrary”组:
#ifndef BridgingHeader_h
#define BridgingHeader_h

#import "geopackage-ios-Bridging-Header.h"

#endif
  1. 通过单击项目Navigator中的“ mylibrary”项目参考桥接标头,选择“ mylibrary”目标,以及在 build build settings 中,指定 > mylibrary/bridgingheader.h 作为“ Objective-C Bridging标头”。
  2. 修改 mylibrary.swift 使用geopackage依赖关系:
public class MyLibrary {
    public init() {}
    
    public func test() {
        let manager = GPKGGeoPackageFactory.manager()!
        print("Manager:", manager)
    }
}
  1. 通过按 cmd + b 来构建iOS模拟器库。
  2. 可选地,使用本文(它将为模拟器编译一次库,一次用于物理设备,然后使用 lipo 命令)。

当我将静态库(以及 mylibrary.swiftModule )或通用框架嵌入到一个应用程序中时,链接将失败此应用程序:

Undefined symbols for architecture x86_64:
  "_OBJC_CLASS_$_GPKGGeoPackageManager", referenced from:
      objc-class-ref in libMyLibrary.a(MyLibrary.o)
  "_OBJC_CLASS_$_GPKGGeoPackageFactory", referenced from:
      objc-class-ref in libMyLibrary.a(MyLibrary.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

我还可以添加 geopackage_ios.framework (在应用程序的“ mylibrary”的构建文件夹中找到)到该应用程序(确保选择 emp; amp; amp; emp; em>嵌入式选项),这将允许成功构建应用程序。但是,该应用将在启动时崩溃:

dyld[79209]: Library not loaded: @rpath/ogc_api_features_json_ios.framework/ogc_api_features_json_ios
  Referenced from: /Users/admin1/Library/Developer/CoreSimulator/Devices/C3D61224-CFE8-45CC-951B-7B6AB54BC8B3/data/Containers/Bundle/Application/D41A82D6-4E69-4BB6-AC59-6BC28AE58795/TestApp.app/Frameworks/geopackage_ios.framework/geopackage_ios

一个人可以通过将所有11个POD框架添加到应用程序中来解决此问题,但是,这是我要避免的。

第二种方法:使用podbuilder

第二种方法是使用 ,旨在自动执行此特定的构建任务。但是,这种方法因构建错误而失败,这是我无法完全理解的原因。

  1. 同样,我将从一个新的Xcode项目开始。这次,我将创建一个名为“ MyApp”的iOS Swift应用程序。
  2. 我将创建一个 podfile ,几乎与上面的内容相同:
use_frameworks!
target 'MyApp' do
    pod 'geopackage-ios', '~> 7.2.1'
end
  1. 然后,我将运行 pod install
  2. 接下来,我将安装podbuilder,创建一个空的git存储库(出于某种原因需要该存储库),初始化podbuilder,然后启动构建任务:
sudo gem install pod-builder
git init
pod_builder init
pod_builder build geopackage-ios
  1. 构建将失败,但是,类似这样的错误将其写入/tmp/pod_builderderderdem /pod_builder.err
Undefined symbols for architecture arm64:
  "_PROJ_WEB_MERCATOR_MAX_LAT_RANGE", referenced from:
      +[GPKGTileBoundingBoxUtils toWebMercatorWithBoundingBox:] in GPKGTileBoundingBoxUtils.o
      +[GPKGTileBoundingBoxUtils boundDegreesBoundingBoxWithWebMercatorLimits:] in GPKGTileBoundingBoxUtils.o
      -[GPKGTileDao isXYZTiles] in GPKGTileDao.o
      -[GPKGTileGenerator adjustXYZBounds] in GPKGTileGenerator.o
  "_PROJ_UNDEFINED_CARTESIAN", referenced from:
      -[GPKGSpatialReferenceSystemDao createIfNeededWithSrs:andOrganization:andCoordsysId:] in GPKGSpatialReferenceSystemDao.o
  "_PROJ_AUTHORITY_NONE", referenced from:
      -[GPKGSpatialReferenceSystemDao createIfNeededWithSrs:andOrganization:andCoordsysId:] in GPKGSpatialReferenceSystemDao.o
  […]
  1. 这似乎是 geopackage-ios pod本身的问题,可以通过克隆我们自己的repo………
cd ..
git clone --branch 7.2.1 https://github.com/ngageoint/geopackage-ios.git
  1. ,安装吊舱
cd geopackage-ios
pod install
  1. ……………………手动复制 proj-ios 源文件…
cp -r Pods/proj-ios/proj-ios geopackage-ios
  1. …,并打开 geopackage-ios.xcodeproj 以引用 proj-ios 文件在该项目中的 geopackage-ios 组中。

  2. 然后告诉Cocoapods使用我们的本地版本的POD…

use_frameworks!
target 'MyApp' do
    pod 'geopackage-ios', :path => '../geopackage-ios'
end
  1. ,重新定性podbuilder
cd ../MyApp
pod_builder deintegrate
pod deintegrate
pod install
pod_builder init
  1. 使用
{
  …,
  "allow_building_development_pods": true,
  …
}
  1. …………并允许podbuilder编辑 ./ podbuilder/podbuilder.json.json 文件:然后,一个人可以尝试尝试,一个人可以尝试尝试,一个人可以尝试尝试,一个人可以尝试试图尝试,一个人可以尝试试图尝试,一个人可以尝试尝试,一个人可以尝试尝试,一个人可以尝试尝试 重建:
pod_builder build geopackage-ios

这次,构建将失败,并以不同的错误失败:

The following build commands failed:
    CompileC /tmp/pod_builder/build/Pods.build/Release-iphoneos/sf-proj-ios.build/Objects-normal/arm64/SFPGeometryTransform.o /tmp/pod_builder/Pods/sf-proj-ios/sf-proj-ios/SFPGeometryTransform.m normal arm64 objective-c com.apple.compilers.llvm.clang.1_0.compiler (in target 'sf-proj-ios' from project 'Pods')
(1 failure)

sfpgeometrytransform.m 文件看起来不错。

The full build log is available here.

第三种方法:使用罗马

第三种方法是使用 cocoapods-rome < /代码>

  1. 要使用它,一个人会安装罗马……
sudo gem install cocoapods-rome
  1. ,摆脱podbuilder的东西……
pod_builder deintegrate
pod deintegrate
  1. ,快速调整 podfile
use_frameworks!
platform :ios, '13.0'

plugin 'cocoapods-rome', { :pre_compile => Proc.new { |installer|
    installer.pods_project.targets.each do |target|
        target.build_configurations.each do |config|
            config.build_settings['SWIFT_VERSION'] = '5.0'
        end
    end

    installer.pods_project.save
},
    dsym: false,
    configuration: 'Release'
}

target 'MyApp' do
    pod 'geopackage-ios', :path => '../geopackage-ios'
end
  1. …并安装pods:
pod install

但是,这种错误将失败,并且与完全相同的错误失败Podbuilder。

谁能就这些方法给我一些建议?还是有人对如何构建这样的框架有完全不同的想法?

(编辑:看起来像 projproctiveTransform.h 导入到 sfppeometrytransform.m 的文件。无论如何,我认为这些方法都不是权宜的。高度赞赏。)

I am trying to build a framework that makes use of the geopackage-ios CocoaPods dependency. I would then like to statically embed this framework into one or more apps.

Similar questions have been asked before, but I couldn't find a solution to my problem. Here's what I've been trying so far:

First Approach: Building Manually

In this approach, I would create a static library using Xcode, add the CocoaPods dependencies to it and build it. The problem with this approach, however, is that the resulting framework will not have the CocoaPods dependencies embedded into it.

  1. Create a new static library from Xcode (File > New > Project… > iOS: Static Library) named "MyLibrary" with language Swift.
  2. Create a Podfile in the project root directory with the following content:
target 'MyLibrary' do
    pod 'geopackage-ios', '~> 7.2.1'
end
  1. Run pod install. (This will install the geopackage-ios pod and 10 depending pods.)
  2. Open the newly created MyLibrary.xcworkspace and add a BridgingHeader.h to the "MyLibrary" group having the following content:
#ifndef BridgingHeader_h
#define BridgingHeader_h

#import "geopackage-ios-Bridging-Header.h"

#endif
  1. Reference the bridging header by clicking on the "MyLibrary" project in the project navigator, selecting the "MyLibrary" target and, in the Build Settings, specifying MyLibrary/BridgingHeader.h as the "Objective-C Bridging Header".
  2. Modify MyLibrary.swift to use the GeoPackage dependency:
public class MyLibrary {
    public init() {}
    
    public func test() {
        let manager = GPKGGeoPackageFactory.manager()!
        print("Manager:", manager)
    }
}
  1. Build the library for the iOS simulator by pressing Cmd + B.
  2. Optionally, create a static framework using a shell script like the one in this article (which will compile the library once for the simulator and once for physical devices and then combine the two results to a universal framework using the lipo command).

When I embed either the static library (along with the MyLibrary.swiftmodule) or the universal framework into an app, linking will fail for this app:

Undefined symbols for architecture x86_64:
  "_OBJC_CLASS_$_GPKGGeoPackageManager", referenced from:
      objc-class-ref in libMyLibrary.a(MyLibrary.o)
  "_OBJC_CLASS_$_GPKGGeoPackageFactory", referenced from:
      objc-class-ref in libMyLibrary.a(MyLibrary.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I could also add the geopackage_ios.framework (found in the build folder of "MyLibrary") to the app (making sure to choose the Embed & Sign embedding option), which will allow the app to be built successfully. Then, however, the app will crash upon launch:

dyld[79209]: Library not loaded: @rpath/ogc_api_features_json_ios.framework/ogc_api_features_json_ios
  Referenced from: /Users/admin1/Library/Developer/CoreSimulator/Devices/C3D61224-CFE8-45CC-951B-7B6AB54BC8B3/data/Containers/Bundle/Application/D41A82D6-4E69-4BB6-AC59-6BC28AE58795/TestApp.app/Frameworks/geopackage_ios.framework/geopackage_ios

One might be able to fix this by adding all eleven pod frameworks to the app, which, however, is what I'm trying to avoid.

Second Approach: Using PodBuilder

A second approach would be to use PodBuilder, which aims at automating this particular kind of build task. This approach, however, fails with a build error, the cause of which I can't quite make out.

  1. Again, I would start out with a new Xcode project. This time, I'd create an iOS Swift app named "MyApp".
  2. I would create a Podfile with almost the same content as above:
use_frameworks!
target 'MyApp' do
    pod 'geopackage-ios', '~> 7.2.1'
end
  1. Then, I'd run pod install.
  2. Next, I would install PodBuilder, create an empty Git repository (which PodBuilder requires for some reason), initialize PodBuilder, and start the build task:
sudo gem install pod-builder
git init
pod_builder init
pod_builder build geopackage-ios
  1. The build will fail, however, with errors like these written to /tmp/pod_builder/pod_builder.err:
Undefined symbols for architecture arm64:
  "_PROJ_WEB_MERCATOR_MAX_LAT_RANGE", referenced from:
      +[GPKGTileBoundingBoxUtils toWebMercatorWithBoundingBox:] in GPKGTileBoundingBoxUtils.o
      +[GPKGTileBoundingBoxUtils boundDegreesBoundingBoxWithWebMercatorLimits:] in GPKGTileBoundingBoxUtils.o
      -[GPKGTileDao isXYZTiles] in GPKGTileDao.o
      -[GPKGTileGenerator adjustXYZBounds] in GPKGTileGenerator.o
  "_PROJ_UNDEFINED_CARTESIAN", referenced from:
      -[GPKGSpatialReferenceSystemDao createIfNeededWithSrs:andOrganization:andCoordsysId:] in GPKGSpatialReferenceSystemDao.o
  "_PROJ_AUTHORITY_NONE", referenced from:
      -[GPKGSpatialReferenceSystemDao createIfNeededWithSrs:andOrganization:andCoordsysId:] in GPKGSpatialReferenceSystemDao.o
  […]
  1. This seems to be a problem with the geopackage-ios pod itself, which can be fixed by cloning our own version of the repo …
cd ..
git clone --branch 7.2.1 https://github.com/ngageoint/geopackage-ios.git
  1. …, installing the pods …
cd geopackage-ios
pod install
  1. … manually copying the proj-ios source files …
cp -r Pods/proj-ios/proj-ios geopackage-ios
  1. …, and opening the geopackage-ios.xcodeproj to reference the proj-ios files in the geopackage-ios group inside that project.

  2. Then telling CocoaPods to use our local version of the pod …

use_frameworks!
target 'MyApp' do
    pod 'geopackage-ios', :path => '../geopackage-ios'
end
  1. …, reinitializing PodBuilder …
cd ../MyApp
pod_builder deintegrate
pod deintegrate
pod install
pod_builder init
  1. … and allowing PodBuilder to use local pods by editing the ./PodBuilder/PodBuilder.json file:
{
  …,
  "allow_building_development_pods": true,
  …
}
  1. Then, one can try to rebuild:
pod_builder build geopackage-ios

This time, the build will fail with a different error:

The following build commands failed:
    CompileC /tmp/pod_builder/build/Pods.build/Release-iphoneos/sf-proj-ios.build/Objects-normal/arm64/SFPGeometryTransform.o /tmp/pod_builder/Pods/sf-proj-ios/sf-proj-ios/SFPGeometryTransform.m normal arm64 objective-c com.apple.compilers.llvm.clang.1_0.compiler (in target 'sf-proj-ios' from project 'Pods')
(1 failure)

The SFPGeometryTransform.m file, however, looks fine.

The full build log is available here.

Third Approach: Using Rome

The third approach would be to use cocoapods-rome.

  1. To use it, one would install Rome …
sudo gem install cocoapods-rome
  1. …, get rid of the PodBuilder stuff …
pod_builder deintegrate
pod deintegrate
  1. …, quickly adjust the Podfile:
use_frameworks!
platform :ios, '13.0'

plugin 'cocoapods-rome', { :pre_compile => Proc.new { |installer|
    installer.pods_project.targets.each do |target|
        target.build_configurations.each do |config|
            config.build_settings['SWIFT_VERSION'] = '5.0'
        end
    end

    installer.pods_project.save
},
    dsym: false,
    configuration: 'Release'
}

target 'MyApp' do
    pod 'geopackage-ios', :path => '../geopackage-ios'
end
  1. … and install the pods:
pod install

This, however, will fail with the exact same error as PodBuilder.

Can anyone give me some advice on any of these approaches? Or does anyone perhaps have a whole different idea on how to build such a framework?

(EDIT: It seems like the PROJProjectionTransform.h file imported to SFPGeometryTransform.m cannot be found. Anyway, I don't think these approaches are expedient. So any help is highly appreciated.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

大海や 2025-02-13 07:04:03

通过简单地将所有汇总的源文件从 pod安装中馈送到新的静态库中,然后使用 lipo 命令来解决问题,从而解决了问题。 creating an Xcode framework from it (as described here).然后,可以使用编译的框架来创建另一个在其顶部构建的框架。

Solved the problem by simply feeding all the aggregated source files from the pod installation into a new static library, then using either the lipo command to make a fat binary out of it or creating an Xcode framework from it (as described here). The compiled framework could then be used to create another framework built on top of it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文