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

Nested sqlite3 framework causing app store rejection #88

Closed
kklobe opened this issue Apr 9, 2015 · 15 comments
Closed

Nested sqlite3 framework causing app store rejection #88

kklobe opened this issue Apr 9, 2015 · 15 comments

Comments

@kklobe
Copy link

kklobe commented Apr 9, 2015

I'm building my app after upgrading to Xcode 6.3 GM and updating to the latest commit (fc086d0). When I try to submit a binary to the app store, I get rejected for a nested framework:

nested

@kklobe
Copy link
Author

kklobe commented Apr 9, 2015

Looks like just removing sqlite3 from Frameworks and Embed Frameworks took care of the issue. Crisis averted!

@stephencelis
Copy link
Owner

@kklobe Removing them from your target or the SQLite framework target? Does everything still function afterward?

@kklobe
Copy link
Author

kklobe commented Apr 9, 2015

From the SQLite framework target, e.g. the following diff in SQLite.swift/SQLite.xcodeproj/project.pbxproj:

34,35d33
<       DCAE4D331ABE0C2100EFCE7A /* sqlite3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCAE4D151ABE0B3300EFCE7A /* sqlite3.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
<       DCAE4D371ABE0C4C00EFCE7A /* sqlite3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DCAE4D151ABE0B3300EFCE7A /* sqlite3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
125d122
<               DCAE4D371ABE0C4C00EFCE7A /* sqlite3.framework in Embed Frameworks */,
183d179
<               DCAE4D331ABE0C2100EFCE7A /* sqlite3.framework in Frameworks */

Yep, everything seems to still works fine. Well, basic insert, update and delete anyways.

@stephencelis
Copy link
Owner

Test a clean (kill your derived data) and clean install on device to be safe. It's easy to get linker errors with nested frameworks, but there's no good alternative till Apple includes a module map for libsqlite3.

@kklobe
Copy link
Author

kklobe commented Apr 9, 2015

I cracked open the .IPA from both builds (wiping DerivedData between builds), and the working/accepted one definitely had no nested sqlite3 framework.

@stephencelis
Copy link
Owner

I'm just wondering how it could possibly work if that's the case. The first query should crash the app. If it works, though, that's good to hear. Keep me posted if you have problems. I may have to bring back my bridging header hack.

@kklobe
Copy link
Author

kklobe commented Apr 9, 2015

I haven't worked at all with modules/embedded frameworks, so I haven't been able to figure out exactly what problem sqlite3 as a framework is designed to solve. What is contained in that embedded 108k sqlite3 file I see in my original rejected .IPA? Is it just the libsqlite3.dylib repackaged?

@stephencelis
Copy link
Owner

OS X and iOS don't currently ship with module maps that point to system headers for common libraries like SQLite3 (/usr/include/sqlite3.h) and CommonCrypto (/usr/include/CommonCrypto/CommonCrypto.h). There are open bug reports with Apple, so hopefully this will be rectified in an upcoming beta.

Meanwhile, framework targets:

  • cannot import non-modular headers into their umbrella headers (i.e., anything outside of the framework)
  • don't support bridging headers (an earlier version of SQLite.swift relied on a hack that let this happen, but Apple says that framework bridging headers are fragile, and I want to avoid it if possible)
  • can't include private Objective-C code (all code made available to Swift must be a public header that's imported in the umbrella header)

The embedded sqlite3 framework is a "dummy" module that tries to address (most of) the above. It allows the SQLite framework to import the system libsqlite3 library into Swift transparently.

Workarounds that other libraries use:

  • Manually requiring the framework consumer to update their own target build settings to point to the same module map used by the framework.
  • Copying the source files into your target (basically: not using a framework).

The embedded framework was the cleanest, seemingly valid solution I could come up with, but because it possibly causes linker issues, I may have to rethink things and go back to the bridging header hack.

Alternatively, I may have to add a build script that copies the appropriate system header into the framework.

@kklobe
Copy link
Author

kklobe commented Apr 9, 2015

Thanks for the explanation! So, a couple more questions:

My app is clearly running just fine. The only change I've made to the SQLite project was the removal of sqlite3. Is the runtime dependency handled by having libsqlite3.dylib in "Linked Frameworks and Libraries"?

In other words, is the embedded sqlite3 target really only required for compilation?

@stephencelis
Copy link
Owner

@kklobe I believe so. I'll have to do some testing locally. Thanks for the heads-up!

@BenoitCaron
Copy link

Hi,
Same problem here. I included your framework into a framework of mine, and getting the same ITMS-90205 and ITMS-90206 errors. I couldn't solve it though :/

@stephencelis
Copy link
Owner

@Nexus45 Did you try @kklobe's solution, diffed above? I'm in the process of traveling so I don't have the bandwidth to test everything right now, but will give things a whirl soon.

@stephencelis
Copy link
Owner

(Butterfingers.)

@BenoitCaron
Copy link

I managed to pass the submission step. I did the same as @kklobe, and also had to remove SQLite from Linked Frameworks and Libraries in the General tab of my frameworks.
Works like a charm now.

@stephencelis
Copy link
Owner

Great! I'll try to get the fix in after testing it soon.

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

3 participants