Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate bundle identifier #62

Closed
ryohey opened this issue Sep 22, 2017 · 6 comments
Closed

Generate bundle identifier #62

ryohey opened this issue Sep 22, 2017 · 6 comments

Comments

@ryohey
Copy link
Collaborator

ryohey commented Sep 22, 2017

Hello,
Thanks for your this great solution that I really wanted.

Today I tried to generate my project using XcodeGen.
I faced the problem that Xcode shows the message This app was unable to be installed after build the project for the simulator.

I reproduced it on TestProject in this repository.

  1. xcodegen --spec spec.yml
  2. Open GeneratedProject.xcodeproj
  3. Select the simulator like iPhone 8 Plus
  4. Run

It can be fixed by removing frameworks from Copy Files in Build Phases or remove the line https://github.com/yonaskolb/XcodeGen/blob/master/Sources/XcodeGenKit/PBXProjGenerator.swift#L236

I don't know this is correct way to fix it. But do frameworks need to be copied when these add as Embedded Framework?

@yonaskolb
Copy link
Owner

Hi @ryohey, glad you like it.

Interesting I haven't seen that issue before. What sort of dependency is it? You can also set embed: false for that dependency and that may fix it.
If you can share your spec that would help a lot.

@ryohey
Copy link
Collaborator Author

ryohey commented Sep 23, 2017

embed: false solved the issue! Thank you so much.

This is my final spec just in case.

name: feather
targets:
  feather:
    type: application
    platform: iOS
    sources: 
      - feather
      - Vendor
    settings:
      base:
        PRODUCT_BUNDLE_IDENTIFIER: com.covelline.feather
        INFOPLIST_FILE: feather/feather-Info.plist
        ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon
        SWIFT_OBJC_BRIDGING_HEADER: feather/feather-Bridging-Header.h
        SWIFT_OPTIMIZATION_LEVEL: "-Owholemodule"
        GCC_PREFIX_HEADER: feather/feather-prefix.pch
      configs:
        Debug:
          CODE_SIGN_IDENTITY: "iPhone Developer"
          CODE_SIGN_ENTITLEMENTS: feather/development.entitlements
          PROVISIONING_PROFILE_SPECIFIER: "match Development com.covelline.feather"
        Release:
          CODE_SIGN_IDENTITY: "iPhone Distribution"
          CODE_SIGN_ENTITLEMENTS: feather/production.entitlements
          PROVISIONING_PROFILE_SPECIFIER: "match AdHoc com.covelline.feather"
    dependencies:
      - target: Prelude
        embed: false
      - target: PreludeUIKit
        embed: false
      - target: Library
        embed: false
      - target: Shared
        embed: false
      - target: TwitterAPI
        embed: false
      - target: TwitterService
        embed: false
      - carthage: IDZSwiftCommonCrypto
      - carthage: MBProgressHUD
      - carthage: NowPlayingFormatter
      - carthage: OnePasswordExtension
      - carthage: PINCache
      - carthage: Popover
      - carthage: Realm
      - carthage: RealmSwift
      - carthage: STPopup
      - carthage: SwiftyAppearance
      - carthage: TextAttributes
      - carthage: Unbox
      - carthage: XCGLogger
    dependencies:
      - target: Prelude
        embed: false
      - target: Library
        embed: false
      - target: Shared
        embed: false
      - target: TwitterAPI
        embed: false
      - target: TwitterService
        embed: false
      - carthage: IDZSwiftCommonCrypto
      - carthage: MBProgressHUD
      - carthage: NowPlayingFormatter
      - carthage: OnePasswordExtension
      - carthage: PINCache
      - carthage: Popover
      - carthage: Realm
      - carthage: RealmSwift
      - carthage: STPopup
      - carthage: SwiftyAppearance
      - carthage: TextAttributes
      - carthage: Unbox
      - carthage: XCGLogger
  featherTests:
    type: bundle.unit-test
    platform: iOS
    sources: featherTests
    settings:
      base:
        PRODUCT_BUNDLE_IDENTIFIER: com.covelline.featherTests
        INFOPLIST_FILE: featherTests/Info.plist
        GCC_PREFIX_HEADER: featherTests/featherTests-prefix.pch
    dependencies:
      - target: TestHelper
  Prelude:
    type: framework
    platform: iOS
    sources: Prelude
    settings:
      INFOPLIST_FILE: Prelude/Info.plist
    scheme:
      testTargets:
        - PreludeTests
  PreludeTests:
    type: bundle.unit-test
    platform: iOS
    sources: PreludeTests
    settings:
      PRODUCT_BUNDLE_IDENTIFIER: com.covelline.PreludeTests
      INFOPLIST_FILE: PreludeTests/Info.plist
    dependencies:
      - target: TestHelper
  PreludeUIKit:
    type: framework
    platform: iOS
    sources: PreludeUIKit
    settings:
      INFOPLIST_FILE: PreludeUIKit/Info.plist
  TestHelper:
    type: framework
    platform: iOS
    sources: TestHelper
    settings:
      INFOPLIST_FILE: TestHelper/Info.plist
  Library:
    type: framework
    platform: iOS
    sources: Library
    settings:
      INFOPLIST_FILE: Library/Info.plist
      GCC_PREFIX_HEADER: Library/Library-prefix.pch
    scheme:
      testTargets:
        - LibraryTests
  LibraryTests:
    type: bundle.unit-test
    platform: iOS
    sources: LibraryTests
    settings:
      PRODUCT_BUNDLE_IDENTIFIER: com.covelline.LibraryTests
      INFOPLIST_FILE: LibraryTests/Info.plist
    dependencies:
      - target: TestHelper
  Shared:
    type: framework
    platform: iOS
    sources: Shared
    settings:
      INFOPLIST_FILE: Library/Info.plist
  TwitterAPI:
    type: framework
    platform: iOS
    sources: TwitterAPI
    settings:
      INFOPLIST_FILE: TwitterAPI/Info.plist
      GCC_PREFIX_HEADER: TwitterAPI/TwitterAPI-prefix.pch
    scheme:
      testTargets:
        - TwitterAPITests
  TwitterAPITests:
    type: bundle.unit-test
    platform: iOS
    sources: TwitterAPITests
    settings:
      PRODUCT_BUNDLE_IDENTIFIER: com.covelline.TwitterAPITests
      INFOPLIST_FILE: TwitterAPITests/Info.plist
    dependencies:
      - target: TestHelper
  TwitterService:
    type: framework
    platform: iOS
    sources: TwitterService
    dependencies:
      - target: TwitterAPI
      - carthage: PINCache
    settings:
      INFOPLIST_FILE: TwitterService/Info.plist
      GCC_PREFIX_HEADER: TwitterService/TwitterService-prefix.pch
    scheme:
      testTargets:
        - TwitterServiceTests
  TwitterServiceTests:
    type: bundle.unit-test
    platform: iOS
    sources: TwitterServiceTests
    settings:
      PRODUCT_BUNDLE_IDENTIFIER: com.covelline.TwitterServiceTests
      INFOPLIST_FILE: TwitterServiceTests/Info.plist
    dependencies:
      - target: TestHelper

