Wednesday, April 01, 2020

Blogger: Change Background Color & Text Size

I have a blog at Blogger. Recently my friends ask me if I could change the background color and increase font size for my posts. After search on web, soon I found solutions.

Change Background Color


First go to Theme, then Edit HTML.

Expand line 9, b: skin section.





Search for "post.background.color". You will find this as variable definition.





In my Blogger, it is located at line 32: Make a copy the variable first. Then you can make change:

  1. <Variable name="post.background.color" description="Post Background" type="color" default="#ffffff" value="#353d4a"/>
  2. <Variable name="post.background.colorDeleted" description="Post Background DELETE" type="color" default="#ffffff" value="#1c1c1c"/>

Make sure the description on line 2 is not as same as description on line 1. I think that the description is a key for variables.

This variable is used for the class of post.outer





Change Font Size


Another change I would like to do is to enlarge text size of post.  This is very easy to do. Find "post-body" in HTML template



In my Programmer's blog, I could not find post-body. The size of text is defined in body class.


References




Read More...

Saturday, March 21, 2020

Story: A Traveler's COVID-19 Experience in Wuhan

Now it is pandemic critical time of COVID-19. I got an article in Chinese, a personal story of his COVID-19 in Wuhan China. I would like to share it in my programming blog. I will keep to update it with my translation as best as I can.

Personal Story of COVID-19 in Wuhan


I am a native of Wuhan and Shanghai. I got my undergraduate degree of Engineering in Huazhong University of Science and Technology in 1998. I am 43 years old. Now I run a software company in Shanghai. During my Chinese New Year's Eve in Wuhan with my family, I was suffering from neo-coronary pneumonia, ie, COVID-19, and then recovered. On January 26, 2020, I developed symptoms, and on March 14, I was confirmed to remove, and finally released from medical isolation. I have experienced the entire course of COVID-19.

As a science and tech person, I think that the COVID-19 is now a global pandemic. I try to summarize my experience and add some of the coping strategies I summarized during my sick for domestic and global friends in need as reference.

Notes on my Data

The cases covered in this article include:


  • Just myself.
  • Temporary Hospital(which is called as FangCai Hospital in Chinese) and I have 20 people in the same cabin from different administrative regions of Wuhan. My cabin number is 31st cabin of Wuhan Jianghan Fangbin Hospital.
  • The rehabilitation station was 19 people on the same floor as me, from different hospitals and cabins. Specifically, it is the 6th floor of Building 2 of a rehabilitation station in Jiang'an District, Wuhan.

My explanation:


  • The statements about specific conditions are all about me.
  • For statistics, I will indicate which data is derived from the above sample.
  • The check-in conditions for the FangCai Hospital are: at check-in, the body temperature must be below 37.5 degrees (normal body temperature) and the age must be under 65 years.
  • The admission conditions of the rehabilitation station are: cured & discharged patients who meet the official discharge standards (negative nucleic acid test for two consecutive times, normal temperature for more than 5 days, etc.). For people discharged from a number of cabins, Raytheon Hill, and Vulcan Hill Hospital, the age is not required, and some are over 65 years old.

My Sick Period

Date Description
2020/1/26 Felt fever in the morning
2020/1/29 Initial check at local community clinic, fevering not changed
2020/2/1 2nd check at the clinic, temperature remaining hight
2020/2/2 visited the specified fever hospital, and my CT showed high suspected symptom
2020/2/4 arranged nucleic acid test check by community clinic
2020/2/5 body temperature went back to normal, stayed at the norm
2020/2/6 received check result, positive.
2020/2/7 sent to Fangcai hospital by community to get isolation treatment
2020/2/29 confirmed recovery at Fangcai hospital
transfered to rehabilitation station
2020/3/4 released from rehabilitation station, back to home.
Now still need 14 days stay at home.

Key points from my own case, as well as other patient cases:


  • I started with fever symptom on 1/26 and ended on 2/5. The duration: 11 days.
  • Patients in the same cabin also have a fever duration of 1-2 weeks.
  • I started with fever, and finally were negative for all three nucleic acid tests. My discharge conditions were met, and it took 32 days.
  • Of 20 people in the same cabin, I was the 9th out of the cabin. I can roughly tell my typical indicators for my own case.

My sick development and key points


  • At the beginning stage of high temperature, I felt very cold, just like in a big room without heating. I felt like the situation of taking off cloth for shower. Even I was in the bed with covers, I was shaking cold.
  • My temperature went high at the period of 3rd to 5th day, about below 38.0. My under arm temperature was about 38.5. Before and after this period, my temperature was about 37 to 38.
  • The time of my most difficult feeling was at about 4th or 5th day. No matter I stood or were in bed, I felt heavy in my chest. It was like finishing 1000m run in middle school, could not breath comfortably. This symptom may be like what medical experts described as breath tight. After passing 2 days, my chest felt much better. At that time, it was like my body immune system was back its strength from sleep. The tight breath was improved a lot.
  • Patients with my in the same cabin all have similar feedback. With the help of medical helpers and moderate medicines, almost all of us fever went down.
  • There are 20 patients in one cabin. After our body recovered to normal, basically none one showed fever except 1-2 people, who had fever 2 days before their coming. After treatment and caring, later they did not show any fever.
  • During my fever initial days, I felt my body muscle sore and pain. After that, the symptom seems much better. After fever was gone, I have not felt muscle issue any more.
  • Since the date I was in cabin, I got measurement of blood oxen level from my fingers and the number was good relatively, among 96-99%. Only a few were 93 or 94%. Nurses took measurements 4 times daily, during 22 days.
  • After I was in cabin, I could tell my lung infection improving and ease, and I felt infections carried out by expelling sputum.
  • During the period of 2nd to 15th of my fever, my cough was very obviously, with sputum. During the highest temperature of 3 days and 2-3 days afterwards, I could see blood threads in my sputum (not clog, I guess it may be from my lung damaged tiny vessels). After 2 days in cabin, my coughing was gone. Several days later, sputum was much less, and then stopped.
  • During my stay in rehabilitation station out of cabin, we were in isolation stage. I stepped up to 6th floor. I felt breathing heavy(short break and heavy). Patients in the same floor had the same feeling. For reference, I was up to stairs every day during Aug to Sep in 2019. My speed up to 24 floors at about 5 minutes 20 seconds. I repeated 4 times (total to 96 floors), two groups in the morning and afternoon.
