Sunday, October 29, 2023

Parallels for macOS running under macOS

I am a long term VMWare user. My VMs were Windows. I tried macOS Mojave on VMWare Fusion 13 running on macOS Ventura and it runs fine. But the problem starts with inter host operability. I am unable to transfer files from Ventura to Mojave. Without this the VM is useless to me. So I tried Parallels. I had seen good reviews about Parallels in general. Installation experience was good just like VMWare and I am able to transfer files from Ventura to Mojave. I also tried with Catalina in the VM and it works without any problem.

Friday, October 20, 2023

Cannot read properties of undefined TestableReference

I received this error with iOS build in Microsoft App Center for Flutter app. There was flavors configured with dev, qa and prod envs. The dev.xcscheme and qa.xcsheme under Runner.xcodeproj/xcshareddata/xcschemes should have Testables under TestAction. Otherwise it will throw Cannot read properties of undefined (reading 'TestableReference') error. The code should look like:
<TestAction
      buildConfiguration = "Debug-qa"
      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
      shouldUseLaunchSchemeArgsEnv = "YES"
      shouldAutocreateTestPlan = "YES">
      <Testables>
      </Testables>
</TestAction>

Friday, October 6, 2023

Fixing Created Date 1970 For Blu-ray In macOS

Blu-ray is a good way to store data for archival purposes. macOS has built-in support for writing blu-ray disks. However there is an issue with file creation date. All files Created date gets reset to 1 January 1970 at 5:30 AM. This the unix epoch time. Clearly this makes lot of things difficult. This issue is present for years and still not fixed with macOS Ventura. I checked the date at a later point in time and by then I have most of my image files written into blu-ray. This makes ordering files by created date difficult and also it's a bug. Luckily we have two other attributes to our rescue. Photos taken by iPhone have Content Created attribute. This value is intact and so is Modified. If you don't edit you image files, then any of these are valid. So I created a little bash script to update the Created date to Content Created date if it is valid or use Modified.
#!/bin/bash

resetted_date="1970-01-01 00:00:00 +0000"
resetted_content_created_date="1970-01-01 00:00:00 +0000"

function update_created_date {
  local file="$1"

  fs_created_date_utc=$(mdls "$file" | grep "kMDItemFSCreationDate" | awk -F '= ' '{print $2}')
  fs_created_date_local=$(date -j -f "%Y-%m-%d %H:%M:%S %z" "$fs_created_date_utc" "+%m/%d/%Y %H:%M:%S %z")

  
  # Get the kMDItemContentCreationDate value
  content_created_date_utc=$(mdls "$file" | grep "kMDItemContentCreationDate[^_]" | awk -F '= ' '{print $2}')
  content_created_date_local=$(date -j -f "%Y-%m-%d %H:%M:%S %z" "$content_created_date_utc" "+%m/%d/%Y %H:%M:%S %z")

  
  fs_modified_date_utc=$(mdls "$file" | grep "kMDItemFSContentChangeDate" | awk -F '= ' '{print $2}')
  fs_modified_date_local=$(date -j -f "%Y-%m-%d %H:%M:%S %z" "$fs_modified_date_utc" "+%m/%d/%Y %H:%M:%S %z")

  # Check if creation date is not empty and fs created date got reset to 1970
  if [ "$fs_created_date_utc" == "$resetted_date" ] && [ -n "$content_created_date_utc" ] && [ "$content_created_date_utc" != "$resetted_content_created_date" ]; then
    SetFile -d "$content_created_date_local" "$file"
    echo "Content created date set $content_created_date_local for $file"
  elif [ "$fs_created_date_utc" == "$resetted_date" ]; then
    SetFile -d "$fs_modified_date_local" "$file"
    echo "Modified date set $fs_modified_date_local for $file"
  fi
}