For TestProject, I think this is not a problem, but I will report it in case.
I just cloned this repository and run xcodegen --spec spec.yml in XcodeGen/Fixtures/TestProject then open the project and Run.
This seems to be caused by the same thing.

image

spec.yml

name: GeneratedProject
targets:
  TestProject:
    type: application
    platform: iOS
    sources: TestProject
    settings:
      INFOPLIST_FILE: TestProject/Info.plist
      PRODUCT_BUNDLE_IDENTIFIER: com.test
    dependencies:
      - target: MyFramework
    scheme:
      testTargets:
        - TestProjectTests
    postbuildScripts:
      - path: scripts/strip-frameworks.sh
        name: Strip Unused Architectures from Frameworks
        runOnlyWhenInstalling: true
      - name: Swiftlint
        script: |
          if which swiftlint >/dev/null; then
            swiftlint
          else
            echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"
          fi
  MyFramework:
    type: framework
    platform: iOS
    sources: MyFramework
    settings:
      INFOPLIST_FILE: MyFramework/Info.plist
    postbuildScripts:
      - name: Swiftlint
        path: scripts/swiftlint.sh
  TestProjectTests:
    type: bundle.unit-test
    platform: iOS
    sources: TestProjectTests
    settings:
      TEST_HOST: $(BUILT_PRODUCTS_DIR)/TestProject.app/TestProject
      INFOPLIST_FILE: TestProjectTests/Info.plist
    dependencies:
      - target: TestProject

@yonaskolb
Copy link
Owner

After some debugging, I found the issue! The problem is that some of your targets and the Fixture framework are missing a PRODUCT_BUNDLE_IDENTIFIER. Adding this launches the app correctly.

It's interesting that removing the embed frameworks phase both stops this issue from happening and also results in a still functional app. I guess embedding isn't necessary when you have a target dependency, but I do it anyway as that's what Xcode does by default when you create a target and "embed" it in another target.

