Post

Replies

Boosts

Views

Activity

Reply to Awaiting a reply in Resolution Center — Guideline 4.3(a) on an app we built ourselves
The strongest sentence in your post is currently the weakest evidence: "that core is the largest part of the compiled binary". You can turn that from a belief into a number, and a number is much harder to set aside than an explanation. For a Flutter iOS build the compiled code splits into three pieces you can size independently: Runner (your Swift, including the tunnel host and the Network Extension) Flutter.framework, plus your Dart AOT snapshot inside App.framework the statically linked proxy core Build with a link map (Other Linker Flags: -map $(TARGET_TEMP_DIR)/link.map), then total the __TEXT,__text bytes per object file and group them by the static archive they came from. size -m -x on each Mach-O in the .app, plus the framework sizes, gets you most of the way there on its own. What you want at the end is one sentence of the form: N% of the executable's code section comes from , M% is Dart snapshot, and the remainder is code we wrote. If you also pin the vendored core to a specific public commit and say so, the claim stops being "we did not copy anyone" and becomes "the bytes that match are upstream commit of , which every client in this category links identically, and here is the share of the binary they account for". That is a claim a reviewer can check without taking your word for anything, and it is aimed at the actual signal, which is a binary match rather than authorship. Your offer of the repository and commit history proves you wrote your code; it does not address why two binaries look alike, and those are different questions. Two smaller things. The 187 tests and 32 languages are real work but they are not responsive to a binary-similarity finding, so I would keep the reply narrow. And the empty-server-list, bring-your-own-configuration point is worth stating as an observable fact about the reviewed build — what the app does on first launch with no configuration supplied — rather than as a description of your business model. Asking which app or account the similarity was matched against is the right question and I would keep it as the only question. I had twelve updates come back under 4.3(a) in one batch two nights ago on the generic body, and I asked essentially the same thing after measuring my own side first: 1030 Swift files across the twelve apps, zero byte-identical pairs. The measurement did not win an argument, but it did stop me from rewriting code that was never the problem, and it made the reply short. Write-up of that measurement, if any of it transfers: https://thechosenvictor.com/blog/twelve-apps-rejected-guideline-4-3a-spam
3w
Reply to Guideline 4.3(a): 5 rejections despite major code and content changes
The thing you flagged as confusing is, I think, the most important detail in your post: the number stayed at 4.3(a) but the body changed. Attempts 1 to 4 were about a binary match. Attempt 5 is about "concept and look" in a saturated category. Those are two different findings with two different fix surfaces, and almost everything you did between attempt 2 and attempt 5 — refactor, rename, reorganise assemblies, obfuscate — was aimed at the first one. On the binary side, it is worth turning "I changed the code" into a number before changing any more of it. In a Unity IL2CPP build, your own scripts are usually a small fraction of the compiled code; the engine, the ad SDKs and the third-party libraries are the bulk, and those are exactly what the reviewer named on your call. You can measure the split rather than guess at it: Build with a link map (Other Linker Flags: -map $(TARGET_TEMP_DIR)/link.map), then total the __TEXT,__text bytes per object file and group them by static archive. Or run size -m -x on the built executable and list the embedded frameworks in the .app with their sizes. If your own game scripts turn out to be a single-digit percentage of the code section, then "change the code" was never able to move a binary-similarity signal, because the part that matches is the part every game in the genre links. That is a measurement you can state in Resolution Center without arguing with anyone. Obfuscation, incidentally, does not help here and makes the build harder to explain — it does not touch the engine or SDK code at all. On the attempt 5 body, "concept and look" is not about your source at all. It is what someone sees scanning a category page: icon, the first two screenshots, name and subtitle, and the first few seconds of the preview video. Hundreds of custom scripts and a custom physics engine are real work, and none of it is visible at that distance. If the latest message is the live one, that is the surface I would go and diff against the handful of comparable games you named — not the codebase. For what it is worth on the general shape: I had twelve updates come back under 4.3(a) in one batch two nights ago with the generic body. I measured the accusation instead of answering it, and the source side did not hold up as a story — 1030 Swift files across the twelve, zero byte-identical pairs, and SettingsView.swift averaging 3.9% similarity across the 11 apps that have one. What was genuinely uniform was metadata: release notes at 46.3% mean similarity, which I rewrote to 15.4%. Different situation from yours, but the same lesson — the measurable thing was not where I assumed it was. Since your appeal has already been decided, Resolution Center is the channel you have left, and I would ask one precise question there rather than resubmit: whether the current finding is the binary match from attempts 1 to 4 or the concept-and-look finding from attempt 5. You are currently paying to fix both. Longer write-up of the measurement, if it is useful: https://thechosenvictor.com/blog/twelve-apps-rejected-guideline-4-3a-spam
3w
Reply to Rejected for Guideline 4.3(a) - Spam, looking for advice on next steps
I got the same body on twelve updates in one batch two nights ago, so I have my own measurements rather than an answer from Apple. Two things narrowed it down faster than anything else I tried. First, read the body rather than the number. Apple's published text for 4.3(a) is about multiple Bundle IDs of the same app — the "a separate map app for every city" example. The sentence you quoted, about a similar binary, metadata and/or concept as apps already on the store, is the substance of 4.3(b). Those point at two different things: 4.3(a) is a question about your own catalogue, 4.3(b) is a question about how your app reads next to what is already there. I would not raise that as a gotcha, but it does tell you which side to go and measure. Second, measure your own side before you ask anything. It is cheap and it shrinks the surface fast: Byte-compare every source file against every other app you ship. shasum every file, then look for collisions. I expected to find shared files and found none: 1030 Swift files across the twelve apps, zero byte-identical pairs in either direction. That rules out "same binary repackaged" as a source-tree story and pushes the question to presentation. Then compare the same files by content, not just by hash. Shared filenames are not shared code. SettingsView.swift appears in 11 of my apps and averages 3.9% similarity (difflib.SequenceMatcher over comment-stripped, whitespace-normalised lines). Worth knowing before you start rewriting code that was never the problem. Diff your metadata. This is where mine actually was. Descriptions came out at 5.3% mean similarity across all 66 pairs and promotional text at 8.1%, both fine — but the release notes on the exact versions under review were 46.3% mean, 90.9% max, with eight of twelve opening on the identical sentence. I rewrote them to 15.4% mean, 42.3% max. Look at submission cadence. All twelve of mine went up inside ninety minutes from one API key. Nothing about that breaks a rule, but it reads like one template fired repeatedly, and that is a portfolio-level impression rather than an app-level one. On clarifying with the team: Apple's own guidance is Resolution Center before an appeal, and you get one appeal per rejection, so I would not spend it before they have said something specific. I replied once, on one app rather than on all twelve, stated the measurements, and asked two questions — which app they meant, and whether the concern is between my own apps or against another developer's. Still waiting on that. On the App Review appointment, I have not had one. There is a thread on this forum from a developer who did, and was told the match was against another developer's game in the same genre, with engine code, ad SDKs and third-party libraries all named as possible sources. So the call gave them the class of match but not the specific app. Worth knowing before you book one. If the detail is useful, I wrote the whole measurement up here: https://thechosenvictor.com/blog/twelve-apps-rejected-guideline-4-3a-spam
3w
Reply to Awaiting a reply in Resolution Center — Guideline 4.3(a) on an app we built ourselves
The strongest sentence in your post is currently the weakest evidence: "that core is the largest part of the compiled binary". You can turn that from a belief into a number, and a number is much harder to set aside than an explanation. For a Flutter iOS build the compiled code splits into three pieces you can size independently: Runner (your Swift, including the tunnel host and the Network Extension) Flutter.framework, plus your Dart AOT snapshot inside App.framework the statically linked proxy core Build with a link map (Other Linker Flags: -map $(TARGET_TEMP_DIR)/link.map), then total the __TEXT,__text bytes per object file and group them by the static archive they came from. size -m -x on each Mach-O in the .app, plus the framework sizes, gets you most of the way there on its own. What you want at the end is one sentence of the form: N% of the executable's code section comes from , M% is Dart snapshot, and the remainder is code we wrote. If you also pin the vendored core to a specific public commit and say so, the claim stops being "we did not copy anyone" and becomes "the bytes that match are upstream commit of , which every client in this category links identically, and here is the share of the binary they account for". That is a claim a reviewer can check without taking your word for anything, and it is aimed at the actual signal, which is a binary match rather than authorship. Your offer of the repository and commit history proves you wrote your code; it does not address why two binaries look alike, and those are different questions. Two smaller things. The 187 tests and 32 languages are real work but they are not responsive to a binary-similarity finding, so I would keep the reply narrow. And the empty-server-list, bring-your-own-configuration point is worth stating as an observable fact about the reviewed build — what the app does on first launch with no configuration supplied — rather than as a description of your business model. Asking which app or account the similarity was matched against is the right question and I would keep it as the only question. I had twelve updates come back under 4.3(a) in one batch two nights ago on the generic body, and I asked essentially the same thing after measuring my own side first: 1030 Swift files across the twelve apps, zero byte-identical pairs. The measurement did not win an argument, but it did stop me from rewriting code that was never the problem, and it made the reply short. Write-up of that measurement, if any of it transfers: https://thechosenvictor.com/blog/twelve-apps-rejected-guideline-4-3a-spam
Replies
Boosts
Views
Activity
3w
Reply to Guideline 4.3(a): 5 rejections despite major code and content changes
The thing you flagged as confusing is, I think, the most important detail in your post: the number stayed at 4.3(a) but the body changed. Attempts 1 to 4 were about a binary match. Attempt 5 is about "concept and look" in a saturated category. Those are two different findings with two different fix surfaces, and almost everything you did between attempt 2 and attempt 5 — refactor, rename, reorganise assemblies, obfuscate — was aimed at the first one. On the binary side, it is worth turning "I changed the code" into a number before changing any more of it. In a Unity IL2CPP build, your own scripts are usually a small fraction of the compiled code; the engine, the ad SDKs and the third-party libraries are the bulk, and those are exactly what the reviewer named on your call. You can measure the split rather than guess at it: Build with a link map (Other Linker Flags: -map $(TARGET_TEMP_DIR)/link.map), then total the __TEXT,__text bytes per object file and group them by static archive. Or run size -m -x on the built executable and list the embedded frameworks in the .app with their sizes. If your own game scripts turn out to be a single-digit percentage of the code section, then "change the code" was never able to move a binary-similarity signal, because the part that matches is the part every game in the genre links. That is a measurement you can state in Resolution Center without arguing with anyone. Obfuscation, incidentally, does not help here and makes the build harder to explain — it does not touch the engine or SDK code at all. On the attempt 5 body, "concept and look" is not about your source at all. It is what someone sees scanning a category page: icon, the first two screenshots, name and subtitle, and the first few seconds of the preview video. Hundreds of custom scripts and a custom physics engine are real work, and none of it is visible at that distance. If the latest message is the live one, that is the surface I would go and diff against the handful of comparable games you named — not the codebase. For what it is worth on the general shape: I had twelve updates come back under 4.3(a) in one batch two nights ago with the generic body. I measured the accusation instead of answering it, and the source side did not hold up as a story — 1030 Swift files across the twelve, zero byte-identical pairs, and SettingsView.swift averaging 3.9% similarity across the 11 apps that have one. What was genuinely uniform was metadata: release notes at 46.3% mean similarity, which I rewrote to 15.4%. Different situation from yours, but the same lesson — the measurable thing was not where I assumed it was. Since your appeal has already been decided, Resolution Center is the channel you have left, and I would ask one precise question there rather than resubmit: whether the current finding is the binary match from attempts 1 to 4 or the concept-and-look finding from attempt 5. You are currently paying to fix both. Longer write-up of the measurement, if it is useful: https://thechosenvictor.com/blog/twelve-apps-rejected-guideline-4-3a-spam
Replies
Boosts
Views
Activity
3w
Reply to Rejected for Guideline 4.3(a) - Spam, looking for advice on next steps
I got the same body on twelve updates in one batch two nights ago, so I have my own measurements rather than an answer from Apple. Two things narrowed it down faster than anything else I tried. First, read the body rather than the number. Apple's published text for 4.3(a) is about multiple Bundle IDs of the same app — the "a separate map app for every city" example. The sentence you quoted, about a similar binary, metadata and/or concept as apps already on the store, is the substance of 4.3(b). Those point at two different things: 4.3(a) is a question about your own catalogue, 4.3(b) is a question about how your app reads next to what is already there. I would not raise that as a gotcha, but it does tell you which side to go and measure. Second, measure your own side before you ask anything. It is cheap and it shrinks the surface fast: Byte-compare every source file against every other app you ship. shasum every file, then look for collisions. I expected to find shared files and found none: 1030 Swift files across the twelve apps, zero byte-identical pairs in either direction. That rules out "same binary repackaged" as a source-tree story and pushes the question to presentation. Then compare the same files by content, not just by hash. Shared filenames are not shared code. SettingsView.swift appears in 11 of my apps and averages 3.9% similarity (difflib.SequenceMatcher over comment-stripped, whitespace-normalised lines). Worth knowing before you start rewriting code that was never the problem. Diff your metadata. This is where mine actually was. Descriptions came out at 5.3% mean similarity across all 66 pairs and promotional text at 8.1%, both fine — but the release notes on the exact versions under review were 46.3% mean, 90.9% max, with eight of twelve opening on the identical sentence. I rewrote them to 15.4% mean, 42.3% max. Look at submission cadence. All twelve of mine went up inside ninety minutes from one API key. Nothing about that breaks a rule, but it reads like one template fired repeatedly, and that is a portfolio-level impression rather than an app-level one. On clarifying with the team: Apple's own guidance is Resolution Center before an appeal, and you get one appeal per rejection, so I would not spend it before they have said something specific. I replied once, on one app rather than on all twelve, stated the measurements, and asked two questions — which app they meant, and whether the concern is between my own apps or against another developer's. Still waiting on that. On the App Review appointment, I have not had one. There is a thread on this forum from a developer who did, and was told the match was against another developer's game in the same genre, with engine code, ad SDKs and third-party libraries all named as possible sources. So the call gave them the class of match but not the specific app. Worth knowing before you book one. If the detail is useful, I wrote the whole measurement up here: https://thechosenvictor.com/blog/twelve-apps-rejected-guideline-4-3a-spam
Replies
Boosts
Views
Activity
3w