Robert W

Dev log for Pic Zip

More of the original ideas could be found here: 我的第一个iOS应用上架经历 & 后台流量 & 收入


  • Created the new repo, start composing the Package.swift following Runewords's example.


Project Modularisation

  • When a project is in the stage of design, and hasn't been started yet, it's usually a problem on how to design the basic data model, as we are uncertain about the entire workflow as well.
    • Take our project as an example, we don't know what DataModel, structs should be inclueded in the dataModel, what kind of interfaces should we use to expose the data inside it.
    • This requires us to go into the logics and UI again.
      • Take another deeper, closer look at the logics, data workflow. Imagine the data flowed through the lifecycle of the programm.
    • We can agree that this will always envolve and grow together with the development itself, which leads to this conclusion, this the nature of the data flow.
    • Do not using "Add Packages" from Xcode, instead, creating a new package project under Packages folder and then drag it into the project to make a versatile management.
    • Project growing
    • Trying to decoupling and adding modularisation too early might not be a good idea.
      • Instead, do a quick demo MVP as 1.0.0, and then carry out the modularisation process instead only at this stage.


Usage of Transferable and UTType

  • UTType (used in DataRepresentation/FileRepresentation) is a concept for denoting the real type in the file system.
  • This could be linked to the concept of the magic block etc to uniquely mark a file's type.
  • In the meanwhile, loadTransferable is the new way convert an instance to some other type, as long as the original type can be data presentation/file representation, and the target type defines how to initialise from it.


Dev Path

  • Can't figure out a clear path with known methodology to spawn the project codebase bit by bit.
  • It's either in a state of fully functioning or in the middle of somewhere you can't see the progress. Hard to mark the milestones.
  • In other words, the primary function and the branches function get twisted together. Without finishing the primary part to make a fully functioning live demo, I turn to handle other less critical codes. How to focus on the Minimum Demo?
    • Why not chekcing the other successful App with open-sourced repo git history???


Data flow and Environment

Have a better understanding of the environment virable. It's not easy to use as I thought - we can't link State variable

SwiftUI's PROs and cons

Using SwiftUI can save tons of time regarding the UI, but it requires you to have a clear mindset about how the data are flowing, and you need to know what you are doing for management the data flow. Without this, it's hard to efficiently using SwiftUI, since the logics are closely coupled with the data Observable.


Preview For Binding property behaviour testing

When using preview for binding property testing, we can't use state directly delcared in the #Preview Macro, instead, inside the content, define a new wrapper struct and declare the State over there. This allows the view functions mocking the the way it's used in real codes.

Tapping Area and conflicts for tapping gesture

When using gesture on Stack Containers, Spacers sitting within sometimes lead to a small content area, this could be fixed by


If a tapping gesture has been defined inside a child view, then adding a tapping gesture on the parent view will leads to conflicts. This could be fixed by using simultaneousGesture like below:

VStack {
    Text("Tap me")
        .onTapGesture {
            print("Text was tapped")
    Text("Another Text")
    TapGesture().onEnded { _ in
        print("VStack was tapped")

Right developing path

When building the App, breaking it down to two major parts, which consist of multiple mall logics modules: 1. UI part 2. Logics part

For logics part (TOP to Bottom approach when designing -> Bottom to Top when implementing)

It's easy to verify these without any UI, as primary logics can be tested using output. When doing this, you need to put the consumer as the first place, so that in the general picture, it's just one line of codes doing all stuff. Whatever the simplest would be the best approach. Usually when you making a clear SDK API, the codes should be really intuitive.

Taking the transferable protocol implementation for LocalImage as an example. The codes should just be 1.) copy the url to the right temporary folder + 2.) set up the instance to represent the images in the temporary folder. If you have already thought this through, you should be able to tell that there is no need to bring in extra layer of Folder/File entity defined in the 3rd party lib, which complicate things overall.

For UI parts (Bottom to Top approach)

It's hard to get all the stuff out in the most top level. When doing UI, design the most basic parts first. But adjusting UI should be already at the final stage. When doing MVP, using a List/ScrollView to scram everything for work flow testing into a Page.

absoluteString vs. Path

absoluteString includes protocol, like file://abc, Path is just the part without protocol.


State vs. Binding

Use state and Binding as natural type as possible. In other words, if there is an enum, then don't define the computed variable in enum's definition, instead, having both state and binding delared to that enum type in View part. The computed logics should happen in the Binding, as this is the place for logics computing, and has better self-governing for the subView using binding delcaration.

SwiftUI active response

Basically if a State is updated in non-main thread, it will pose a risk of inconsistency for the UI as these changes won't notify the SwiftUI update. Basically SwiftUI is like observable UI changes to data model only happen in main thread. This saves the trouble for you to manually call tableView.reloadData() but you still need to ensure the updates happen in mainthread.


The animation is still bugging me, however, considering the input effort and output effect, it's not worth spending too much time on this release TODO:

  • External link in MoreMenu
  • Privacy policy + Terms statement in MoreMenu
  • (Optional) The buggy animation for the foldable
    • It turns out the animation bug of unclear layout structure. Placing the animation part in H/VStack, and Group will help.


SnapShot integration

There is a disgusting bug for UI/Unit tests in Xcode15, you have to manually set the excute in parallel in test option settings. And even if you do this, it's impossible to pass this parameters via snapshot to the xcbuild command, which means you CANNOT run fastlane snapshot command.

  • see -

Trying to upgrade to the latest version of Xcode to see if this helps. In the meanwhile, disabled excute in parallel option, and begin to record the screenshots.


Remaining Agenda

The original function of the App has been migrated to the new App built in SwiftUI! Now there are some new challenges while we picking up some other new project ideas:

-[] Automation for screenshot - Can't make it working!!! Need further investigation. - Currently still need to manually screenshot. - Otherwise it'll be a great deal amount of work when there are multiple languages.

-[x] Remove past records

-[x] Localisation: Add Support for multiple languages

-[x] Use SEO/ASO strategy to see if manual effort could play some role in bumping the App rating and usage. - This is a really large topic - And an existing tool is SensorTower again. (Free) - - - - -

-[] InApp notification (discarded)

-[] Guide tips (TipsKit)(discarded)

-[x] Progress result/ ask for feedback

-[] In App Purchase. When How Where to pop? Reasonable solution (long term plan)


Device screenshot management

Device families:

  • iPad: 1. new iPad without home button 12.9 2. classic iPad with home button 12.9
  • iPhone: 1. new iPhone without home button 6.5 - iPhone XR 2. classic iPhone with home button 5.5 - iPhone 8 Plus (Phasing out)

iOS 17 no longer support iPhone 8 Plus. Checked the analytics - product page views, you can see all users coming from iOS17+.

Decided to abandon iPhone 8 Plus and older models, the gain not worth the effort input.


  • Use Udemy to learn ASO basics
  • Links
    • Apple Feature self intro: - DO not spam it, however, should do it monthly.
    • Google KeywordPlanner: - Free if you stopped at "Adding credit card"
  • Keyword research
  • Android也可以提供参考
  • Google Ads (苦恼没有具体数据)


  • 每两周周都要坚持检测动态.每两周动态会体现在后两周中.
  • title: 有改进空间.
    • Pic Zip: Bulk Resize in KB PDF
    • subtitle: 有改进空间.
    • Bypass file size limit easily!
    • keywords: shrink,bulk,compress,squash,jpg,squeeze,kb,less,jpeg,id,export,cut,pack,pdf,size limit,jpg,export
    • 截图有改进空间
    • new feature:
    • 删除元素,删除记录.
    • ask for feedback.
    • 截图preview改进


Now I can understand the importance of Unit tests and UI tests: From old data model in the previous App, I used tmp as the temporary folder name, however, this was changed in this SwiftUI release. This will have a separate folder listed under the existing past records, which leads to confusion.


Apple Could have shifted their position on the screenshot policy, See:

Use the following tools to generate a marketing pic:

New ASO:

  • Pic Zip: Bulk KB Resize as PDF

Also did the localisation for all languages via ChatGPT.

Gesture Conflicts and multiple State variable updates

When handling multiple State variables. OnTapGesture call back is not a good option. As the State is not atomic. Use Button with the oringal UI component as label can resolve this.


  • When using SwiftUI, define less reusability for more versatile behaviour. The sharing bevhaiour differs when placed in the profile list and the compress menu, checking these conditions sometimes cause buggy problem.


  • Multiple languages localisation strategy proves to be successful, but not a game changer - lower the expections.
    • Each of the localisation page has to be updated with different attempt, like local slang.
    • The task, even its parent task ASO, should be considered as a single puzzle piece for the marketing.
      • Need to have a broder marketing strategy. A Matrix plan rather than just sit and pray.

Fastlane: Screenshots and Deliver

It appears that there is still plenty of local work. Even copying stuff and copy directly to AI will cost a lot of time. Need to have a customised

  • Need to find a more efficient way for localisation and sub-language ASO.
    • Bring in the fastlane.
    • fastlane init now has a wizard guide
    • fastlane deliver download_metadata --use_live_version true --app_version 1.2.1
      • This gets you the meta data for all the languages in the nominated version.
  • Alter the local assets and the deliver has been made easy when setting up a new version/for sub localisation ASO purpose.

Better polishing screenshots, while adding privacy manifest file

  1. use to add a frame for Simulator's screenshot.
  2. use all sorts of figma frame:
    • This one doesn't include iPad, but still recommend it!


Do the right things, little by little. Don't waste time in perfection, but rather, spending your time in iteration. It matters more on "What you do" (Effectiveness) than "How you do it" (Efficiency), effectiveness is always at higher priority than efficiency.

  1. Fix screenshots and it's almost 7 days since we start multiple languages ASO last week (2024/03/15).
    • Wait for another week before next iteration of ASO.
  1. In the meanwhile, grid view would be the last feature before we freeze the development and turn to our next App.
    • Potienail new feature include, each one should be another chance for ASO. With priority
      • Footnote,title name to be append ( - Paywall to dismiss, but now introducd as a free feature
      • Zoom to preview.
      • Watermark (dismissable) - with QR codes/slogan to promote the App itself
      • Paywall for no watermark.
  1. before the App makes it to at least 1 high volume/value keywords, don't do any monetisation, but it should be ready from codes perspective.
  1. Today's TODO:
    • refactor the ImageData as the data manager
    • gridView
    • new UI (new button for gridView, redesign add more buttons)
    • Tiny fixes
      • Rate us as feedback
      • vibration interaction

New launch page tool:



  • Have a better understanding of the columns layout - it's setting the vailable space into pieces
    • adaptive can still be repeated for mimimum column count
    • ASO:
    • Pic Zip: Bulk KB Resize as PDF
    • Archive/Compress Image freely!
    • sizer,compressor,compresser,resizer,arch,jpeg,shrink,cram,mb,profile,thumbnail,reshape,reduce,export

Release road map

-[] Disable the layout flip button when there is empty input -[] Reuse ImageList in ProfileList -[] Preview carousel view -[] IAP - Buy coffee/ Donation -[] water mark

Tagged with: