
macOS-utveckling
TidyImage
TidyImage är en native macOS-app som vi på GrandWorks byggde för att lösa vårt eget bildarbetsflöde, och som sedan blev en kommersiell produkt. Vi byggde hela stacken: mac-appen, ett Stripe-baserat licenssystem, användarkonton, hantering av teamplatser och en adminpanel för att styra alltihop.
Kund
GrandWorks
bransch
produktivitetsverktyg
Lösning
macOS-app, licensiering, backend

ett verktyg vi behövde, så vi byggde det
Varje GrandWorks-projekt avslutas på samma sätt: bilderna komprimeras. Under flera år lappade vi ihop det här med de verktyg som fanns tillhands. De flesta verktyg klarade bara ett format. Vissa laddade upp filer till servrar vi inte kontrollerade. Inget hade stöd för teamlicenser. TidyImage började som ett internt verktyg. Det blev till en produkt vi säljer.
Varje GrandWorks-projekt avslutas på samma sätt: bilderna komprimeras. Under flera år lappade vi ihop det här med de verktyg som fanns tillhands. De flesta verktyg klarade bara ett format. Vissa laddade upp filer till servrar vi inte kontrollerade. Inget hade stöd för teamlicenser.
TidyImage började som ett internt verktyg. Det blev till en produkt vi säljer.
utmaningen & lösningen
Det dräller av verktyg för bildkomprimering. Vad som saknas är riktiga produkter. De flesta verktyg löser bara själva komprimeringen isolerat – dra in en fil, få en mindre fil tillbaka – utan tanke på vad som händer före eller efter. Ingen masshantering för mappar med hundratals bilder. Ingen formatkonvertering i samma steg. Ingen teamlicensiering. Det var i glappen i arbetsflödet som tiden försvann, inte i själva komprimeringen.
Vi byggde TidyImage för att lösa just de problemen. Batch-processning direkt på enheten, formatkonvertering i samma svep och export till en vald mapp. Runt själva appen byggde vi den kommersiella delen: betalning med Stripe, licensvalidering på serversidan, kontohantering och hantering av teamlicenser.

masskomprimering direkt på enheten
Behandlar stora mängder bilder direkt med macOS egna bildramverk, utan att några filer skickas till externa servrar. En mapp med 500 bilder komprimeras i bakgrunden medan du arbetar vidare, med en framstegsindikator som syns men inte stör.
stöd för moderna format
Stöd för JPEG, PNG, WebP, HEIC och SVG, med möjlighet till formatkonvertering i samma batchkörning. En designer kan släppa in en mapp med HEIC-exporter från iPhone och få tillbaka en mapp med WebP-filer på en och samma gång.

Format-specifik
komprimeringskontroll
Varje format har ett eget reglage för kvalitet istället för en gemensam inställning. JPEG och WebP kan finjusteras helt oberoende av varandra. Gränssnittet visar den uppskattade storleksminskningen före export, så att du kan ta rätt beslut direkt utan att behöva göra om jobbet.
Licenssystem för Stripe
Hanterar enskilda köp, uppgraderingar av abonnemang och förnyelser via Stripe Checkout. Licensnycklar skapas på servern när betalningen har godkänts, skickas via e-post och valideras när appen startas. Webhook-hanteringen tar hand om misslyckade betalningar och ändrade abonnemang helt automatiskt.


konton och licenser
En intern instrumentpanel ger oss koll på alla konton, licenser, platser och betalningshistorik – byggd för praktisk vardagsanvändning, inte för sakens skull. En teamlicens täcker ett visst antal platser under ett konto; licensägaren bjuder in medlemmar via e-post, och systemet ger åtkomst automatiskt. Platser kan tilldelas på nytt, och användningen spåras per plats, inte per enhet.
design & ux
TidyImage används när man vill leverera filer, inte utforska funktioner. Gränssnittet speglar det: drag och släpp är huvudfunktionen, inställningarna kräver inte din uppmärksamhet varje gång och förloppsindikatorn tar inte över skärmen. Samma logik gällde för webbplatsen. Kort köpflöde. Kontosidan visar bara det som behövs. Designarbetet handlade mest om att bestämma vad som skulle väljas bort.
teknisk implementering
macOS-app
Byggt i Swift med Apples egna ramverk för bildhantering, CoreImage och ImageIO, istället för externa kodbibliotek. All processering sker direkt på enheten vilket gör det snabbt och slipper de integritets- och fördröjningsproblem som serverbaserad komprimering innebär.
backend & api
Ett Node.js-API hanterar licensvalidering, kontotransaktioner, logik för teamplatser och Stripe-webhook-händelser. Licenskontroller körs när appen startas och med jämna mellanrum under användning, där kortlivade tokens cachas lokalt för att undvika fördröjning vid varje kontroll.
Stripe Checkout sköter hela köpflödet. Webhooks hanterar licensiering, förnyelser och uteblivna betalningar. Alla webhook-händelser processas med idempotensnycklar, så att upprepade anrop inte skapar dubbla licenser eller debiterar kunden två gånger.
Nycklarna signeras på servern och kopplas till ett konto, inte en enhet. Appen validerar mot API:et istället för en lokal fil. Licenserna styrs på kontonivå, vilket gör att en teamlicens inte kan delas av fler än det antal platser ni betalar för.






























