R.swift icon indicating copy to clipboard operation
R.swift copied to clipboard

R.generetade.swift is missing in Private pod library, when runnning pod install

Open sandeeprachha opened this issue 2 years ago • 14 comments

Hi team I'm trying to add R.swift in our custom pod library which is installed in our project. I have added run script in Podspec and able to generate script, input, output files in build phases of Pods.xcodeproj and drag and drop the R.genereted.swift in Xcode Pods. But if we make any changes in pod and installs again in our project, then R.generated,swift is missing from Xcode. Requesting you to how to resolve this issue, to keep R.generated.swift always even after pod install.

sandeeprachha avatar Jul 22 '21 18:07 sandeeprachha

Hi team I'm trying to add R.swift in our custom pod library which is installed in our project. I have added run script in Podspec and able to generate script, input, output files in build phases of Pods.xcodeproj and drag and drop the R.genereted.swift in Xcode Pods. But if we make any changes in pod and installs again in our project, then R.generated,swift is missing from Xcode. Requesting you to how to resolve this issue, to keep R.generated.swift always even after pod install.

I am also in this matter,How can I added run script in Podspec and able to generate script, input, output files in build phases of Pods.xcodeproj ?Could you provide the script,thx

XiMuYouZi avatar Aug 05 '21 10:08 XiMuYouZi

@XiMuYouZi s.dependency 'R.swift' s.script_phases = [{ :name => 'R', :script => '"$PODS_ROOT/R.swift/rswift" generate --accessLevel public "$SRCROOT/PodlibraryName/R.generated.swift"', :execution_position => :before_compile, :input_files => ["$TEMP_DIR/rswift-lastrun"], :output_files => ["$SRCROOT/PodlibraryName/R.generated.swift"] }]

sandeeprachha avatar Aug 17 '21 06:08 sandeeprachha

@sandeeprachha @XiMuYouZi

Change the path of your output file to your Pod Library Source directory. Then when you run pod install it will be always there.

  s.script_phases = [{
    :name => 'R',
    :script => '"$PODS_ROOT/R.swift/rswift" generate "$SRCROOT/../<PodLibraryName>/Classes/R.generated.swift"',
    :execution_position => :before_compile,
    :input_files => ["$TEMP_DIR/rswift-lastrun"],
    :output_files => ["$SRCROOT/../<PodLibraryName>/Classes/R.generated.swift"]
  }]

udbhateja avatar Aug 27 '21 06:08 udbhateja

@XiMuYouZi I think change podspec is not a good idea. That's what I do

# Podfile

post_install do |installer|
  puts "Adding code generation build phases to development pods"
  installer.pods_project.targets.each do |target|
    if ["NMHomeModule", "NMProfileModule"].include? target.name
      phase = target.new_shell_script_build_phase("Code generation")
      phase.shell_script = "\"$PODS_ROOT/R.swift/rswift\" generate \"$SRCROOT/../../../#{target.name}/sources/R.generated.swift\""
      phase.input_paths << "$TEMP_DIR/rswift-lastrun"
      phase.output_paths << "$SRCROOT/../../../#{target.name}/sources/R.generated.swift"
      target.build_phases.unshift(target.build_phases.pop()) # move it to the beginning. `target.build_phases.rotate(1)` should have worked as well
    end
  end
end


BTCherryKing avatar Oct 20 '21 03:10 BTCherryKing

@sandeeprachha @XiMuYouZi

Change the path of your output file to your Pod Library Source directory. Then when you run pod install it will be always there.

  s.script_phases = [{
    :name => 'R',
    :script => '"$PODS_ROOT/R.swift/rswift" generate "$SRCROOT/../<PodLibraryName>/Classes/R.generated.swift"',
    :execution_position => :before_compile,
    :input_files => ["$TEMP_DIR/rswift-lastrun"],
    :output_files => ["$SRCROOT/../<PodLibraryName>/Classes/R.generated.swift"]
  }]

So how do I add the R.generated.swift file to the project?

rakuyoMo avatar Feb 15 '22 05:02 rakuyoMo

@sandeeprachha @XiMuYouZi Change the path of your output file to your Pod Library Source directory. Then when you run pod install it will be always there.

  s.script_phases = [{
    :name => 'R',
    :script => '"$PODS_ROOT/R.swift/rswift" generate "$SRCROOT/../<PodLibraryName>/Classes/R.generated.swift"',
    :execution_position => :before_compile,
    :input_files => ["$TEMP_DIR/rswift-lastrun"],
    :output_files => ["$SRCROOT/../<PodLibraryName>/Classes/R.generated.swift"]
  }]