To make it easier to provide a bundle id I could add a feature where you provide an Organisation Identifier in the spec like you do in Xcode when you create a project. This could then let targets auto generate their bundle id using that and appending their name. This is similar to how I automatically find the Info.plist file in sources if it isn't already specified. What do you think?

Also it's cool for my to see what other people's specs look like. Looking at yours I could offer a few suggestions/comments:

  • You seem to have defined dependencies twice in your feature application
  • ASSETCATALOG_COMPILER_APPICON_NAME should already be applied by default to all iOS apps via SettingPresets/Platforms/iOS.yml.
  • as mentioned above Info.plist files are automatically found in a targets sources, so unless they live outside of that you can optionally leave it out.

@ryohey
Copy link
Collaborator Author

ryohey commented Sep 24, 2017

Auto generation of the bundle id is very cool! It's so helpful.

Thank you for your suggestions! I have a mistake of copy & paste.
This is fixed spec.

name: feather
targets:
  feather:
    type: application
    platform: iOS
    sources: 
      - feather
      - Vendor
    settings:
      base:
        PRODUCT_BUNDLE_IDENTIFIER: com.covelline.feather
        INFOPLIST_FILE: feather/feather-Info.plist
        ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon
        SWIFT_OBJC_BRIDGING_HEADER: feather/feather-Bridging-Header.h
        SWIFT_OPTIMIZATION_LEVEL: "-Owholemodule"
        GCC_PREFIX_HEADER: feather/feather-prefix.pch
      configs:
        Debug:
          CODE_SIGN_IDENTITY: "iPhone Developer"
          CODE_SIGN_ENTITLEMENTS: feather/development.entitlements
          PROVISIONING_PROFILE_SPECIFIER: "match Development com.covelline.feather"
        Release:
          CODE_SIGN_IDENTITY: "iPhone Distribution"
          CODE_SIGN_ENTITLEMENTS: feather/production.entitlements
          PROVISIONING_PROFILE_SPECIFIER: "match AdHoc com.covelline.feather"
    dependencies:
      - target: Prelude
        embed: false
      - target: Library
        embed: false
      - target: Shared
        embed: false
      - target: TwitterAPI
        embed: false
      - target: TwitterService
        embed: false
      - carthage: IDZSwiftCommonCrypto
      - carthage: MBProgressHUD
      - carthage: NowPlayingFormatter
      - carthage: OnePasswordExtension
      - carthage: PINCache
      - carthage: Popover
      - carthage: Realm
      - carthage: RealmSwift
      - carthage: STPopup
      - carthage: SwiftyAppearance
      - carthage: TextAttributes
      - carthage: Unbox
      - carthage: XCGLogger
  "feather free":
    type: application
    platform: iOS
    sources: 
      - feather
      - "feather free"
      - Vendor
    settings:
      base: 
        PRODUCT_BUNDLE_IDENTIFIER: com.covelline.feather-free
        INFOPLIST_FILE: feather/feather-free-Info.plist
        ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon-free
        SWIFT_OBJC_BRIDGING_HEADER: feather/feather-Bridging-Header.h
        SWIFT_OBJC_INTERFACE_HEADER_NAME: feather-Swift.h
        SWIFT_OPTIMIZATION_LEVEL: "-Owholemodule"
        GCC_PREFIX_HEADER: feather/feather-prefix.pch
        GCC_PREPROCESSOR_DEFINITIONS:
          - "$(inherited)"
          - FEATHER_FREE=1
      configs:
        Debug:
          CODE_SIGN_IDENTITY: "iPhone Developer"
          CODE_SIGN_ENTITLEMENTS: feather/development.entitlements
          PROVISIONING_PROFILE_SPECIFIER: "match Development com.covelline.feather-free"
        Release:
          CODE_SIGN_IDENTITY: "iPhone Distribution"
          CODE_SIGN_ENTITLEMENTS: feather/production.entitlements
          PROVISIONING_PROFILE_SPECIFIER: "match AdHoc com.covelline.feather-free"
    dependencies:
      - target: Prelude
        embed: false
      - target: Library
        embed: false
      - target: Shared
        embed: false
      - target: TwitterAPI
        embed: false
      - target: TwitterService
        embed: false
      - carthage: IDZSwiftCommonCrypto
      - carthage: MBProgressHUD
      - carthage: NowPlayingFormatter
      - carthage: OnePasswordExtension
      - carthage: PINCache
      - carthage: Popover
      - carthage: Realm
      - carthage: RealmSwift
      - carthage: STPopup
      - carthage: SwiftyAppearance
      - carthage: TextAttributes
      - carthage: Unbox
      - carthage: XCGLogger
  featherTests:
    type: bundle.unit-test
    platform: iOS
    sources: featherTests
    settings:
      base:
        PRODUCT_BUNDLE_IDENTIFIER: com.covelline.featherTests
        INFOPLIST_FILE: featherTests/Info.plist
        GCC_PREFIX_HEADER: featherTests/featherTests-prefix.pch
    dependencies:
      - target: TestHelper
  "feather freeTests":
    type: bundle.unit-test
    platform: iOS
    sources: "feather freeTests"
    settings:
      PRODUCT_BUNDLE_IDENTIFIER: com.covelline.feather-freeTests
      INFOPLIST_FILE: "feather freeTests/Info.plist"
    dependencies:
      - target: TestHelper
  Prelude:
    type: framework
    platform: iOS
    sources: Prelude
    settings:
      INFOPLIST_FILE: Prelude/Info.plist
    scheme:
      testTargets:
        - PreludeTests
  PreludeTests:
    type: bundle.unit-test
    platform: iOS
    sources: PreludeTests
    settings:
      PRODUCT_BUNDLE_IDENTIFIER: com.covelline.PreludeTests
      INFOPLIST_FILE: PreludeTests/Info.plist
    dependencies:
      - target: TestHelper
  PreludeUIKit:
    type: framework
    platform: iOS
    sources: PreludeUIKit
    settings:
      INFOPLIST_FILE: PreludeUIKit/Info.plist
  TestHelper:
    type: framework
    platform: iOS
    sources: TestHelper
    settings:
      INFOPLIST_FILE: TestHelper/Info.plist
  Library:
    type: framework
    platform: iOS
    sources: Library
    settings:
      INFOPLIST_FILE: Library/Info.plist
      GCC_PREFIX_HEADER: Library/Library-prefix.pch
    scheme:
      testTargets:
        - LibraryTests
  LibraryTests:
    type: bundle.unit-test
    platform: iOS
    sources: LibraryTests
    settings:
      PRODUCT_BUNDLE_IDENTIFIER: com.covelline.LibraryTests
      INFOPLIST_FILE: LibraryTests/Info.plist
    dependencies:
      - target: TestHelper
  Shared:
    type: framework
    platform: iOS
    sources: Shared
    settings:
      INFOPLIST_FILE: Library/Info.plist
  TwitterAPI:
    type: framework
    platform: iOS
    sources: TwitterAPI
    settings:
      INFOPLIST_FILE: TwitterAPI/Info.plist
      GCC_PREFIX_HEADER: TwitterAPI/TwitterAPI-prefix.pch
    scheme:
      testTargets:
        - TwitterAPITests
  TwitterAPITests:
    type: bundle.unit-test
    platform: iOS
    sources: TwitterAPITests
    settings:
      PRODUCT_BUNDLE_IDENTIFIER: com.covelline.TwitterAPITests
      INFOPLIST_FILE: TwitterAPITests/Info.plist
    dependencies:
      - target: TestHelper
  TwitterService:
    type: framework
    platform: iOS
    sources: TwitterService
    dependencies:
      - target: TwitterAPI
      - carthage: PINCache
    settings:
      INFOPLIST_FILE: TwitterService/Info.plist
      GCC_PREFIX_HEADER: TwitterService/TwitterService-prefix.pch
    scheme:
      testTargets:
        - TwitterServiceTests
  TwitterServiceTests:
    type: bundle.unit-test
    platform: iOS
    sources: TwitterServiceTests
    settings:
      PRODUCT_BUNDLE_IDENTIFIER: com.covelline.TwitterServiceTests
      INFOPLIST_FILE: TwitterServiceTests/Info.plist
    dependencies:
      - target: TestHelper

Actually spec has other target feather-free that is another version of this application that shared the code base but AppIcon and Info.plist and preprocessor flags are difference.

Both targets have almost same spec. I'm not sure can we provide the abstract target that is the parent of targets feather and feather-free like cocoapods abstract_target? (Sorry this is a little off topic)

@yonaskolb
Copy link
Owner

yonaskolb commented Sep 24, 2017

You can indeed have a sort of abstract target by using the include feature. See #61 for more details.
Basically you could have a base spec and then have 1 or more other specs that ‘include’ the base and then add or override any properties you wish

@yonaskolb yonaskolb changed the title Xcode9: This app was unable to be installed Generate bundle identifier Sep 24, 2017
@yonaskolb
Copy link
Owner

@ryohey, automatically generating PRODUCT_BUNDLE_IDENTIFIER has been added in #67

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants