Last Week
Last week was the moment the launch stopped being theoretical. Google granted Android production access, the public listing went live, and I started thinking much more seriously about the work that happens after shipping: better screenshots, better copy, better trust signals, and a clearer path from “the app exists” to “a real business can picture using it.” The iOS production submission was also in Apple’s hands, and I expected that side to be more demanding even if I could not yet see which part would trigger the first problem.
This week delivered the answer. Apple rejected the first submission, but not because the app was crashing or because the core product was fundamentally broken. The rejection was about store-readiness interpretation: first, Apple wanted more explanation of the business model and where paid access can be purchased, and second, my privacy/data-use declaration described future marketing ambitions instead of the app’s current behavior. I fixed the disclosures, sent the response back, and then shifted part of my attention into a much more enjoyable problem: adding restaurant menus to the guest waiting experience so diners can decide faster and order sooner once seated.
Rejected, But In A Useful Way
The theme this week is Apple’s first rejection, and weirdly enough I do not consider that bad news.
I expected the first iOS production submission to come back with questions. Apple took a few days to move the app into review, then rejected it within hours. That sounds dramatic until you remember what store review actually is. It is not just a binary check for “does the app run?” It is also a structured negotiation over how the product makes money, what data it collects, how that data is used, and whether the words in the submission match the software that actually ships.
The two issues Apple raised were both annoying, but they were also clarifying. The first was basically a business-model question: who buys this, who pays for the subscription, and where can that purchase happen? The second was a privacy declaration problem that I created myself by being too aspirational in the submission. I described what I might eventually want to do with user email addresses instead of what the app does today, and Apple quite reasonably treated that as a present-day marketing use case.
So the practical result of this week is that the app is back in Apple’s court, and I am better educated about the difference between “future plan” and “current disclosure.” That would have been enough material for one week already, but I also used the frustration productively by moving into the next feature: letting restaurant hosts attach menu information to the guest-side waiting flow. If the waitlist is supposed to reduce friction, then the obvious next step is helping hungry people decide earlier so the time between seating and ordering gets shorter.
What does it mean in English?
Apple did not reject the app because Shokken is unsafe or because the product idea does not make sense. Apple rejected the first submission because it wanted clearer answers about how the paid version works and because my privacy paperwork implied a marketing system that the app does not currently have.
That matters because the lesson is broader than this one release. When you submit software to a store, you are not only shipping code. You are shipping a legal and business description of the code. If that description gets ahead of reality, even in a well-intentioned way, you create extra work for yourself.
The more interesting product work this week was the new menu feature. The idea is simple: if guests can view a restaurant’s menu while they are already waiting, some of them will be ready to order almost immediately after they sit down. That does not help every diner, but for busy restaurants it can reduce one more chunk of dead time in the table-turn cycle.
Nerdy Details
Store review is part policy audit, part product interview
The first useful lesson from this week is that app-store review should not be thought of as a glorified QA pass.
Google and Apple are both reviewing a piece of software, but they are not reviewing it in the same way. Google approved my Android production access without much drama. Apple came back with questions that were only partially about the software itself. The rest were about the commercial and compliance frame around the software.
That distinction matters because it changes what “ready” means. A feature can be implemented correctly and still be submission-incomplete. A pricing model can be technically functional and still be under-explained. A privacy inventory can be honest and still be phrased in a way that creates obligations you do not yet want to assume. That is the real shape of store readiness.
So I do not interpret this week’s rejection as “Apple found the fatal flaw.” I interpret it as “Apple started the real conversation.” In hindsight, that is obvious. The store is not just hosting binaries. It is hosting a commercial relationship. Of course the platform owner cares about how a user pays, what the user is told, and what data flows through the system.
Issue one was not code, it was business-model clarity
Apple’s first issue fell under the generic “information needed” bucket, which sounds harmless until you realize it can block the release just as effectively as a crash.
The question, paraphrased, was: who is paying for this app, and where can the paid service be purchased? That seems straightforward at first. Shokken has a free tier for the QR waitlist flow, and the paid layer is tied to the more expensive messaging functionality. The part that makes it messy is that this is a cross-platform app.
My understanding of the rules is that if I sell access inside the iOS app, I need to offer Apple’s in-app purchase path there as well. That part is not controversial. Apple takes its cut, and that is the price of access to the platform. The confusing part is what happens once the same account can exist on Android, on iOS, and potentially on the web. If a user buys access on Android and then logs into iOS, the entitlement still exists. If a user eventually buys from the website, the same account should still work inside the app.
That is what made the phrasing of Apple’s question feel strange to me. I was not trying to bypass the rule that iOS purchases must be offered through iOS. I was trying to understand why Apple needed a broader explanation of all the places the service could be purchased if the iOS path was already going to be compliant.
In practice, though, it does not matter whether I find the question elegant. What matters is whether I can answer it clearly. So I did. I wrote the response, clarified the model, and sent it back. That is a useful mental shift: in store review, “this question is slightly awkward” is not a productive reaction. “How do I reduce ambiguity for the reviewer?” is the productive one.
Issue two was self-inflicted: I described the future instead of the present
The second issue was the more educational one.
When you submit an app to Apple, you provide a fairly detailed inventory of the data the app collects and the reasons it collects it. Phone number? Explain why. Email address? Explain why. Any activity tracking? Explain why. GPS? Explain why. The system is tedious, but it is also fair: if you gather data from users, you should be able to justify it concretely.
Where I got myself into trouble was not with the inventory of fields. It was with the declared purpose.
Today, the app uses collected data for product functionality. The phone number exists so a guest can be contacted when their table is ready. The email address exists because user accounts need identity. That is the current state of the software. But when I filled out the submission, I let my future plans bleed into the current declaration. I thought ahead to the possibility of eventually emailing users about new features or releases, and I classified the email address in a way that implied present-day marketing use.
That single declaration changed the compliance surface immediately. Once I said the app used data for marketing purposes, Apple treated the app as if it needed App Tracking Transparency support. In other words, by describing a future-state marketing system that does not yet exist, I accidentally volunteered the app for a present-day requirement that I did not actually need.
That is a painfully useful lesson. Compliance forms are not the place to describe ambition. They are the place to describe the software that exists right now. If the current app does not perform marketing tracking, then the declaration should say exactly that. If someday it does, then that is the moment to expand the disclosure and implement the additional requirements that come with it.
So the fix was simple in concept, even if irritating in practice: go back to the submission, describe the current app honestly, remove the imaginary future marketing behavior from the declaration, and resubmit.
The review loop is incremental, not exhaustive
Another useful thing I learned is that Apple does not necessarily hand you the complete list of problems in one pass.
The review process appears to stop at the first blocking issues. That means a rejection is not always a full inventory of everything that still needs work. It is often just the first set of blockers the reviewer hit before stopping the pass and sending the app back to you.
That is important because it changes how I should plan time around store release. I cannot assume that “I answered the first rejection” means “I am done.” It may simply mean I am ready for the next round of questions. I hope this resubmission clears the remaining hurdles, but I would not bet on that yet.
The right mindset is iterative compliance. Fix the current blockers. Resubmit. See what the next pass reveals. Treat the review queue as part of the delivery timeline rather than as a one-shot ceremony that happens after the real work is done.
The actual feature work this week was much more fun
After spending enough time on Apple paperwork, I wanted to work on something that was unmistakably product.
So I moved into the next feature: letting restaurant hosts provide menu information inside the guest waiting flow.
The use case is simple. A guest joins the waitlist, then waits. Right now, waiting usually means staring at a queue estimate, walking around, or killing time on their phone. But for restaurants specifically, waiting time can be more valuable than that. It can be decision time.
If a guest can browse the menu while they wait, they can begin forming the order before they ever sit down. If pricing and availability are up to date, even better. Then when the table opens and they are seated, the period between “we are finally at the table” and “we are ready to order” can shrink.
That does not mean every diner wants the same experience. Some people want to sit, relax, look at the menu slowly, and enjoy the whole ritual. Fair enough. The feature does not need to convert everybody. It only needs to help the subset of guests who are already motivated to decide quickly.
That subset matters because busy restaurants do not mostly struggle with demand. If they are using a digital waitlist during peak hours, demand is already there. The more operational question is how efficiently they can move people through the seating and ordering flow without making the experience feel rushed or mechanical.
That is why I like this feature. It is not growth theater. It addresses a real bottleneck. It reduces the dead space between seating and the first order. It gives the customer something useful to do while waiting. And it helps the restaurant increase throughput by removing hesitation that does not add value.
Why this feature fits the waitlist instead of distracting from it
On paper, menus and ordering can look like they belong to a different product. But in practice they line up with the waitlist surprisingly well.
The waitlist already has the guest’s attention during an otherwise idle window. That means it is one of the few product surfaces where the restaurant has permission to communicate with a guest before the meal begins. Using that moment to show the menu is not random upsell clutter. It is contextually aligned with what the guest is already there to do.
More importantly, it extends Shokken in a direction that still respects its core job. The app is not trying to become a full point-of-sale system. It is trying to reduce friction around the moments immediately surrounding the wait. Giving guests a way to think through their order earlier fits that mission better than most adjacent ideas I could pursue.
I expect I will need another round of focused testing once this lands, because it is not a tiny tweak. It changes what the guest sees and changes how the host may think about the queue experience. But this is exactly the kind of addition I want right now: something operationally useful, easy to explain, and directly connected to the businesses that are most likely to feel the pain Shokken is built to address.
Next Week
Next week probably splits in two directions. First, I expect Apple to respond again, and I need to be ready for the possibility that the current resubmission clears the two issues I fixed but exposes a new one. That is now just part of the cost of getting through the iOS release process.
Second, I want to keep pushing the menu feature until it is testable, then run another serious round of validation because it changes a meaningful part of the guest experience. If I can come out of next week with cleaner iOS review status and a working menu-aware waitlist flow, that will be solid progress on both the compliance front and the product front.