Wednesday, November 29, 2017

Mac change folder owner for permission to update file

When upgrading to High Sierra on the mac, somehow the owner needs to be updated due to an IT requirement.

After the ownership change, a lot of files are locked due to the current user does not own the file.

Updating the owner of the file and folder from Get Info page does not work as expected. So the best way to fix the issue is running chown from terminal as


sudo chown -Rv i826633 FolderPathToChangeTheOwner 

Saturday, November 18, 2017

iOS 11 UIBarButtonItem may not work on real device

One iOS project has a view controller containing a table view and a toolbar, the toolbar has a UIBarButtonItem to open another view controller.

After upgrading an old ios project with XCode 9.1 and swift 4, running it on iOS 11 real device shows clicking on the UIBarButtonItem does not work as expected. However when running on iOS 11 simulator, clicking on the button works fine.

Even if after reverting all the change made during the upgrading in the project, the issue still happens, so it indicates the issue is caused by rebuilding the project using the ios 11 SDK and running it on ios 11 device.

The more investigation indicates the issue is caused by a tap gesture recognizer added in the viewcontroller's view object. The tap gesture is used for dismissing the keyboard.

In ios build prior to iOS 11, even if adding a tap gesture recognize on the view controller's view object, the toolbar button's handle will still be called. However, in iOS 11 sdk, when clicking the button, only the tap gesture recognizer's handler will be called, the button item's click handler will not be called.

The fix is quite simple, instead of adding the gesture recognizer to the view controller's view object, just add it to the tableview' view object. So that when clicking on the bar button item, it will not trigger the tap gesture recognizer's event handler

Original code:
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(TravelDateViewController.handleTap(recognizer:)))

self.view.addGestureRecognizer(tap)

After the fix:
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(TravelDateViewController.handleTap(recognizer:)))

self.tableView.addGestureRecognizer(tap)

Monday, November 13, 2017

Missing Firebase module error when adding unit test target into existing ios project

An ios xcode swift project was created a while ago with swift 3.0. Later when adding a unit test target into the project, a build error happens due to import module gets unknown module or missing Firebase module error.

For the unknown module error, it is because the module name has been changed after the project was created, the import statement requires module name instead of target name. So fix this error, just go to application's build settings' module name field and use the module name for the import statement.

The second error is due to swift version mismatch, the application target uses swift 3.0, while the new unit test target uses swift 4.0, and the Firebase library downloaded by pod file can only have one version, so both target must have the same version. From the target's Build Settings, change the swift language version to 3.0

The pod file was generated only have the configuration for application target, after adding the unit test target, it needs to be updated to also have Firebase library for unit test target as below, and then run "pod update" to update the pod

source 'https://github.com/CocoaPods/Specs.git'

platform :ios, '9.0'

target 'myapp' do
  use_frameworks!
  pod 'Firebase/Core'
  pod 'Firebase/AdMob'
  
  target 'UnitTests' do
        use_frameworks!
        inherit! :search_paths
        pod 'Firebase'
  end

end


Finally after import the application module into the test file, be sure @testable is used, so the internal class can be used by the unit test methods.

import XCTest
@testable import myapp

Avoid main thread check warning in iOS project when firebase is used

When starting ios project which integrated with Google Firebase library, the app may generate few main thread check warning as below
Main Thread Checker: UI API called on a background thread: -[UIApplication delegate]
PID: 740, TID: 51958, Thread name: (none), Queue name: FIRAnalyticsQueue, QoS: 9
Backtrace:
In addition, the ios unit test target may not be able to run at all if the main thread warning exists.

The reason is the old Google Firebase library 4.0.0 and below has not been updated for the new ios 11 and xcode 9, the issue can be fixed by updating the Google Firebase library through the pod file by running the below command from ios project root folder in mac terminal:

pod update

Currently it will update the Google Firebase library to
Installing Firebase 4.5.0 (was 4.0.0)
Installing FirebaseAnalytics 4.0.4 (was 4.0.0)
Installing FirebaseCore 4.0.10 (was 4.0.0)
Installing FirebaseInstanceID 2.0.5 (was 2.0.0)
Installing Google-Mobile-Ads-SDK 7.25.0 (was 7.20.0)
Installing GoogleToolboxForMac 2.1.3 (was 2.1.1)

Installing nanopb (0.3.8)

Friday, November 10, 2017

git merge and rebase from same and forked repository

Git Merge and rebase from same repository
Both merge and rebase can be used to integrate changes from one branch to another, however they use different approach. Consider the below case:
A forked commit history



git merge
As the name imply, when git merge is used as below
git checkout A
git merge B
(git pull B)
It appends all the change from B as a single commit to the current history of A. So all changes happened in B are added as a single new changes in A. None of the existing commit history in branch A is affected by this.
Merging master into the feature branch





git rebase
As an alternative to merge,
git checkout A
git rebase B
(git pull --rebase B)
Rebase will insert each commit happened in B into the history of A, so the changes in B get inserted at the proper history in A Rebasing the feature branch onto master



Git merge for forked repository
If you have a forked repository, usually you will make some change and then send a pull request to update the original repository. But quite often you will need to update your forked repository to bring back the change made in original master repository. Although you can do this from git bash command, but if you prefer there is an easier way to do this from github web page.

In the forked repository, click the pull request button, in the next page, click "switching the base" button as you want to merge the change from original repository to your forked repository. Then create the pull request and merge the pull request.