Cause

Unfortunately, I could not find out why for the moment.

When I was back to Wuhan, the disease were found in many places. I was very cautious and avoid out unnecessary, not contact people in large crowd. However, I was still caught the disease. I have 20 years senior programming experience, as well as many years of management and operations. My profession behave is very caution. I am with in top 1% in China. My case of COVID-19 only explains that this one is very hard to normal people to avoid. Many media news saying that it was spread by entering eyes, from shoes bottom were not enogh. I want to say that if you try to not getting this virus infection, you have to very very careful in everywhere, otherwise noway. Any careless or mistake would ruin all your protection efforts.

I try to get my caught reason as follows:

A. I might be infected by standing on street to have my breakfast (twice, about 20 minutes each time)
B. I was shopping (one time, about 30 minutes)
C. I was walking in our community area (3 times, 1 hour each time)
D. Our family build had some infected people. I might get caught during the time I was in elevator when I dump wastes (4-6 times a day, about 5 minutes)

My analysis

In all those cases, A, B, C I was with my daughter; D only myself.

My parents tested negative after my result was confirmed. My daughter was not infected. Only I was infected.

Based on above analysis, the most possibility is D.

Based on patients I was with in cabin:

  • They were in cabin and rehabilitation station. Some were veterans. They have very good body, and they exercise a lot. They still were infected.
  • Some are office workers, and they love exercise. Some got COVID-19 and passed away very quickly.
  • Based on some news, there are some wellness trainers caught COVID-19 and passed away.
My conclusion:

  • This virus is very easy to spread. Careless protection would not work.
  • The infection time is very short, may be in just minutes.
  • Don't go to area of crowd people, the risk would be very high.
  • Be very careful in closed area such as elevator. 
  • Choose to go to stairs if building is not too high, however, the stairs are also closed area. It may not safe neither.
  • People with regular exercise and good health may also get infection. It seems that virus only infect weak people.
CT Images

See Chinese version for CT images. From the image, there are some cloud in clear lung, as I marked as red.

Medical experts summarize those area as cloud and unclear area. These area maybe infected.

Clinic medical person examined my CT image, and said very positively that this was typical case, 90% COVID-19.

CT image after removed

Unfortunately all films would have to sanitized and they were all collected back. When I was out of cabin, I could not take photos. I can only simply say that all the cloud area are disappeared or much less, with only small spots. Doctors from cabin said that this is called as absolved by itself.

Here is another more straightforward comparison pictures (see tree pictures in Chinese article).

Treatment of COVID-19

 The treatment is in two stages, before cabin, and in cabin. In rehabilitation station, the condition is simple and no treatment service were provided.

Up to the time being, there is no official announcement of effective treatment medicines. I am not medical expert, nor I have any medical background. Therefore, my personal views may misleading you. Here I only objectively choose the treatment medical helpers provided for me, as for your reference. Please note that any medical treatment is only for specific case, and cannot be applied as general. Follow your medical doctors instruction when apply medicine.

During my treatment, the basics what I did are:

  1. keep positive attitude
  2. trust medical export's ability and professional skills, follow their advice to take medicines
  3. corporate with nurses routine checks and instructions
Treatment in cabin

Before cain, my treatment was mainly to follow medical instructions to take medicines.

During my community visits, I was not identified if I was normal fever or COVID-19. My treatment was mainly to reduce fever. I took fever medicines, anti-infection medicines, Lianhua medicine for ease virus. Because those methods were not for COVID-19, my fever not improved.

After that period, medical export in community realized that normal medicine seems not working. They decided to check if I was in COVID-19, and sent me to specified Wuhan Hospital to check.

At the hospital, I was determined mostly likely as COVID-19 based on CT image. They my treatment was focused on the virus. My personal feeling was that the result was very obvious. I started to take medicine on Feb 2. On Feb 5, my fever was basically released. See pictures of medicines (in Chinese article).

The last two are most effective. After taking with hotter, I felt a little bit sweat afterwards. I got those medicines from Hankou Hospital. All those medicines are within medical insurance.

Treatment in cabin

The treatment in cabin is the mixture of Western and Chinese medicines.


  • On the 1st date in cabin, doctors described us normal anti virus medicines (such as Abidol), as well as Chinese herb medicine(Lianhua anti virus capsues).
  • One week later, based on national announcement of medical treatment, we took the 2nd description, 2 bags daily, patient made decision to take or not.
  • 10 days later, doctors advised us to stop western medicines. We continued 2nd plan, 2 bags daily. They also provided more milk and other nutritions.
As I mentioned above, after I was in cabin, my fever was gone and blood oxygen level back to normal. With much less symptoms and the continuation of medicines I did not seem obviously.

Medical Expenses

My house registration and insurance are belonging to Shanghai. The expense before COVID-19 was on myself, in total 1983.42.

Date Hospital Item Fees Sub
2020/1/29 Community Clinic Diag fee 20.5
Medicine 227.45 247.84
2020/2/1 Clinic Diag 20.5
Medicine 186.62 207.12
2020/2/2 Hankou H. Reg free
Blood check 449
CT 359
Treatment 36
Med 346.98 1190.98
2020/2/7 Hankou H. Med 337.48 337.48
Total: 1983.42


I purchased commercial insurance, and I claimed it after I was released. My insurance paid 60% of my claim (about 1190yuan). For remaining amont (about 790yuan), I will check it when I get back to Shanghai. I think that it may be covered by normal insurance coverage at outside locations.

All my cabin and rehabilitation fees, all treatment, check, CT, food, daily expenses could be free. Up to the time being, I have not paid for those. I have not been asked to pay my cabin fees, nor any forms. However, I am not sure if my Shanghai insurance would refuse any payments. If any, I would list them and let my friends know.

Nutrition to COVID-19 Patients

For COVID-19 infection, nutritions are needed for patients to help them to quickly recover. I have the following list about nutrition concern:


  • Cooked eggs, 1 or 2 for breakfast and. There are rich nutritions in eggs, with protein. This will provide sufficient bullets for body to fight virus. At cabin and rehabilitation, at least one boiled egg is supplied.
  • Chicken soup. Hot soup helps to bring body strength back, help to sweat. With some salts, it adds electrolytes.
  • Balanced lunch. noon and evening meals in cabin and rehabilitation are supplied based on nutrition recommendations. Unfortunately I could find resources about it at that time. Based on my observation, there are meat, chicken, fish and shrimps for proteins, and sufficient vegs.
  • Seasonal fruits to supplement vitamins, helping to fight free-radicals.
  • Milk and sour milk, as protein and calciums supplements.
  • Small meals. small ones are almost as same as noon and evening meals, not much variations. In order to help patients to recover quicker, patients ate a little more than normal.
Because of different tastes among individuals, my observation is based food in Wuhan food style. Other places should refer to local nutrition experts recommendations.

Personal Supply Preperation

how much to prepare?

Based on my own observation, more people are less severe patients, and their treatment period is about 30 days. Taking isolation into consideration, it should prepare personal supplies for 60 days.

Basic supply

Location administrations provide guidelines for supplies, including:

  1. sufficient food: meals, vegs, meat, eggs, frozen foods, and others.
  2. cleaning products, hand gel (or 75% alcohol), soap, and others, one package for one person in a family.
  3. masks, sufficient for use
  4. sanitizers, carbon dioxide pills, 84 disinfectant, former is better to long time storage.
  5. home used medical equipments, temperature measure device, finger oxygen measure device, blood pressure measure device, and others.
  6. sufficient medicines for chronic illness if you are depend on them, such as high pressure, diabetes, insulin injection devices.
  7. toilet and hygiene paper.
Others

Besides above recommendations, based on my own and other patient cases, you may consider to prepare following supplies.

  1. strongly recommend to bring some physiology books, basic or middle levels. They will help you pre, during, and post periods.
  2. if you don't have insurance, you should consider to buy some health insurance. Pay attention to starting date of insurance.
  3. personal care products, at least 2 sets, such as finger nail cutter, shavers, swabs.
  4. women hygiene products, at least for 2 months.
  5. baby supplies if you have baby
  6. Hair cutter
  7. charger and wires
  8. medicines for eyes, such as erythromycin eye ointment, ofloxacin drops. 
  9. paper, pen and notes.
  10. several sets of one time use rain coat. if passing disinfection spray, normal rain coats are good enough.
  11. fresh preserve bags
  12. one cell, optional
  13. oxygen breath machine for senior people, about 3000 yuan cost, optional
  14. eye protection glasses, optional
  15. bicycle or electric slide board, for shot distance emergency use

Supplies for isolation

following supplies are very useful if being isolated:


  1. swissarmy utility. This device can be used to peel fruits, cut plastic bags, and fixing small items. This is really a handy device. If you don't have, you can bring fruit peeler or knigh. Those tools were allowed duing my stays. Personally, I think they are very useful.
  2. charger and wires
  3. one thermal cup and one cub, for taking medicines or cooling waters.
  4. paper, pen, and note books.
  5. carryon computer. The period of isolation was very boring. The laptop may help you to spend times.
  6. earphone plugs and eye covers. Those items were really helpful for sleeping and quick recovery. If you cannot sleep in short time, those items are good for you.
  7. toilet paper. Normally all stations have papers, but you may find it helpful in emergency.
  8. slipers. One time use or normal ones are good and convenient. But you should be careful when floor are wet or slippery (wash room, toilets), very dangerous there.
  9. personal care items such as nail cutter, shaver, and swabs.
  10. women use items
  11. a lots of fresh preserve bags, large size and thick ones.
  12. bring a book. you can read, or use it to cover convenient noddles, or as seat pad, many usages.
I recommend you to prepare those supplies now. Prepare two sets, one for you and one for family.

Self Psychological Adjustment and Recovery

I was very serious to read psychological books, on how to cope with COVID-19. Some one already provide a solution: the killer is not virus, but the panic and anxiety by the virus.

In case of being caught by the virus, either you or your friends(you may skip this section if you not by the virus), my personal self psychological adjustment for COVID-19 is as follows. I use the title of a well-known book as this section header. I think it can be also called as self-cultivation of COVID-19 patients.


  1. I agree with psychological release, instead of intervention. These two methods, for people who don't know, may think they are the same. In fact, they are very different in reality.
  2. No matter how long in treatment or isolation, or self status suddenly falling to bottom, you should always keep optimistic. Try to adapt to it, and don't just complain. If possible, try to change your context.
  3. Tell out when you cannot hold things. You should use simply and clear words to tell direct administrators, or relevant, or people who has influence. Actually, every one is willing to help you. Communication is necessary. Don't hesitate, depressed, or would bother others.
  4. The most important thing to do is to maintain good sleep.
  5.  After 8:00pm, you could play games, don't watch mass media news about the virus, which may affect your sleep.
  6. Image a way to guide your to sleep. What I did to watch math of university level. I remembered that I would go to sleep when I saw those questions. Now I could use this strategy. You could learn something when you cannot sleep, or fall in sleep.
  7. Friends around you all would like to talk. Try to talk to them. This could help you to ease stressed mood. Keep away 1 meter away, just remember this. Every one should wear masks. Keep further away if not with mask.
Conclusion

I close my strategies towards COVID-19. I hope every one have most careful protection measures. It is better not being caught by the virus. In case of you infected, I hope you will overcome fear thoughts, be positive.

I think I am a ordinary person, just like you. I have managed to pass over this journey and fully recovered, same will be you. Be strong!

I hope that my experience and this summary could help you. If you have any questions, or want to know more, please leave your comments. I will try my best to answer your questions.


References



Read More...

Wednesday, March 04, 2020

Conditional Compilation in Xcode

Recently I have interest in C/C++ #ifdef macro features in Swift. The main reason is that I have some debug codes through out my project for test and debug purpose. For example, I like to add deinit destruction with print() codes in classes to test memory leaks. Since those destructors have no purpose to clean up resources, I have to comment out them in production compilation.

In Swift, there are some conditional compilation features to including or excluding block of codes. For example, the following codes using #available to test if the current iOS matches required version.

if #available(iOS 11.0, *)

Further investigation, I find out that Swift does support #if statements to provide conditional compilation. The following are steps to implement the feature.

Define Custom Compilation Flags


The first step is to define customized complication flags in Xcode project. In the section of Build Settings, find Swift Compiler - Custom Flags (make sure All and Combined are enabled on top tab bar).



Then, you can add custom flag variables. Here are two examples of DEBUG_PRINT and DEBUG_DEINIT. For each flag, add -D before it, like "-D DEBUG_DEINIT -D DEBUG_PRINT"



Note: in the picture, I defined those two with _X as suffix to disable them. If I want to enable them in compilation, I remove _X.

Use Custom Compilation Flags in Swift


To use #if feature, it is quite straightforward. For example, there is the conditional compilation block for destructor:


  1. // MARK: - CTOR
  2. #if DEBUG_DEINIT
  3. deinit {
  4.  Logger.debug() {
  5.    String("\(CopyMoveViewController.className) deinit")
  6.  }
  7. }
  8. #endif
and here is an example of conditional compilation block for some codes:

  1. class Logger {
  2.  ...
  3.  static func debug(_ message: () -> String) {
  4.    #if DEBUG_PRINT
  5.    print(message())
  6.    #elseif DEBUG_DEINIT
  7.    print(message())
  8.    #endif
  9.  }
  10. }

Now I don't need to comment out some debug codes when I need to compile my project to production release target. The only thing I need to do is to disable those flags in my Xcode project file.

References



Read More...

Wednesday, January 08, 2020

Update to Xcode 11.3

I have been working on iOS projects with Xcode 11.1 for quite long time. Previously, I tried to update to 11.2. However, I experienced crashing issues after I compiled my project with Xcode. The problem was text editor. Each time when I tried to enter edit mode with text field UI, the app suddenly crashed. That was really bad experience.


I had to restore back to 11.1 version. Fortunately, I have Time Machine backup. From there, I restored Xcode 11.1.

Xcode 11.3 was released, but I did not update right away. Until I tried to compile my project to my iPhone with iOS 13. I got message that I had to move up to newer Xcode supporting iOS 13. I have no choice to move  on.

Update from App Store is also a pain. I tried for several days to update but I got failure each time. There is no reason given, and each time it took long period to download package, 7.8GB. That was really frustrating.

Yesterday a idea came up to my mind. Why not to go to Apple developer site to get Xcode? There must be Xcode 11.3 package just for download only. I went to the site and Xcode.xip is in the section of More(Beta, Release and More 3 sections). This makes me update much easier because it is the straight download.

After downloading, I clicked on the package. Soon I got a message of "not enough space on destination". That's why. The disk space is always problem on MacBookAir/Pro. What I did is to move out existing Xcode from Application to external disk. Finally I got Xcode 11.3 successfully installed!

So far, I have no issues with this version, and I could run my app on my iPhone for testing.

Read More...

Friday, May 31, 2019

Add Remote Repository to Xcode Project

I have been using BitBucket web based repository for a while. I like its user interface, easy and convenient to view changes of my Xcode projects. Another nice thing about this service is that BitBucket allows to create private repositories and it is free.

To add a project to git repository, exit Xcode and open a Terminal.

Local Git Repository


For creating a local git repository, please read my previous blog. This step is important because the remote git repository is based on local git repository.

Remote Git Repository


Create a new repository on BitBucket first, for example, myTestPository. Use the following command in Terminal to link local repository to remote.

# Sets to new remote
git remote add origin remote git@bitbucket.org:yourAccountName/randomdraw.git
# Verifies the new remote URL
git remote -v
# Pushes the changes in your local repository up to the remote repository you specified as the origin
$ git push -u origin master

With the above steps completion, your remote git repository is ready for committing any new changes/updates.

References


Read More...

Sunday, April 21, 2019

Bouncing Issue: Tap on Static TableView Content

Recently I found a really wired problem in my app. It took me several weeks to resolve the issue. I would like to write this blog to record this issue.

Here is the simplified case. I have a view controller based on UITableViewController. The table view is a static table view with several cells predefined in storyboard. Each cell has various height. The following is an example:



In cell Row2, there is a text view controller for editing a note.

When I run my app, I tap on edit button to change the text view into edit mode. This would cause the table view bouncing/jumping back and forth. At the end of this movement, the screen will stay at cell row 2 to allow me to edit the node. I don't like this kind of jumping movement.



When I test my app, I realize that I have another similar table view for editing note. That one does not have this jumping issue. Ok, I thought there must be something different to cause the issue.

I tried to compare every thing between those two screens, in storyboard settings and in view controller codes. I could not find anything obvious thing to cause the issue.

Finally, by carefully analyzing codes in both view controllers, I found that there is one line of code that caused the issue!

In smooth-none-jumper view controller, in the override func of viewDidAppear(), there is no call to its super class; while in the jumping one, the super class method of viewDIdAppear() is called, as in normal practice.

  1. override func viewWillAppear(_ animated: Bool) {
  2.  // Call base class method will cause edit note jumpping
  3.  // super.viewWillAppear(animated)
  4.  ...
  5. }

This is the first time I encounter the case that the base class method should not be called, as in my comment above.

With this solution and change, my screen becomes smooth when I tap on the edit button:



By the way, I like to use static table view for my editing screens because the table view is a scrollable view.

Read More...

Friday, March 29, 2019

Xcode 10.2, Swift 5, iOS 12.2 Released

On March 25, 2019, Apple formally released Xcode 10.2 with Swift 5, iOS 12.2, and others. With the release available, it is time for me to update my app projects. The following are some issues I have encountered and I think it is worthwhile to take some notes.

Warnings and Errors


The update, as same as my previous experiences, presented some issues I have to deal with. The migration process does not resolve all the issues. I got about 69 errors and 50 warnings. Those are the issues I have to check and change one by one. Fortunately, most of them are just API's changes, and Xcode does provides enough hints to tell what have changed. For example method name changes, and constants changes.

