Creating Swift Package from XCFramework: should .bundle be part of xcframework? - ios

I'm trying to create a swift package from xcframework, the question is if the framework need to load certain resources from a .bundle file, should the bundle be part of the framework, ie. xcframework? I had the following files in the single zip file:
MyPackage.xcframework
MyPackage.bundle
And uploaded it to a host server, in my Package.swift:
targets: [
.binaryTarget(name: "MyPackage", url: "HOST/MyPackage.xcframework.zip", checksum: "CHECKSUM")
]
I can add the Swift Package to my project and use it, but at runtime it cannot find the .bundle file.
I found someone having the same problem:
https://devforum.zoom.us/t/bundling-the-zoom-sdk-within-a-swift-package/48400
Even having the .bundle file as dependency in the Package.swift, it doesn't work, unless the bundle file is manually copied into the project.
So my question is, should this bundle be part of the .xcframework file instead of being a standalone .bundle file along with the .xcframework file? Or if there's something else I can do?
Thanks!

You can use the new approach introduced in Swift 5.3 for bundling resources with your swift package as described here.
Currently, there are two rules that are supported: process rule and copy rule, process rule applies specific processing rules to your resource files depending on whether it is xib, storyboard etc.
In your case, you need to use copy rule to copy the .bundle resource in your app. By default copy rule will copy your file to the root directory of your app, you can decide to provide path to a folder instead if you want to copy your file with specific folder structure.

Related

Make Xcode build a C file generated by processing a file with a custom extension

I'm trying to set up Xcode to build generated .c files just like it does for files generated by yacc (*.y) and lex (*.l) files.
Say I have input files with a *.corn extension that are meant to be processed by a tool of mine to create C source files. I then want these C source files to be compiled and linked using the rest of Xcode's mechanisms.
This is exactly what happens to my .y and .l files for yacc and lex. The project target contains only the .y and .l files and the rest happens automatically. Generated .c files get put in the derived files directory and those get compiled and linked automatically.
Here's what I've tried so far:
-If I just add a .corn file to my target, Xcode copies it into the bundle at build time presuming it is a resource. Okay, whatever.
-I then create a custom build rule to handle
Source files with names matching: *.corn
Using Custom Script:
#!/bin/sh
cp "${INPUT_FILE_PATH}" "${DERIVED_FILES_DIR}/${INPUT_FILE_BASE}.c"
I have to give it an output file so:
OutputFiles:
${DERIVED_FILES_DIR}/${INPUT_FILE_BASE}.c
Note in this case I'm just copying the file as I rename it with .c extension. (As I'm playing around, the .corn file just contains C source.)
So now before the bundle directory even gets created I get the following warning:
unexpected C compiler invocation with specified outputs: 'blahblahblah/Build/Products/Debug-iphonesimulator/MyApp.app/foo.c' (for input: 'blahblahblah/Build/Intermediates.noindex/MyApp.build/Debug-iphonesimulator/MyApp.build/DerivedSources/foo.c')
Then after the link phase (sheesh!), the script above runs and I do end up with my foo.c in DERIVED_FILES_DIR. It doesn't get compiled however and notably, foo.corn didn't get copied into the bundle anymore so there's hope.
I've tried a bunch of other stuff, but this is the cleanest I can describe that others can try. Please what is the magic incantation to make this work?!
Note that I've also tried using DERIVED_SOURCES_DIR instead of DERIVED_FILES_DIR.
So I missed two things:
I needed to add the .corn files to the "Compile Sources" build phase.
By adding .corn files to the project/target before the adding the custom build rule, Xcode added the .corn files to the "Copy Bundle Resources" build phase which broke the build.

Automate the process of including generated proto files into an Xcode project