So how do I add the R.generated.swift file to the project?

@rakuyoMo R.generated.swift file is automatically created. Also the above script takes care of moving the file to the desired location. No need to do these things manually.

PS: If you are unable to see the R file, try 'pod install' again and it will be there.

udbhateja avatar Feb 15 '22 05:02 udbhateja

@sandeeprachha @XiMuYouZi Change the path of your output file to your Pod Library Source directory. Then when you run pod install it will be always there.

  s.script_phases = [{
    :name => 'R',
    :script => '"$PODS_ROOT/R.swift/rswift" generate "$SRCROOT/../<PodLibraryName>/Classes/R.generated.swift"',
    :execution_position => :before_compile,
    :input_files => ["$TEMP_DIR/rswift-lastrun"],
    :output_files => ["$SRCROOT/../<PodLibraryName>/Classes/R.generated.swift"]
  }]

So how do I add the R.generated.swift file to the project?

@rakuyoMo R.generated.swift file is automatically created. Also the above script takes care of moving the file to the desired location. No need to do these things manually.

PS: If you are unable to see the R file, try 'pod install' again and it will be there.

I have added this script to my podspec file and when I execute the pod lib lint command, it prompts me that I cannot find the R structure.

Should I add the path to R.generated.swift to the source_files parameter? If so, is there any advantage to this way of adding scripts to the podspec file compared to directly using the R.generated.swift file generated when compiling the project?

rakuyoMo avatar Feb 15 '22 05:02 rakuyoMo

Have you added 'R' to dependencies as s.dependency = 'R' If not, add this dependency.

Should I add the path to R.generated.swift to the source_files parameter? If so, is there any advantage to this way of adding scripts to the podspec file compared to directly using the R.generated.swift file generated when compiling the project

Manually this won't work. Every time 'pod install' is run.Developer would have to manually copy-paste the file.

udbhateja avatar Feb 15 '22 08:02 udbhateja

I'm assuming this issue is resolved with the comments above. If this is still an issue, please provide more details.

tomlokhorst avatar Nov 28 '22 13:11 tomlokhorst

I am facing same problem as @rakuyoMo has described. Initially, R.generated.swift is not present at the time of running first pod install, hence it never gets added to the list of source files that are part of my development pod. The phase script from podspec file is executed after pod install, hence, even if it generates the required file and places it at the right place, it is never part of compilation. It only becomes part of compilation after second pod install (if the file was generated previously). This is a problem at CI phase.

therohansanap avatar Dec 19 '22 11:12 therohansanap

@therohansanap Right! Initially a pod install is required to generate the R.generated.swift file. Second one to add it to the bundle as mentioned in the script. Maybe some tweaks to script that copies the file after pod install is performed can help.

udbhateja avatar Dec 19 '22 12:12 udbhateja

For anyone who want to fix this for every new clone (should build at first go), I fixed this via a workaround:

  1. Add the phase script mentioned above to podspec file of MyFramework.

  2. Add a lane in Fastfile (use can use a bash script instead of fastlane lane):

lane :build_my_framework do
    cocoapods(podfile: "path/to/MyFramework/Podfile")
    build_app(
      workspace: "path/to/MyFramework/MyFramework.xcworkspace",
      configuration: "Debug",
      scheme: "MyFramework",
      clean: true,
      skip_archive: true,
      skip_codesigning: true,
      silent: true
    )
end
  1. Add a pre-install hook to Podfile
pre_install do |installer|
  exists = File.exists?('path/to/MyFramework/Resources/Generated/MyFramework.R.generated.swift')
  if exists != true
    system("bundle exec fastlane ios build_my_framework")
  end
end

I would have considered using prepare_command inside podspec file, but it does not work if the pod is integrated via :path directive.

therohansanap avatar Dec 19 '22 15:12 therohansanap

@therohansanap Thanks for this workaround. Any idea for developers not using fastlane or any other CI tool?

udbhateja avatar Dec 19 '22 18:12 udbhateja

@udbhateja fastlane was just a convenience choice for building framework project. You can use a custom shell script here instead of fastlane.

therohansanap avatar Dec 22 '22 10:12 therohansanap