MobileNativeFoundation / rules_xcodeproj

Bazel rules for generating Xcode projects.
MIT License
514 stars 81 forks source link

Previews in modules #2911

Closed cordechasse closed 6 months ago

cordechasse commented 6 months ago

Hi,

I want to create an iOS App, with this kind of hierarchy:

Unfortunatlly, I can't find how to have Xcode Previews in the Packages. If I use a swift_library, I get the error : Previews not supported for static libraries. I've looked into the examples and didn't find any help. Could you give me a hint?

Thanks!

Here's my main BUILD.bazel file

load("@rules_apple//apple:ios.bzl", "ios_application")
load("@rules_swift//swift:swift.bzl", "swift_library")
load(
    "@rules_xcodeproj//xcodeproj:defs.bzl",
    "top_level_target",
    "xcodeproj",
)

swift_library(
    name = "lib",
    module_name = "MainLib",
    srcs = glob(["App/Sources/*.swift"]),
    deps = [
        "//Packages/UI:UI",
    ],
    visibility = ["//visibility:public"],
)

ios_application(
    name = "App",
    bundle_id = "xxx.xxx.xxx",
    families = [
        "iphone",
        "ipad",
    ],
    infoplists = ["App/Resources/Info.plist"],
    minimum_os_version = "17.0",
    visibility = ["//visibility:public"],
    deps = [":lib"],
)

xcodeproj(
    name = "xcodeproj",
    build_mode = "bazel",
    project_name = "iOSApp",
    tags = ["manual"],
    top_level_targets = [
        ":App",
    ],
)

In each packages, I've got a BUILD.bazel file :

load("@rules_swift//swift:swift.bzl", "swift_library")

swift_library(
    name = "UI",
    module_name = "UI",
    package_name = "UI",
    srcs = glob(["Sources/**/*.swift"]),
    data = [
        ":Assets"
    ],
    visibility = [
        "//visibility:public",
    ]
)

filegroup(
    name = "Assets",
    srcs = glob(["Resources/GlobalAssets.xcassets/**", "Resources/localizables/**"]),
    visibility = ["//visibility:public"],
)
luispadron commented 6 months ago

Xcode Previews require dynamic frameworks to work as the error in Xcode indicates. Essentially you'll need to add an ios_framework which bundles your swift_library.

For example, to make MainLib a dynamic framework:

swift_library(
    name = "lib",
    module_name = "MainLib",
    srcs = glob(["App/Sources/*.swift"]),
    deps = [
        "//Packages/UI:UI",
    ],
    visibility = ["//visibility:public"],
)

ios_framework(
  name = "lib.framework",
  deps = [":lib"],
  ...
)

ios_application(
    name = "App",
    bundle_id = "xxx.xxx.xxx",
    families = [
        "iphone",
        "ipad",
    ],
    frameworks = [":lib.framework"],  # <--- add the framework target here
    infoplists = ["App/Resources/Info.plist"],
    minimum_os_version = "17.0",
    visibility = ["//visibility:public"],
    deps = [":lib"],
)

For more information on using ios_framework the rules_apple docs give more information

You can see this previous question on the topic for more info as well: https://github.com/MobileNativeFoundation/rules_xcodeproj/issues/640

luispadron commented 6 months ago

I'm going to close this as things are working as expected from the example you gave us, but follow up in here if you have more questions

cordechasse commented 6 months ago

Thanks a lot for your answer., it works perfectly!