# Check for folder path arg
if [ $# -ne 1 ]; then
  echo "Usage: $0 "
  exit 1
fi

folder_path="$1"

# Check if the folder exists
if [ ! -d "$folder_path" ]; then
  echo "Folder '$folder_path' not found."
  exit 1
fi

# recursively process files in folder
while IFS= read -r -d '' file; do
  if [ -f "$file" ] || [ -d "$file" ]; then
    if [ "$(basename "$file")" != ".DS_Store" ]; then  # ignore .DS_Store
      update_created_date "$file"
    fi
  fi
done < <(find "$folder_path" -type f -print0)

# recursively update created for the directory as well
while IFS= read -r -d '' dir; do
  if [ -d "$dir" ]; then
    update_created_date "$dir"
  fi
done < <(find "$folder_path" -type d -print0)

Run this script by specifying the folder like set-created-date-to-image-date Pictures-2018. It will recusively set the created date for folders and files.

The above script will fix the date problem. To prevent this issue with blu-ray disk image writing, one solution is to create a dmg container and format it into the same file system type used by the macOS. I use APFS case-sensitive. So I use the same format as the dmg as well.

To create a new disk image, open Disk Utility > File > New Image > Blank Image and set the parameters as below.
Name: beetles-all-the-way
Size: 25GB
Partitions: Single parition - GUID Partition Map
Format: APFS (Case-Sensitive)
Image Format: read/write disk image
Encryption: none

Save this to say Burn Folder, mount it, copy files. Then insert the blu-ray and drag and drop the dmg for burning. This will preserve the file attributes.

Thursday, October 5, 2023

Using same DB by multiple users in DEVONthink 3

DEVONthink stores all data in a dtBase2 file. It's a container which contains the file and other settings. I have a DB called CSE where I keep my web archives, bookmarks and I want to use it from my work and personal accounts in the computer. I created the DB under the personal account. So it belongs to that user. It is advised to close the DB before opening by other user. Since the work user does not have permissions, it opens in read-only mode. To fix this we can add read-write permission to the DB file. Now if we try to open it will show "Database seems to be already in use" warning and when clicked on continue anyway it won't open. The solution as suggested by cgrunenberg is to quit DEVONthink, remove the .dtBase2 extension, which will now appear as a folder. Now add the work user with read-write permission for the folder and apply changes for enclosing files and folders. Add back the .dtBase2 extension. Open the DB and it will work just fine!

NB: It's adviced to never use the open the same database by mutliple users at the same time.

Saturday, September 23, 2023

Finding files differences between folders

I wrote a small script to find the files which are not present between two folders. Initially I used diff which works fine for source codes but when I want to just check for folders and files newly added to a directory without having to compare its content, diff is very slow. I wrote it mainly for backup purposes. For example, I have documents written to optical disk for archiving. I want to know which are the newly added files since the archival. So I can quickly compare the folder from optical disk and the hard drive to get a list of file I need to backup.
#!/bin/bash

if [ $# -ne 2 ]; then
    echo "Usage: $0  "
    exit 1
fi

folder1_path="$1"
folder2_path="$2"

# List all files in first folder
find "$folder1_path" -type f | sed "s#${folder1_path}/##" | sort > files_in_folder1.txt

# List all files in second folder
find "$folder2_path" -type f | sed "s#${folder2_path}/##" | sort > files_in_folder2.txt

echo 'Files in folder1 that are not in folder2:'
comm -23 files_in_folder1.txt files_in_folder2.txt

echo ''
echo 'Files in folder2 that are not in folder1:'
comm -23 files_in_folder2.txt files_in_folder1.txt

# Clean up
rm files_in_folder1.txt files_in_folder2.txt
For checking content difference
#!/bin/bash

# find difference between file and folder contents

diff -rq "$1" "$2"

Thursday, September 21, 2023

Bookmarks Organiser v4.0 is live

Bookmarks Organizer is a nifty browser extension that automatically sorts bookmarks alphabetically when added. We can also sort all bookmarks manually using the reorder button. Chrome has moved to new version of manifest which is v3 making incompatible differences in how extensions work. All manifest v2 extensions will be removed from the store starting Jan 2024.

The previous version of the Bookmarks Organizer used web worker for compute intensive sort operation. With manifest v3, the default background script runs as a service worker. Currently chrome cannot create nested workers. So I rewrote the entire extension as I cannot use web worker and made it more streamlined. The current version excludes Other Bookmarks/Other Favourites from sorting so that any manual ordering can be placed there.

Get Bookmarks Organizer for Google Chrome which is a featured extension in the chrome web store.
Now Bookmarks Organizer is also available for Microsoft Edge browser as Edge Add-on!

Thursday, July 6, 2023

Integrity could not be verified error on launching app in iOS

When trying to install a build from third party websites like Microsoft App Center, if we get the error "This app cannot be installed because its integrity could not be verified", when launching the app, it means that the current provisioning profile used does not contain the UDID of the device used. To fix this, add the UDID in the Devices section in Apple Developer Portal and regenerate the provisioning profile. If using App Center, upload the new provisioning profile and generate a new build.

Monday, June 19, 2023

Firebase Messaging iOS Errors

When using Firebase SDK with cloud function to send push notification, below are the errors and its description related to iOS.

"messaging/third-party-auth-error"
This error means that the authentication with the APNS failed. This is most likely due to not uploading the APNS key in the Firebase Cloud Messaging Settings.

"messaging/invalid-argument"
This error is thrown when there is an issue with the token. This can arise from an invalid or expired token. This could also arise when a token obtained from iOS simulator is used. It's better to test push notification using a iOS device. Later versions of Xcode supports push notification on simulator but needs additional configuration.

Sunday, June 18, 2023

Delete a file from git history

I have tried multiple commands to delete a file entirely from the git and its history. This is what worked without any issues. This requires force push the changes.
$ git filter-branch --force --index-filter "git rm --cached --ignore-unmatch path-to-file-to-remove.txt" --prune-empty --tag-name-filter cat -- --all
If there is space in the path escape with a slash \.
After that force push to the repo.
$ git push -u origin main --force

Thursday, June 15, 2023

Setting Up Remote Git Sync In Working Copy on macOS

Working Copy is an iOS git client app. It has a good text editor and a pleasant UI. Since it is a git client it can sync with remote git servers. Here I will decribe how to sync within internal network running git server on macOS.

1. Install Simple Git Server on macOS.
2. Under repositories create a new repository. I use Working Copy mainly for journalling. So I will create a repo named journal.git. Use .git extension ticked.
3. Start the git server. It will show two URLs. One with IP and other with local domain name. Use the domain name URL as it's constant.
4. Checkout the created repo under mac.
$ git clone git://ataraxia.local/journal.git
5. Open Working Copy on iPhone and create a new directory. Let's call personal. We cannot move repositories to new directory once cloned. Once in the directory, tap on the plus button and choose clone repository. For the url give git://ataraxia.local/journal.git and tap clone.
6. Add a file sync-test.txt to test the syncing. Commit the file with push radio button enabled. This will sync the changes to remote.
7. Go to macOS Terminal and run
$ git pull
This will show output like below.
jsloop@ataraxia journal % git pull
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 220 bytes | 220.00 KiB/s, done.
From git://ataraxia.local/journal
 * [new branch]      main       -> origin/main
Your configuration specifies to merge with the ref 'refs/heads/master'
from the remote, but no such ref was fetched.
Here we can see that the repo fetched all remote branches which is main but did not checkout the fetched branch. Let's checkout the main branch.
jsloop@ataraxia journal % git checkout main
branch 'main' set up to track 'origin/main'.
Switched to a new branch 'main'
Now that the files are checked out, use ls to view the synced files. Any changes made from the macOS and sycned with remote will appear on Working Copy on pull. I use terminal and Fork app for git GUI on macOS.

This gives us a fully locally synced git repository. After finding Obsidian not working for me, I have moved all files to Working Copy and now uses it for my journal. I write journals in plain text files, so this setup works well.

Tuesday, June 13, 2023

Obsidian Content Search

While Obsidian is a great app, the search is rudimentary. It searches only the file name and not content. In order to search for contents, luckily we have a community plugin Omnisearch which searches through file content as well. This can be installed from the community plugin section of the app.

Sunday, June 11, 2023

Journalling on iPhone using Obsidian

I just came by Obsidian app which is a note taking application available on all platforms. I have been using DEVONthink Pro since 2018. I bought the mac and iOS apps mainly because it offers seamless offline syncing between these two apps. I can write my journal on iPhone and sync it to mac all offline. It's a bit involved but not that complicated to setup offline sync. The main issue that I face now with DEVONthink is that mine is version 2 and now the latest supported version is 3. Version 2 is no longer supported and the app crashes on iPhone when searching for anything.

I found that Obsidian is really good for writing notes. Notes are saved as markdown (.md) files in the local file system. These appear when we connect iPhone to the mac and can be easily backed up by dragging and dropping the folder. I read that there are plugins for syncing but a simple copy works for me. Also, the Obsidian app is free for personal use.

Update on 15 June 2023
I have migrated all my notes from DEVONthink to Obsidian. Now the app is taking more than 20 seconds to open an offline vault containing 283 plain markdown files. This is unusable for me. So I moved away from Obsidian to Working Copy.

Thursday, June 8, 2023

Android Simulator Internet Access on Hotspot

Sometimes the internet access in the Android simulator does not work if connected to an iPhone Hotspot. Chrome won't load any page, apps cannot connect to servers. This can be fixed by added a public DNS under the Network settings in System Preference in macOS. Choose the Hotspot connection > Advanced > DNS and under the DNS Servers: add 8.8.8.8 and 8.8.4.4. Then relaunch the emulator to get internet access.

Azure Function Slots For Staging Env

Azure Functions are serverless cloud computing platform offered by Microsoft. When we create an Azure Function, the default one is considered as production. This has the URL https://<function-name>.azurewebsites.net. For development and testing purposes it is essential that we have a staging environment as well. And Azure Functions offer this in the form of Slots. Slots provide a different environment under the main function project. These have URL https://<slot-name>.azurewebsites.net. We can deploy the cloud function to slot and it acts as another environment completely.

To deploy to a slot we can use the Azure Account extension. Login using the Azure credentials and navigate to the slot as shown in the screenshot. Right clicking on a slot, there is option to deploy. And this will deploy the cloud function to the corresponding slot.

Wednesday, June 7, 2023

Firebase Token Retrieval Failed: SERVICE_NOT_AVAILABLE

When running Firebase Messaging based app under Android emulator, if we are getting the error W/FirebaseInstanceId: Token retrieval failed: SERVICE_NOT_AVAILABLE. Will retry token retrieval, this most likely means that the fcm messaging token retrieval failed due to inability to connect to the server. Check the internet connectivity inside the emulator. I was running the app with iPhone Hotspot and the emulator had no internet connectivity. Once the connectivity issue got resolved, the token generation succeeded.

Friday, June 2, 2023

Enable Horizontal Scrolling for Code in Blogger

For code snippets we use pre tag in blogger. These appear in a straight line and breaks out of the layout. To enable scrolling for pre tags add overflow: auto;.
pre {
    overflow: auto;
}

Friday, January 27, 2023

JreJsonObject cannot be cast to Serializable

macOS Monterey 12.6.2 gives this exception when trying to run a spring boot based vaadin project. ClassCastException: class elemental.json.impl.JreJsonObject cannot be cast to class java.io.Serializable. This is an issue with the OS. The project works fine on a lower version of the OS, v12.3.1 for example.