Our iOS app currently is using Google protobuffer gRPC as our API layer to communicate between App and backend. And so we have these .proto files in our backend directory which will be converting to .grpc.swift and .pb.swift files by gRPC-Swift-Plugins and then consumed by the App.
This works okay, but the process of converting is very tedious, and we would like to automate the whole process.
Below is how we're doing it:
Delete previously copied directory, and copy all .proto files from backend (.proto files are maintained by backend devs) to App directory named "Protos" via a shell script
We already set up Build rules and include .proto files in Compile Sources. Following the steps from an answer here on SO
Screenshot of the current setup in Xcode Build Rules:
Whenever we build the project, .pb.swift and .grpc.swift are generated and putting into a directory named "generated" under the "Protos" folder.
Here are the problems:
If the backend added a new .proto files into the source directory, my script will only copy the files into the Protos directory but not included news files in the Compile Sources list.
Similar to the first problem, we need to manually set up Compile Sources in Xcode and that means if a new dev joins our team, he/she also needs to do the same setup again.
We sometimes need to refer to the .grpc.swift and .ph.swift files while coding. But If we add these files into Xcode and build the project again, Xcode will complain that these generated files are there like (Sorry, we're working on a private repo, so the project name and file names are replaced):
Multiple commands produce '${user_path}/${proto_name}.pb.o':
Target '${my_project_name}' (project '${my_project_name}') has compile command for Swift source files
Target '${my_project_name}' (project '${my_project_name}') has compile command for Swift source files
Any answers or comments and suggestions are greatly appreciated!
It's interesting I didn't have those problems with Swift if I use the $DERIVED_FILE_DIR
protoc "$INPUT_FILE_NAME" --swift_out="$DERIVED_FILE_DIR" --proto_path="Your/proto/path"
I don't use the plugin because I've got the plugin installed in my /usr/local/bin
But I have exactly those problems when we use the output for cpp files.

Is there a way to copy bundle resource to app folder when built finished?

Actually I have a xcode workspace, containing several projects, for example, projectA and projectB, projectA is the main project, and projectB will generate a bundle file which projectA will use, is there a way to copy the bundle file to the main app folder? I know one way to do this is to drag the generated bundle file here like the below image shows, but as we have several team members and use git to manage the project, this method will use my personal folder path, and when others want to build the project, they will have to drag the bundle again. Is there a way to copy the generated bundle using relative path? Or can I use a script to do this? So everyone can just checkout the code directly without dragging the bundle manually? Thanks.
In Target -> Build Phases can you just Run Script after that target is done to copy it to the other place?

Automate copying resources from dependency project

I have a static library which
Creates .a file
Exports public headers
Creates a .bundle containing resources
I have a workspace containing my project which depends on this lib. Library is also part of the workspace. I am able to work out the build dependencies on .a file and public headers. For the bundle, I have to manually add/update the bundle to my applications copy bundle resources build phase.
I want to automate this such that the bundle created in the $(BUILT_PRODUCTS_DIR) gets copied in the application bundle.
Is there a way to do this, may be a run script?
Appreciate your help.
Figured it out.
I added a run script phase to my application. Script to copy the generated bundle to my application,
cp -R ${BUILT_PRODUCTS_DIR}/Mybundle.bundle ${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/Mybundle.bundle
Hope this helps!

Invalid Directory Name - Your app contains a directory name that is already reserved

Just submitted my app for review and was then emailed this error message:
Invalid Directory Name - Your app contains a directory name that is already reserved: 'Frameworks'. You must rename this directory.
Anyone have experience with this?
edit for a little more info: The only thing I have changed recently which may have caused this is to use Cocoapods. I'm opening and compiling from the xcworkspace. I do notice that a library called 'QuickDialogs' which I use had a Group called 'Frameworks' which I renamed.
Try following steps:
find and open ${YOUR_PROJECT_ROOT}/Pods/Pods-resources.sh
search ${FRAMEWORKS_FOLDER_PATH} and replace with ${UNLOCALIZED_RESOURCES_FOLDER_PATH}
clean your project and delete derived Data(organizer-projects)
achive your application again
I met this problem when I add extra frameworks by cocoapods. App store's response told me that there was a directory named Frameworks, which is reserved.
This folder is created at Copy Pods Resources step in Build Phases,
I have found that using ShareKit with Cocoapods was adding a Frameworks to my binary. That's why I substituted:
pod "ShareKit"
with:
pod "ShareKit/Facebook"
pod "ShareKit/Twitter"
pod "ShareKit/GooglePlus"
as I only use these services.
In order to see the folder created go to your binary and see the contents of the archive generated in the Applications folder.
Hope that helps!

Resources