I maintain my 3rd party libs with cocoapods. But recently I found some bugs and would like to add some new features to one of the libs so I manually created some .h and .m files in one of the libs.
However when importing those added .h files, Xcode gave the file not found error and couldn't compile them.
How can I solve the problem?
Thanks.
When integrating the Pods into your project, CocoaPods generates libraries that cannot be easily modified from Xcode. If you're having CocoaPods build frameworks, instead, those cannot be modified at all. You usually have to rerun pod install or pod update to let CocoaPods regenerate them if you add files to a Pod.
If you want to reliably add files to a Pod, you should checkout a copy on your machine, somewhere NOT in you project's folder and use something like the following to tell CocoaPods that that one Pod is one you're developing and therefore should integrate differently:
pod MyPod, :path => 'path/to/MyPod.podspec'
Still, even in this case, if you add files to the Pod, although it's easier to add them from Xcode, you might want to rerun the pod command line tool to have CocoaPods reintegrate your pod. However, in this case, you'll only have to make sure your files are added to the right project target in order to add files directly from Xcode.
Related
I am new to CocoaPod and IOS in general, I am trying to use a framework I built locally in my podfile as follows:
# Pods for Example
pod 'OsonWidget', :path => "../OsonWidget/"
when I run a pod install and open the .xcworkspace of the project, the framework gets saved under Pods/Development pods. So my question is what is Development pods
Normally in Podfile you point to the repo with its git name and your intended version.
You’re not doing that. Instead you are pointing to the pod by the :path identifier in the Podfile.
Other than the two ways mentioned above, there are other ways to point to a repo.
Obviously you are locally pointing to a pod, ie the pod was not fetched from the actual repo, implying that you own the pod and you’re developing the pod, you want to make changes to it and immediately see how the changes work for you in your Example app. Hence it’s named ‘development pods’.
Any change you make will be reflected into the Example project. Though if you add a new file, then you need to run pod install again so the projectfile gets updated.
This is slightly different from other dependency managers where the term 'development' is used for dependencies that are necessary for testing, benchmarking, and other developer tasks. Example with Ruby Gems, you have add_development_dependency vs. add_runtime_dependency
With CocoaPods the decision to use something as development vs. deployment is per file i.e. whether or not a pod/framework imports a file.
This all means you could have a file in your test target i.e. only import the pod in your test target and never include it in production e.g. the KIF pods. But mainly if you import a pod in your production code, then you'd need to import it again in files you have under you unit test target.
I did some digging on cocoapods.org, and found this snippet:
Development Pods are different from normal CocoaPods in that they are symlinked files, so making edits to them will change the original files, so you can work on your library from inside Xcode. Your demo & tests will need to include references to headers using the #import <MyLib/XYZ.h> format.
https://guides.cocoapods.org/making/using-pod-lib-create
I'm trying to create a Cocoa Touch Framework.
I created a Cocoa Touch Framework
I ran pod init
I added our own CocoaPod to this, which has some dependencies itself as well.
I ran pod install.
Now when I try to build the framework (I open the .xcodeproj) I get the following warnings for each dependency.
ld: warning: directory not found for option '-F/Users/jeroen/Library/Developer/Xcode/DerivedData/OurFramework-culynvrparvtfjbjlitmammotpkf/Build/Products/Debug-iphoneos/Alamofire'
I get the following errors:
ld: framework not found Alamofire
error: Resource "/Users/jeroen/Library/Developer/Xcode/DerivedData/OurFramework-culynvrparvtfjbjlitmammotpkf/Build/Products/Debug-iphoneos/FirebaseFirestore/gRPCCertificates-Firestore.bundle" not found. Run 'pod install' to update the copy resources script.
I expect that this is because the CocoaPod files are not copied to the right place. Is that correct?
What could I do to make this work anyway?
The reason I want to do this is the following:
I have a CocoaPods project which is a regular Xcode project with only Swift classes and some view controllers. We want to make this available as closed source. So I'm hoping that including this pod in a Cocoa Touch Framework would still make all public functions of its pods available to the user.
If there are other suggestions, they are welcome!
Thanks in advance.
The first point I got is you used .xcodeproj after pod installation. Please note that once you install pods there is one more file is created with an extension .xcworkspace you need to use this file to open project and your future work should be done in this file.
Okay, so all the problems I had with setting this up seemed to be Xcode-related.
Basically what I did to get this working is the following:
Create a Cocoa Touch Framework through Xcode's File > New > Project ....
Using terminal, navigate to the framework's root folder (the folder with the YourFramework.xcodeproj-file).
Run pod init.
Add the necessary CocoaPods to the Podfile.
Run pod install.
Make sure you close the YourFramework-project that's probably open in Xcode.
From here on my problems started occurring. Opening the YourFramework.xcworkspace worked, but in the left-side navigator of Xcode, I could only expand the Pods-project, not the Framework-project; it seemed to be empty. Building didn't work either.
To solve this (So, just the regular steps to solve Xcode problems):
Close Xcode.
Delete derived data.
Open the YourFramework.xcworkspace again.
Clean the build folder.
Now it maybe builds, or not. In my case it didn't and got 100s of problems related to the Swift language being unavailable. I created a framework without any source files, just imported CocoaPods. To solve this create a Swift file in the framework which imports at least Foundation.
Now it should build.
I'm creating a private pod and would like it to be used as a module. According to Using Pod Lib Create, in CocoaPods.org:
The first question you're asked is what language you want to build a pod in. For both choices CocoaPods will set up your library as a framework.
In fact, when I run pod lib create MyLibrary, the initial project template they generate does have everything configured to be a framework, so that I can add a class to Development Pods/MyLibrary, and access methods of that class from the sample project simply by importing the module using #import MyLibrary; (or import MyLibrary, in Swift).
The problem lies on the fact that the same page tells us
With the questions over, we run pod install on the newly created Project.
And as soon as I do that, the module-related files are gone, and all the files that I had added to my Development Pods folders are gone. Not only that, the framework Target itself is gone, so it's not even a matter of simply adding the files back again.
What's the correct approach here? I don't seem to find anyone with the same problem.
I'm running Cocoapod v1.5.3
Any help is highly appreciated!
tl;dr:
pod lib create MyLibrary
cd MyLibrary/Example
pod install
Now notice that the project has no module configuration anymore. How can I avoid this?
According to the same page:
[!] Note: Due to a Development Pods implementation detail, when you
add new/existing files to Pod/Classes or Pod/Assets or update your
podspec, you should run pod install or pod update.
In my experience, you have to be very careful when adding new files because they may end up on a different folder than the expected Pods/Classes.
When in doubt, I go to the folder containing the project and search for the missing file and move it to the correct folder.
What's super important is that when you run pod install CocoaPods will look into your PodSpec and only install files that match the source_files criteria mentioned in the PodSpec i.e. the files need to be
correct extension
correct path.
But basically you have to add the file to the exact directory you want. If you're using groups it gets messed up. So instead of adding a new file using Xcode, just add the new file using Finder and then run pod install.
Not sure why but if I add to the same group that has a similar file at the appropriate directory, Xcode and CocoaPods will just put the file at the top directory.
On a complete tangent:
If you've been pointing locally to to your private pod using :path and then add new files into your private pod, those new files aren't reflect in the repo that pull in the private pod. They'r not reflected because their source control is from another git repo.
As long as you see the new file of your private pod in your main app and your main app compiles then you're good.
I'm creating a CocoaPod, say MyPod, which depends on another Cocoapod, say RxSwift.
So I have this in MyPod.podspec:
s.dependency "RxSwift", "~> 3.0.1"
However, while developing MyPod, how can I actually use the dependency?
import RxSwift
// ^
// No such module 'RxSwift'
public class MyClass { //...
Is there a step I'm missing, or some common convention? It looks like some other projects like Moya are using Carthage to build dependencies while developing. Should I be doing that, or maybe adding a Podfile?
I know that this shouldn't be a problem for an Example App located within the repo, which would have its own Podfile. However, I'd like to still have tests located at top level, outside of the Example App, and to be able to actually build the framework while working on it, again, outside of an Example App.
I can't speak to whether or not to use CocoaPods or Carthage. Both have their strong points and weak points. Plus the decision should be made considering many factors, some of which you might not be able to control (like a client that insists you use CocoaPods!) So I'll skip that part.
However, to your question, indeed a pod you are developing can depend on another pod. You already have the correct s.dependency line. That's necessary.
However, I suspect that the reason why you were not able to reference the dependent pod could be because you did not have a Podfile in your 'tester/example' project and/or you did not do a pod install after adding the dependency in your Podspec.
The reason for this is requirement I suspect is that since the Podspec is not actually processed at all by Xcode, you're not actually downloading (or compiling) the dependency.
Instead, when you do the pod install (via command line of course), CocoaPods will create a Pods project with your development pod, the pods you depend on (in Podspec) as well as any other pods in your Podfile.
To test this theory, I:
Created a new pod (using CocoaPod's own 'pod lib create' (https://guides.cocoapods.org/making/using-pod-lib-create.html).
Opened the workspace that CocoaPod created for me and edited the Podspec to add the dependency s.dependency 'RxSwift', '~> 3.0.1'.
Added another pod in my Example App's Podfile (to demonstrate the difference between Podfile dependencies and Podspec dependencies.)
Performed pod install in the Example App's folder.
Edited my Pod's class to do something useful AND to add the import RxSwift line.
Added a label to my Example App ("Hello World" of course).
Used PureLayout to do all the auto layout constraints for the label (and to demonstrate how the Example project has access to both pods - the development pod as well as the referenced pod PureLayout.)
You can check out the demo I created on my public GitHub:
https://github.com/ericwastaken/CocoaPod-Dependency-Demo
Honestly, I've created several pods using the pod lib create and it does indeed create a nice structure that has always worked for me. For this reason, I would recommend always using it to create your pod's skeleton.
Xcode 8 comment: pod lib create still seems to create a Swift 1.x project. So, right after you use this tool, when you open Xcode, you'll be offered to "convert" to a newer version of Swift. I would let that conversion happen right then and there (the first time) so that you can be in Swift 2.x or 3.x syntax (you choose).
I ended up using Carthage to build the framework dependencies. I imagine I could have used CocoaPods to do it as well. However, that would have required that I start using a workspace, and I didn't want to have to do that so as to keep changes as minimal as possible.
Also, with Carthage, it didn't require that I add a new Podfile/Podfile.lock, since Carthage will use the existing Cartfile/Cartfile.resolved that's already there. That's because Carthage uses the Cartfile.resolved when using the framework in another project and when building the framework on its own. Whereas, with CocoaPods, *.podspec is used when using the framework in another project but Podfile.lock (if you've added a Podfile) is required to install dependent pods in the framework itself.
This was a very challenging problem to solve, and required a combination of a few solutions pieced together. #EricWasTaken's solution helped, as well as adding:
source 'https://github.com/CocoaPods/Specs.git'
to the top of my Podfile. Then navigating to the Example app and run
pod repo update
pod install
Now the framework I am creating can find the cocoapods my framework requires.
I downloaded a zip of my own project from github but keep running into an error on building it. 2 out of 5 libraries I installed using cocoapods, though present in the pods folder, aren't identified by Xcode, specifically, SDWebImage and YTPlayerView.
Can anyone tell me how to fix this?
As intboolstring said, ensure you run pod install inside the directory of the project you have downloaded, however what I have found is that you should also build the project after running pod install, as it sometimes does not link the pods to the project. Do this using the .xcworkspace file.
When downloading a git project, the project comes with the Podspec file, which specifies which dependencies need to be downloaded. To download the required dependencies for your project, you can run
pod install
Also, to make sure that the dependencies are loaded, open the .xcworkspace file. If you can't find the workspace, you can go to your project directory and run
open `ls | grep xcworkspace`
I fixed the problem with the pods. Adding import pod name to the affected classes fixed it.
For some reason, the local copy of the app works fine, even without said import statements.