Fatal Error with no Clue


After I manually migrated all those changes. I got no warnings, and no errors in my codes. However, I had this no-clue fatal error:

Command CompileSwiftSources failed with a nonzero exit code

As my project is so complex and has massive codes. I was lost at first. Where should I start to resolve the issue? Since the Xcode 10.2 and Swift 5 are quite new. I could not find direct or clear solution from web.

Even so, some people had similar issue in their project. I looked at their cases and solutions carefully. I have to say some of their analysis provide me lights out of dark. Finally, I got this issue resolved.

In the project settings, this was my previous setting in Build Settings -> Compilation Mode:



the setting is Incremental. I found one solution is to change this to Whole Module as in the following:




Then I continued to build my project. This time, I got serval errors, which could not be found in Incremental compilation mode. One error complains that override cannot be applied to method in extension.

Here I give a simplified example: a base class implementing a none-objc delegate in iOS SDK's framework. When I wrote this base class, I put all the delegate methods within an extension of the base class. I like to use the strategy to separate delegate implementation in the extension block. This is OK in Swift 4 and 5 versions.

There are some occasions, I need to override some of those methods in inheritance classes. In the inheritance class I continue to put those override methods in extension block. In the previous version of Swift, ie ver 4, it is OK. However, this is not allowed in Swift 5. In other words, the override none-objc methods cannot be defined in extension.

It seems that Xcode Incremental compilation could not be identified the issue. Each file can be built or compiled without any errors. However, in the later or integration stage of compilation, Xcode could not resolve integration of the base class and inheritance class, based on Swift 5 rules. This may be Xcode bug. Fortunately, Xcode could start reporting and explaining errors in Whole Module mode.

I moved codes from extension to its class body block, those errors are gone!

After the successful build, I changed the compilation mode back iOS recommended default Incremental mode again.


References


Read More...

Wednesday, March 06, 2019

Source Code Control and Task Management

I have been using Bitbucket on-line service as my iOS source code control for about one year. I really like this tool. As remove and online repository, it works very well, and I can use Xcode to check in & out my changes.

Another related tool is task management. I use Trello to log my tasks. Within Trello, I can manage several lists, such as todo, doing, and versions. Within each list, task can be added with comments. By using this great tool, I can add check change as a task, and move them over lists. In this way, I have overview of all my changes.

The good news is that all above on-line services are free, great for starter developers.

References


Read More...

Tuesday, December 04, 2018

Add New Version to Core Data

There are sometimes when I need to update Core Data from existing version to a new version. In other words, I need to update Core Data database with changes on some entities. Apple provides very good framework to do that: Lightweight Migration. Here are my notes on how to add a new version to Core Data.

I am using my TapToCount-3W project as example.

In Xcode, select the data model in Project navigator:



From menu Editor, you will find Add Model Version....




Accept the default settings or make changes if you need. Make sure the base version is the most active version as base. In this case, I accept TapToCount 1.3 as my new version.

Change the property settings: identifier to 1.3 and current version to 1.3. A new version of database model is created and ready for update.



As it is indicated in Project navigator:



References




Read More...

Sunday, October 07, 2018

Run app on iOS 12.0 device from Xcode 9.4

Recently I updated my iPhone 5s with iOS 12.0. To my surprise, Xcode 9.4 on my Mac High Sierra dose not support iOS 12.0 device. That's hold on my app development.

My first reaction was to install the newest Xcode 10 beta 2 from Apple. The whole package is pretty big, 5GB+. That's OK. I downloaded the package and installed it. After that I was rushing to run my project in Xcode 10 (I did make a copy of the project to an external HD to run, to avoid any mass up). There were not much updates I had to make change in my app codes, however, I got a compiling error.

That was really painful time. The error seems to be related to linkage to iOS frameworks, no thing to do with my codes. I could not figure out what's wrong in Mac library system. Even worse, I could not run Xcode 9.4 with my project neither, with the similar linkage error.

I tried to look into my Mac library and Xcode framework dependencies. Remove and re-add frameworks. Nothing was working. I decided to stop further trying or mass-up. Took a break.

Fortunately, before I installed Xcode 10 beta 2, I checked in all my codes into my code-repository. I had my Mac Time Machine on. I know what is the time when I had the correct and latest working version of my Xcode 9.4, and it was just one day before. By using TM restoration, I finally got my app, in about 3 hours restoration of my Mac, working in Xcode 9.4.

With the successful restoration, I followed an advice from SO, copying iOS 12.0 supported folders from Xcode 10 beta to my Xcode 9.4.


Xcode-beta/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport


To


/Applications/Xcode/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport

Now I can run my codes from Xcode 9.4 to my iPhone 5s device.

What's adventure and life-saving experience!


References


Read More...

Wednesday, October 03, 2018

Python script: MapIt.py


Based on an example, script of mapIt.py, from the video of Automate the Boring Stuff with Python, I figured out that the codes should be changed in Mac OS X, as I mentioned that there are multiple versions of python in Max OS in my previous blog.

In addition to those changes, there are some steps that should done in Mac to make the script as executable in terminal. I further make it working in Spotlight as well. Here are my notes.

Script

Based on the video, I made minor changes on the script. Here is what I have now:


  1. #! /usr/bin/env python3
  2. import webbrowser, sys, pyperclip
  3. sys.argv  # example ['mapit.py', '870', 'Valencia', 'St.']
  4. address = 'Home'
  5. if len(sys.argv) > 1 :
  6.    address = ' '.join(sys.argv[1:]) # ['870', 'Valencia', 'St.']
  7. else :
  8.    address = pyperclip.paste()
  9. # https://www.google.com/maps/place/<address>
  10. webbrowser.open('https://www.google.com/maps/place/' + address)

The first line is important if you want to run the script directly from terminal or Spotlight. Still there are some other steps to be done in order to run the script directly from terminal or Spotlight.

Notice that I specify the name of python is python3! Another minor change is the default address value: Home. I am using Mac and the Google map knows where my home is in my local Mac account.

I saved the script at my local user account path: ~/Programming/py/mapit.py With script ready, I test the script in terminal:

...$ python3 Programming/py/mapit.py Park Ave 83 St New York

