[NSBundle allBundles] returns incorrect bundle list.
| Originator: | d4rkf1br3 | ||
| Number: | rdar://29173153 | Date Originated: | 9/11/2016 |
| Status: | Open | Resolved: | |
| Product: | iOS SDK | Product Version: | 10.1 |
| Classification: | Serious bug | Reproducible: | Always |
Summary: I have an API than needs to scan all the frameworks in an app. The previous version of my code used NSBundle.allBundles to get a list of frameworks which it would then loop through, retrieving the class list for each one via objc_copyClassNamesForImage(const char *image, int *count). After updating to the latest iOS beta, my API stopped working. After much testing I found that NSBundle.allBundles is returning a list of all the bundles for the app, however these are not necessarily the bundles that the app has loaded. Therefore when objc_copyClassNamesForImage(...) was called, it was returning o classes. When running on a device I found that the bundles are sourced from a /private/... directory. When running in a simulator with a workspace with framework projects imported into the workspace, I found that the loaded bundles are coming from the derived data product path rather than the app's simulator installation path. In both of these cases NSBundle.allBundles still returns the bundles from within the app bundle's ./Frameworks directory even though they are not loaded. I managed to fix this problem by switching my code from NSBundle.allBundles to Core Foundaton's CFBundleGetAllBundles(). Although the API documentation suggests that both NSBundle.allBundles and CFBundleGetAllBundles() should return the same results, CFBundleGetAllBundles() actually returns the bundle that the app has loaded as opposed to the bundles from the app's bundle. Obivously these are coming from different locations. Steps to Reproduce: 1. Build an app that has two (or more) (non-system) frameworks included. 2. Make sure both frameworks are copied to the app's /Framework directory during the build. 3. In the Xcode project, add the source project for one of the bundles so you can see the difference in locations. 4. Add code to the app to get a list of bundles from NSBundle.allBundles and CFBundleGetAllBundles. 5. Compare the results. Expected Results: Both lists of bundles should be identical and show the loaded frameworks for the app. Actual Results: Only the system (Apple's) frameworks will be consistent. The 3rd party framework copied in the build will have a different location. As will the framework whose source code project is included in the workspace. Version: Version 8.2 beta (8C23) Notes: Configuration: MBP. Xcode 8.2 Attachments:
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!