Wednesday, May 10, 2017

Apple Developer

Today is an important date for me. I just applied my Apple Developer from Apple web site. Actually I have been Apple Developer for long time, but I have not paid my annual fee as former developer yet. Even so, I have been doing development since the start of iPhone released. Now my app is ready for Apple Store.

The application process is very simple. First, submit my request from the web site. I applied as an company. What I need to get D&B's DUNS number for my company. This can be obtained for free from D&B Canada. Normally it requires 30 days to process. Another requirement is an email. The email cannot be gmail, hotmail, yahoo, or the likes. The recommended is email with company's domain name. I found that iCloud email is acceptable.

After submitting my request, I receive an email about acceptance. The next step is to agree Apple Developer Program License Agreement.

The last step is to pay my annual fee $99US or $119CAD, plus tax 5.95.

Within one hour after my annual fee payment, I am not registered developer for all Apple platform apps. The first three things I have to do are prompt when I login to my developer's account:

  • Connect to my team members (none so far)
  • Get Certificates which will be used for my apps
  • and set up iTunes connect account to manage my apps,



Monday, May 08, 2017

Workspace in Xcode

One of interesting things I learned from Developing Apps for iOS CS193P, by Stanford U, is using Workspace in Xcode. This was explained in detail in lecture 9, TableView, at about 46minute.

Follow the instruction, what I did in my app project is to convert my project to Workspace from menu File-Save as Workspace...

Then from Finder to locate another project file and drag it to the Workspace, as two parallel projects.

One of project is a iOS Target type. This target has to be added to another project as embedded binary in project. This can be done by dragging the target to project settings.

The advantage of Workspace is that I can modify both project if needed.


Thursday, May 04, 2017

Xcode and Swift Tips and Tricks

During my development of my iOS app, I have encountered some hurdles. Even though some of them are small ones, I did spend a lots of time to find solution to overcome them. Here are some in my past short period.

Can't find customized class from Storyboard

Normally customized view controller classes are used to handle specific requirement for some views. In Storyboard, this customized class can be specified in Storyboard right property panel "Show the identity inspector" tab.

For whatever reason, I may pressed space bar by chance in the area of Module. This caused the Module's value as None! As a result, I got this run time error:

Could not cast value of type 'UIViewController' (0x113f1b798) to 'MyProject.MyViewController' (0x113985200).

I spent hours trying to figure out why. Eventually, I found out the simple solution: change the module to my project.

This is what I had in my Storyboard for this customized class setting:

Hide Tabbar and use toolbar

In a tabar driven app, sometimes, I may need to hide tabbar and show a toolbar as alternative. To hide tabar for next view controller, it can be done in prepare(for segue: sender:) event.

  1. override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
  2.  ...
  3.  let vc = segue.destination
  4.  // call vc's hidebottombar
  5.  vc.hidesBottomBarWhenPushed = true
  6.  ...
  7. }

For the case of normal view controller, bar button item can be directly added to the bottom of the view. For the case of tableview controller, in order to show bar button item on the bottom, a toolbar has to be used to encapsulate bar button items. This can be done in storyboard.

However, it seems that there is no API or method to let vc to show or hide toolbar. At first, I found a solution to show or hide toolbar by adjusting toolbar y position in viewWillAppear event. The problem is that if user changes device from portrait to landscape, the toolbar will be off screen, disappeared. As a result, I have to adjust toolbar y position in the event of viewRotated.

To adjust toolbar y position, I add the following API to view controller as extension. This makes it easier in call this API to show toolbar.

  1. extension UIViewController {
  2.  func setToolBarShow(show: Bool, delay: Double = 2) {
  3.    if let toolbar = self.navigationController?.toolbar {
  4.      let newOriginY = UIScreen.main.bounds.height - toolbar.bounds.size.height
  5.      if toolbar.frame.origin.y != newOriginY {
  6.        toolbar.frame.origin.y = newOriginY
  7.      }
  8.      if delay > 0 {
  9.        // Make sure origin is set correctly
  10.        DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
  11.          if toolbar.frame.origin.y != newOriginY {
  12.            toolbar.frame.origin.y = newOriginY
  13.          }
  14.        }
  15.      }
  16.    }
  17.  }
  18. ...
  19. }

Here the trick to show toolbar in the events of viewDidAppeared and viewRotated is to delay adjusting toolbar y position. It seems that in both events, without delay, toolbar would not show. It may be something inside UIKit would not seeing this adjustment. With delay, the toolbar would show correctly at the bottom of the view.

Change navigation back button's title

In the case of parent VC to child VC by using navigation controller, the top-left button is used to pop off child VC and back to parent VC. The title of this button is by default the title of the parent VC. If the parent title is too long, it may make top text too crowded if the title of child VC is too long. One simple way to change top-left button title to "Back". This can be done by clearing parent title before pushing to child VC. UIKit will automatically use "Back" as the title.

Here is the solution to do that: clear view's title when pushing a new view controller. This can be done in the event of prepare() for segue.

One thing to remember is that to set view's title on the event of viewDidAppear(), otherwise, the view's title would be blank if the view is pushed back.