As soon as I type in the above command, a new tab page of Google Map is opened in Safari with the correct address.



Make the Script Executable

So far so good. However, I would prefer to open the script directly from terminal, or from Spotlight, without specifying python3. For the case of terminal, first I have to make the script executable with the following commands:

...$chmod a+x ~/Programming/py/mapit.py

The second step is to add my script path to env PATH so that I can simply type in mapit.py anywhere in command line. This is done by adding the path in ~/.bash_profile:

  1. PATH="/Library/Frameworks/Python.framework/Versions/3.7/bin:${PATH}:/Users/dchu/Programming/py"
  2. export PATH

With above setup ready, now I can run the script anywhere in terminal:

...$ mapit.py Donggaodi Hongxing St Beijing

Isn't that cool?




Make the Script Runnable in Spotlight


Spotlight on Mac is a very convenient way to launch an app, to open a file, and to find information. However, unlike Windows Run, it not the way to direcly launch an app with arguments. Even though I set my script mapit.py as executable, I cannot run it from Spotlight. It will only open the script in Xcode!

One way to get it work in Spotlight is to change the script to .command extension. Mac OS will recognize this type of file as a runnable command.

I prefer to keep my script as .py. In UNIX or Mac, I can create an alias file of script: hard link(only hard link works in Spotlight). Here is the command to set it up:

  1. ...$ cd ~/Programming/py
  2. ...$ ln mapit.py mapit.command

The good thing is that any change to my script will be automatically reflected in the command file.

In order to open the Google Map with specified address, I need to copy the address to clipboard first. Then I open my Spotlight and type in mapit.command. It will pick up the address and open Google map in my default browser.

The only thing is that I cannot specify address directly as arguments in Spotlight. This is the limitation of it, and I cannot find a way to do that.

This is why I need to use pyperclip package in my script.




Note: another minor thing has to be done to make it runnable cleanly. The command is running in terminal. When the Spotlight launches the command and opens the map in browser, it will leave the terminal in open status. I prefer to close the terminal automatically.

To do that, go to terminal Preferences..., change the shell setting to Close the Windows:




The last word I have to say is that even the python script is very powerful and convenient to open a map with an address. I think Mac's Automator is much more powerful. It is easy to create (as a service), and can be set to selected text to open a map. Even though, I think it is a very good practice and great programming experience.

References


Read More...

Tuesday, September 25, 2018

Python and Packages

Recently I started to watch a long training video on YouTube, 9+ hours. I just spent fraction of a few minutes daily as alternative refreshment. During the training period, I tired to use Idle app to practice some codes. Up to the point of installing third party packages, I could not get import to work on my Mac. I spent couple of days struggling and finally I figured it out. I think it is worthwhile to take some notes about this experience.

Tool to Install Packages


The first hurdle is that there is no pip, a tool to install third party python packages, available in terminal on Mac. It seems that python is part of Mac OS system, but the version of python is an old version: 2.5 & 2.7. pip was not installed on my Mac.

Eventually I got pip installed by using easy_install tool:

sudo easy_install install pip

After that, I could install pyperclip, a package for using clipboard copy and paste features.

sudo pip install pyperclip

However, the import of pyperclip in python shell and script still does not working!

Version Issue

I could not find out any solution from web easily. It seems that all the solutions in the top search list I found from web are old ones, ie for python 2.*. From one place I read a hint about the issue: different versions of python on Mac. It is true that python came with Mac OS is version 2.3, 2.5 & 2.7. The newest version, for the time being, I installed on Mac is python 3.7.

Further investigation, I found that the tool of pip is actually used to install packages for python 2.7. The pip is located at the path of:

/Library//Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pip

The tool I need to install pyperclip is actually pip3! This one is at the path of:

/Library//Frameworks/Python.framework/Versions/3.7/bin/pip3

When I sorted it out, it is so easy to install third party packages for python 3.7. For example:

sudo pip3 install pyperclip

For my interest, I further found out the locations of packages for different versions. For python 2.7, the location of package is at:

  1. find /Library/Python/ -name pyperclip
  2. /Library/Python//2.7/site-packages/pyperclip

and for python version 3.7 it is at:

  1. find /Library/Frameworks/Python.framework/ -name pyperclip
  2. /Library/Frameworks/Python.framework//Versions/3.7/lib/python3.7/site-packages/pyperclip


Python also in Different Versions!


One more interesting thing I found out is that, on my Mac, the name of python executable also has different ones! For the python came with Mac OS is actually version 2.5, and the executable name is python:

/Library//Frameworks/Python.framework/Versions/2.5/bin/python

and for the newest version, 3.7 I installed, the name is python3:

/Library/Frameworks/Python.framework//Versions/3.7/bin/python3


From the terminal, the command of python will bring up to version 2.5:

  1. ...$ python
  2. Python 2.5 (r25:51918, Sep 19 2006, 08:49:13)
  3. [GCC 4.0.1 (Apple Computer, Inc. build 5341)] on darwin
  4. Type "help", "copyright", "credits" or "license" for more information
  5. >>>

or type option -h to get all available options. -V is for getting python version:

  1. python -h
  2. ...
  3. Python 2.5


In order to run python3 from terminal, the PATH has to be changed: adding python3's path. This is the result of my updated PATH:

  1. echo $PATH
  2. /Library/Frameworks/Python.framework/Versions/3.7/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:

The PATH is set in the file of .bash_profile:

    more ~/.bash_profile

  1. # Setting PATH for Python 3.7
  2. # The original version is saved in .bash_profile.pysave
  3. PATH="/Library/Frameworks/Python.framework/Versions/3.7/bin:${PATH}:/Users/dchu/Programming/py"
  4. export PATH

Even with this change, you have to type the correct python executable name, ie python3, to enter python shell:

  1. python3
  2. Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 26 2018, 23:26:24)
  3. [Clang 6.0 (clang-600.0.57)] on darwin
  4. Type "help", "copyright", "credits" or "license" for more information.
  5. >>> import pyperclip
  6. >>>

Finally, I could do import pyperclip in python shell and scripts without any errors.

By the way, here are the options to get all the commands, options, and the version for the tool of pip or pip3:

  1. pip -h
  2. ...
  3. pip -V
  4. pip 18.0 from /Library/Python/2.7/site-packages/pip-18.0-py2.7.egg/pip (python 2.7)
  5. pip3 -V
  6. pip 10.0.1 from /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pip (python 3.7)


References



Read More...

Monday, September 17, 2018

Access to iOS Device Sandbox Data

If you have some files, database for example, in your iOS app, you may need to access to them. Recently, while I was working my app update, I was not sure if a major change would cause to lose my database. Before I run the app on my iPhone, I would like to keep a copy of my database to avoid any risk to lose my data over years.

There are couple ways to do that.

Backup to iTunes


This is very common way to keep a backup of a whole iOS device. First lunch iTunes on a Mac/Windows. Then connect your iPhone to the Mac/Windows. Click on iPhone icon to open a view, where backup is available.

This is very convenient to keep a backup before any adventure or after a period of time. In case of screwup, you can easily to restore your iPhone back to your previous status.

However, with this method, you could not see any files in your app sandbox, nor you could make any changes.

Devices in Xcode


The second way to make a backup of an app is available in Xcode. First, set your iPhone as target or active scheme. From the menu of Windows->Devices and Simulators, open a view.



Here is the view:



Select the app you want to make a backup, then click the gear icon to bring up a menu list. In this way, the whole app sandbox is backed up to your local Mac. The content of the backup can be viewed through Show Package Contents context menu.



This is pretty cool! Not only I can easily to restore the sandbox back to my iPhone, I could also view the content what I have in the app on my iPhone device. For example, the core data database, as you can see, is actually based on several files, all beginning with the same prefix name, defaultDatabase, as I choose it as database name for my app.

When I run my app in Xcode simulator, not only I could view, but also I could access to my app sandbox from Finder. There is no need to download or upload files to my app sandbox in Simulator.

I think that I could make some changes in the backup and restore back with changes I need. This is really handy for iOS developers in case needed.

Notice that you can only access to the app you are in development and installed to the device from Xcode, and the app has to be on your device. You can not see any other apps. If your app is installed through App Store, or Test Flight, you could not see it. This is for security reason. Anyway, it is good enough for me.

The Xcode I use is version 9.4 and iOS is version 11.4.

References



Read More...

Thursday, August 23, 2018

ActionSheet as PopOver View

Recently, I have been working on my app update. In some cases, some actions could not be performed. I need to present a view to explain the reason. Alert view is a very common method to do that. Alert view is good to present the information, however, it is a modal view. User have to tap on OK or Cancel button to dismiss the alert view. I prefer the method of a popover view as alternative.

It is very easy to do that by using the same UIActionControler, and set the style as .actionSheet. This is well explained in Nick Meehan's post. Still there some thing missing is his post.

I would like to support both iPhon and iPad. For iPhone case, an action button should be added to dismiss the view. By default, the view is still a model view. You need a way to dismiss the alert view.

It is very interesting to find out that an action with .cancel style will change the modal view into a popover view. Further investigation, there is no need to add action handler to dismiss the view. The actionSheet will behaviour like a popover in iPhone.

Here are some codes.

  1. if let popoverController = alertController.popoverPresentationController {
  2.  popoverController.sourceView = view
  3.  popoverController.sourceRect =
  4.    CGRect(x: view.bounds.midX, y: view.bounds.midY, width: 0, height: 0)
  5.  popoverController.permittedArrowDirections = []
  6. } else {
  7.  let cancelAction = UIAlertAction(title: UIHelper.dismissButtonTitle(), style: .cancel)
  8.  alertController.addAction(cancelAction)
  9. }


Another interesting thing is that the cancel style action button will be displayed as an separate button on the bottom. You can specify any title to the button. I like it. This is the UI as in some Apple apps, such as deleting a message in message app.

Here is what I achieved in my update:



References


Read More...

Thursday, June 21, 2018

Debugging with Xcode and LLDB

Really cool stuff on lldb, Xcode debug power tool. As well there is one training video from WWDC 2018: Advanced Debugging with Xcode and lldb.



Read More...

Tuesday, April 17, 2018

Pace Calculation in Swift

I need to add a new feature to show pace in my iOS App(TapToCount -3W). By given two dates and two locations as input, the pace can be easily calculated in the formula:

pace = duration / distance

Duration

In swift the duration can be obtained in following codes:


// dt1 and dt2 are Date types
let timeInterval = dt2.timeIntervalSince(dt1)

The func timeIntervalSince call will return seconds as time interval between two days.

Distance

The distance between two locations is obtained

// loc1 and loc2 are CLLocation type
let dist = dist2.distance(from: dist1)

where dist is the distance value in meters.

Support Localization and Accessibility

It seems that the pace calculation is so simple to get. Hold on. iOS provides APIs to support metric or imperial measurement system. It would be nice to get pace calculation result either in metric or imperial system. This can be easily detected by the following codes.


let locale = NSLocale.current
let metricSystem = locale.usesMetricSystem

In my iOS app, I presented the pace calculation result in human readable format. For example, 6'34" would be "6 min, 28 secs".

Further more, the pace result may be in hours, or even years, depending on inputs of dates and locations. My pace calculation is more generic to support a wide range of cases. To obtain readable result, it can be done by using Swift codes:


1 let fm = DateComponentsFormatter()
2 fm.allowedUnits = [.year, .day, .hour, .minute, .second]
3 fm.unitsStyle = .short
4 let short = fm.string(from: value)
5 fm.unitsStyle = .full
6 let full = fm.string(from: value)

The allowedUnits property specifies what readable units should be used. Here is the complete units from seconds to years, and only first none zero value's unit will be presented, for example, 2 hrs, 15 min, 23 secs. This example is in a short form. There is no need to worry about languages. The API will do the localization automatically. Very nice!

The short form is good for UI presentation. The full form will spell out whole units, such as "2 hours, 15 minutes, 23 seconds". This would be great for accessibility support, for example, label's accessibilityValue. The localization for full form is done automatically as well.

I tested this pace calculation in my iOS app. The following is the screenshot of my mountain hiking, Ha Ling Peak, last Sunday.



and this is my running result today when I was doing my test.




and here is one more test I did. I changed the iPhone language to Traditional Chinese.



You may notice that when the pace result is in years or long days, the last units minute and second are dropped out, since such small amount is so insignificant.  The complete codes are available in my answer in StackOverflow discussion.

References




Read More...

Sunday, January 14, 2018

Autoresizing and Constraints to Safe Area

Recently one issue has troubled me for several days. Finally I just figured it out. I think it is worthwhile to make a note about my experience.

I have an app with several tab views, all displaying similar data in table view. I tried to add search feature for the app. The way to add search controller for iOS 11 and iOS 10 is different. For iOS 11, the search controller is added to navigation controller while the search controller is added to table view's header for iOS 10. My test of iOS 11 works great. However, the test for iOS 10 presented an issue.

In the first tab view, the search works well, but not in the second one. The issue is that the content of table view is shifted up about 40 pixels in the second tab.

Here is the search bar at initial status:



Tap on search bar to start search. Notice that the content of table view is shifted up 40, about half of the first row is behind the search bar.



Even worse, I could not see the search bar if I select a row to the next screen and back to the main screen. The search bar is moved up, not in reachable view.



The search function in the first tab view works without this issue. Therefore, the best way is to compare the difference between two tab view controllers. There are not any major difference. I tried to disable some codes in viewDidLoad, viewWillAppear, and viewDidAppear to make them behaviour the same. Still I could not resolve the issue.

Finally, I noticed there is a difference in storyboard. The table view of the first tab is using autoresizing.



while the second tab's view controller uses constraints for its table view!



I removed four constraints and set autoresizing for the table view of the second tab. With this change, the search feature works well as expected.

It seems that autoresizing for iOS 11 is almost as same as four constraints to its safe area (which is introduced in iOS 11 but not exist in iOS 10). Even it would fall back to previous layout guide, it seems not working in the same way for table view in this case. For old iOS back from 11, try to not use safe area as reference for table view constraints.

Test for all supported iOS versions is very important!

Read More...

Monday, December 04, 2017

iOS 11 New Feature: Displaying Large Size Content

iOS 11 introduce many great features. One of them is display large size content, for example, text and images. With small size of mobile devices, for many people it is really hard to read small text or content. With this new feature in iOS 11, I want to support it in my app.

One new change is the large size title in navigation control. Another one is dynamic size for text views. PDF format for images is also great to avoid making various size of images in project.

There are two very good videos to watch as in the reference.

References


Read More...

Monday, November 13, 2017

Dynamic Height of TableView Cell

For table view in iOS, its cell could be one of several styles: basic, detail, subtitle and custom. The first 3 are built-in style. The title, subtitle, and detail are labels in the cell. By default, those labels cannot grow vertically if text in the label is too long. I found out there is a property for label to control if displaying only one or multiple lines: numberOfLines. By default, this property is one.

If you change the property to 0, the label may grow vertically to show all the text in it. That means the view cell in a table view could grow dynamically in height. This is true for the first three styles. However, for the custom view cell, it is tricky.

Recently, I was working on my iOS app to enhance its user interface. One of table views contains custom view cell. I would like to show cells in dynamic height if labels in the cell having long text. At first, I tried to set up enough constrains in the custom view cell so that no any warning nor errors in storyboard. However, my view could not show dynamic cell height.



It seems that all cell height are the same.

Finally I figured out why. The contrails in the custom view cell have to be enough for UIKit to calculate the height. In my view, I placed three labels one by one vertically. From top to bottom, I set constrains one to next vertically. However, I did not add a constrain from the last label to the bottom. As a result, UIKit could get the height of view cell.



I added the constrain to make sure the last label's bottom related to the bottom of its container. With this change, I got my app working as expected.




Enough-constrains-for-vertial-span is a trick for custom table view cell. There are other things which have to be set for dynamic cell height. See the reference blog for detail.

By the way, my app supports several languages. Therefore, for this update, I have to make all the changes in all language views in storyboard. You may notice that the messy one above is in Chinese, and the next expected one is in English. By the time I am writing this blog, I have not updated my Chinese view yet.

Reference


Read More...

Wednesday, November 08, 2017

Grey blank toolbar on TableView

During my work on my iOS app (TapToCount - 3W), I had a very bizarre issue. There is grey blank toolbar appearing above tab bar on one of tableview controller.

Problem


Actually, the main view with tableview looks OK initially. A grey blank tool bar appears above tab bar after back from a detail view.



The detail view is popped up from the main view when a row of tableview is selected by using navigation controller. The detail view shows a toolbar with some buttons, but no tab bar. Look at detail view, I notice that the tool bar actually is raised up from bottom.




I tried to find what settings triggered this problem from storyboard on both main and detail views, as well as my codes for those views. I could not find anything wrong.

One thing I noticed is that the English version runs good. The problem only appeared on my Chinese version (when I changed iOS language to simplified Chinese, but traditional Chinese is good). I think that it must be something I might changed in storyboard for simplified Chinese. Most unlikely in my view controller codes.

Snapshots to Find out Differences


I am using MaBook Air 2014 on my App. There are tens of property settings in a view. It is really very painful slow (about 40 secs) to compare those settings switch back and forth between Chinese and English storyboards. I found a trick to do the checking, taking snapshots of property settings in one language and then using those snapshots to compare property settings in another language.

Interesting thing is that both main and detail views are exactly same! That puzzled me. Soon I realize that the view is driven by navigation controller. There might be something different in navigation controller. There are several navigation controllers: root view controller (tab view controller as start), master view controller (split view controller), and navigation controller.

From those view controllers, I found the differences!







I am not sure what those marked settings mean. I changed the settings in views of Chinese storyboard. voilà! It works!

Here is the current version of views for the same problem ones as in above.






Conclusion


Sometimes, it may be hard to find out straight solutions either from my own knowledge/skills or internet. There may be some other ways to target the issue. Here is an example, from working version as start, then trace down the difference in the problem target.

I am not going to explain what caused the problem. I may figure out reason behind those property settings. This blog is just a note about my programming experience and growth.

Read More...