Monday, December 31, 2012

Year 2012 is Over, Welcome Year 2013

Year 2012 will be over soon. At the time of this blog being published, I am on my way to China for my vacation. In the middle of 2012, my contact job was changed. My previous contact job is mainly as software developer to support historian services for SCADA system. Development work only took small portion of my time, I was mainly responsible to provide support for applications, such as SQL server, Parcview, and applications I wrote.

When my contract was terminated, I thought I would never to touch Parcview. I was looking for .Net development jobs, as well as iOS development. In my personal profile and resume, I did not mention Parcview at all. To my surprise, I got a call from a company, in about 2 weeks of my break, to ask me to fill a role to provide support for Parcview. As a result, I accepted the offer. Now my IT role has been changed since. Not much development work, my work, or new contract, has been mainly on Parcview and historian service support. In 2012, a big change happened in my career.

Even though I know Parcview and historian services very well, there are still many new challenges. I think this provides me a good opportunity to extend my skills and knowledge in this area. Since my work is mainly in support case, I have not touched codes at all. I tried to reorganize some of previous Visual Studio projects and trie to find a way to put them in my work. So far, my effort has not been approved yet.

My iOS app has been on hold as well. The career change may be one of reasons I delayed my app. Another reason is that I have been waiting for my daughter to provide art work for my app. The app is about 80% finished. All my iOS development are in my afterwork hours.

I had a talk with my best friend over a weekend. He asked me what are my new goals for the year 2013. Among many goals I would like to complemented, to continue my iOS development is one of them. My current contract has been extended for the year 2013. I am pretty much sure there will be not much development at my support work. Therefore, I will focus on iOS or even Mac OS app development. I have to make my effort to plan my time and allocate enough resources to continue my software development. I hope this will extend my software development to a more existing area.

Read More...

Tuesday, December 18, 2012

Get Folder Permissions by Scripts (3)

In terms of getting folder permissions by using PS script, the first two blogs are just good enough. As a bonus and my personal reference, here are simple helper function and entry point. That completes my blog about my script.

The help function is a very simple one which prints out the usage of the script. The same practice can be applied to other scripts.

# FUNCTION LISTINGS
# =============================================================================
# Function: HelpInfo
# Created: [11/25/2009]
# Author: David Chu
# Arguments:
#   $p_scriptApp: script application
# -------------------------------------------
# Purpose: display usage message
# -------------------------------------------
function HelpInfo($p_scriptApp)
{
 Write-Output ""
 Write-Output "Description: Get permissions for a folder."
 Write-Output "Parameters: folderPath [outFile] [/s]"
 Write-Output "Where"
 Write-Output "      folderPath: a path for a folder"
 Write-Output "      outFile: output file"
 Write-Output "      /s: recursive to get sub folders"
 Write-Output "Examples:"
 Write-Output "This one running from PowerShell:"
 Write-Output ("  PS: {0} C:\MyData" -f $p_scriptApp)
 Write-Output "The following example running from cmd console:"
 Write-Output ("  cmd> PowerShell {0} C:\MyData myFile /s" -f $p_scriptApp)
}

PS entry section is the place to get all the parameters from command line.

# Example to run this script:
# @powershell d:\Scripts\GetPerm.ps1 'D:\Displays\Public' /s
# Result:
D:\Displays\Users Everyone:(OI)(CI)F
                 BUILTIN\Administrators:(OI)(CI)F
                 NT AUTHORITY\SYSTEM:(OI)(CI)F
                 CREATOR OWNER:(OI)(CI)(IO)F
                 BUILTIN\Users:(OI)(CI)R
                 BUILTIN\Users:(CI)(special access:)

                                   FILE_APPEND_DATA

                 BUILTIN\Users:(CI)(special access:)

                                   FILE_WRITE_DATA
#*=============================================================================
#* SCRIPT BODY
#*=============================================================================
# example parameter values for this script. Add the parameter to PowerGUI Script
# Editor's Input toolbar:
# C:\Users /s
$scriptApp = "GetPerm.ps1"

# check input arguments
if ( $args.length -eq 0 -or $args.length -gt 3 )
{
 HelpInfo $scriptApp
 return
}
# Get the first input parameter
$i = 0
$folderPath = $args[$i++
$outFile = "outFile.txt"]
$recursive = $false
if ($args.length -gt 1)
{
 if ( $args[$i++].ToLower() -eq "/s")
 {
   $recursive = $true
   if ($args.length -gt 2)
   {
     $outFile = $args[$i++]
   }
 }
 else
 {
   $outFile = $args[$i++]
   if ($args[$i++] -eq "/s")
   {
     $recursive = $true
   }
 }
}
# check if source and dest pathes exist
if ( Test-Path -Path $folderPath | where {!$_PSIsContainer} )
{
 GetFolderPermission $folderPath $recursive $outFile
} else {
 Write-Output ("Invalid path: {0}" -f $folderPath)
}

#*=============================================================================
#* END OF SCRIPT BODY
#*=============================================================================

In PS, command line argument can be obtained from $args[] collection, and the number of arguments is the property of length of $args.  Each argument can be enclosed by single quote ' char, not double " char.

Read More...

Tuesday, December 11, 2012

Get Folder Permissions by Scripts (2)

I created a simple function in PowerShell script to get folder permissions. As I mentioned in my previous blog, a DOS command is used to get folder permissions: Calcs. If there is subfolder within a folder, the function provides recursive option to get subfolder permissions. In addition to that, the folder can contain wild characters such as "*data".

To get all the containers as a collection in PS, the command is Get-Item with option $_.PSIsContainer:

$fs = Get-Item -Path $p_Path | Where-Object {$_.PSIsContainer }

The following is the function

# Function: GetFolderPermission
# Created: [10/02/2012]
# Author: David Chu
# Arguments:
#   $p_Path: folder
#   $p_recursive:    true for recursive, false for not
# -------------------------------------------
# Purpose: get folder permissions
# -------------------------------------------
function GetFolderPermission(
 $p_Path,
 $p_outFile,
 $p_recursive)
{
 # get all the files matched and timestamp > comparing date
 $fs = Get-Item -Path $p_Path | Where-Object {$_.PSIsContainer }
 if ( $fs -ne $null )
 {
   foreach ($folder in $fs)
   {
     $fullDir = $folder.FullName
     Write-Output $fullDir
     $cmd =  'cacls "{0}"' -f $fullDir
     Invoke-Expression $cmd | out-File -Append $p_outFile
     if ( $p_recursive )

     {
       $fsSub = Get-ChildItem -Path $fullDir |Where-Object {$_.PSIsContainer}
       if ( $fsSub -ne $null)
       {
         foreach ($subDir in $fsSub)
         {
           $fullDir = $subDir.FullName
           GetFolderPermission $fullDir $p_recursive $p_outFile
         }
       }
     }
   }
 }
}

The above codes are very straightforward, therefore, no need to explain.

Read More...

Tuesday, December 04, 2012

Get Folder Permissions by Scripts (1)

I found there is a DOS command tool to get folder permissions: Calcs. By using this tool, permissions can be added, deleted or modified as well. Based on this findings, I used PowserShell to create a script to get folder permissions. I am planning to further to enhance this script to create duplicated permissions for a specified folder.

Here is a example of using the script in a batch script:

C:\test\powershell c:\scripts\GetPerm.ps1'C:\MyData' /s

The result is something like this:

D:\MyData Everyone:(OI)(CI)F
         BUILTIN\Administrators:(OI)(CI)F
         NT AUTHORITY\SYSTEM:(OI)(CI)F
         CREATOR OWNER:(OI)(CI)(IO)F
         BUILTIN\Users:(OI)(CI)R
         BUILTIN\Users:(CI)(special access:)

                           FILE_APPEND_DATA

         BUILTIN\Users:(CI)(special access:)

                           FILE_WRITE_DATA

If there are sub-folders within, the script will loop through to get all sub-fodler permissions as well.

It is possible to use WMI class or other tools in PS to get folder permissions. Calcs is a free tool in Windows. I found it is much easy to leverage its power to do the job.

Read More...

Wednesday, November 28, 2012

OPC and DCOM/COM Issues

My working experience with OPC and DCOM/COM can be tracked back to more than 10 years ago. I remember that when I was working at a SCADA software company in Calgary, I was assigned to a project to write OPC Client app. OPC technology is based on Microsoft Windows DCOM/COM infrastructure to provide automation for industries. At that time, it was very advanced technology and has been quickly adopted by many industry companies, specially in SCADNA system.

Since then, I have been on and off on OPC development and support. Even COM was very nice library based design infrastructure, it has it is drawbacks. Microsoft has been moved to .Net based infrastructure, COM and DCOM becomes old technology. However, so many software and applications have been developed and they are in use in various systems, it is really hard to cut it off.

Recently I have been working on a project to build a new historian system. The system is based OPC technology. In the past week, I have been working to set up a new historian system. I expected OPC configuration being the hardest task. Basically, an OPC client application has be set up to communicate with a remote OPC server. I have been struggled for almost a week on the project. I almost reached the point to make them to talk. The OPC client could talk to the remote OPC server by using local Administrator, but not a domain user. The DCOM settings on the OPC server side should be OK since we have a production OPC Client collecting data. It is just a new Windows 2008 Server not being able to collect data. Windows 2008 Server is a kind of Windows Vista, which is based on a more complicated secure framework, such as firewall, network configuration and system security configurations, in addition to OPC configurations.

My past experience and my knowledge in this area still benefit me a lot for my current work. I have changed my careers in a wide range of areas. Never know what you have done may continue to impact your future.

Read More...

Wednesday, November 21, 2012

Oligo Got Patent

Since I started my new contract job at HP/Cenuvos, I have not been doing application development. Instead, I provide applications support. That's why I don't have a lots to write about my programming and skill experience.

I have been kept listening some .Net technology podcasts, such as HanselMiniutes and .Net Rocks. Those podcasts occasionally talk about some none-programming topics. That's a change to bring some thing the authors being interested while they cannot find any good topics. Now I am going to talk about nutrients.

I have been a Melaleuca preferred customer for about 16 years. I really enjoy their great products, green, safe, effective and reasonably priced. This month I got my products. Along with the box, there is fly normally about products and specials. I saw the first page is dedicated to Oligo, the technology behind many of Melaleuca products.


To restate the claim:

Melaleuca's Oligo™ technology is now protected by U.S. Patent No 8,273,393

On Tuesday, September 25, 2012, the United States Patent and Trademark Office granted a patent protecting the Oligo technology that powers the Vitality Pack® and other Melaleuca products.

*Patent pending in Canada 

I started to use Vitality products (multi-vitamins and minerals) 10 years ago. It makes great difference to improve my health. Before I did not believe nutritional supplements at all. I thought I get all the nutrients from my daily in-takes, and why should I rely on supplements. From Melaleuca product information and my own research, I found that I could not get enough and balanced micro-food my body needs. That changed my mind to give Melaleuca Vitality product a try. The more I learn about health knowledge, the more I believe that I need to use Melaleuca products to enhance my life.

That's my after work research and hobby. I am a down-to-earth person, not only for the best codes, but also for my other hobbies, such personal health. I spent many of my after-work hours to explore and to study Melaleuca products. Each time when I see anything I don't know, I'll try to do my research through all the channels, such as on web and books, to expand my knowledge. As a programmer and IT consultant, I think my health is very important. I need to keep my mind sharp and my body strong and in good shape so that I have more energy to do what I like.

Before Oligo, Melaleuca has already obtained patent about how improve minerals absorption, it was called as fructose-compounding. This technology makes Melaleuca multi-vitamin and multi-minerals with high absorption rate. The Oligo technology goes one more step. It has been proven that the Oligo-fructose compound minerals has much less oxidations during digest process, which means less multi-vitamines wasted during intestinal digestion process.

Reference


Read More...

Tuesday, November 13, 2012

Xcode 4.5 Upate and Mac Automatic Update


Yesterday I saw Xcode 4.5 update in my App store. I have been put my App development on hold for a while. This update may have new features I have been waiting for: customized object collection view for pictures I'll use my my app.




One new feature in Mountain Lion(ML) is to download updates automatically. All the Mac and app updates are through App Store. The download process happens automatically. However, the update has to be done through users.

Before ML, Mac OS update check is set through System Preference, as a scheduled check. When new updates are available, OS will prompt user to proceed downloading and then installation. In ML, the software has more options in System Preference:


The download process can be done automatically, as well as system data and files. For other updates, Mac users have to be click on Update button  to proceed. The above is my settings. The advantage of this update is that the update process will avoid long time waiting for downloading. When updates are ready, the installation can be done immediately.

I notice that there is no way to define checking updates schedule, daily, weekly or monthly. There is only a button for Check Now.

This new feature is quite convenient for users because most of cases users want to do updates.

Read More...

Monday, November 05, 2012

Mac OS Security: Gatekeeper (2)

I remember that one of WWDC 2010 session videos has a show on this topic with demos. The demo was a quick one, but it is very impressive. I have done some tests on this feature. Here are my hands-on tests.

App Store Only

First, I tried to set up my Security to Mac App Store only. This is the most restrictive option. With this simple setting, I could not download any apps from browser.

Identified Developers

This is the recommended option for most users: Mac App Store and Identified Developers. This means you can download apps from web, but those apps have to have authorized developer IDs. According to Apple, an developers ID certificate can be obtained from none-Apple Agents, such as Google, Microsoft.

I set up this option in my Mac. Then I can download any apps from Web. Only apps with identified developer IDs can be opened. For example, I downloaded a free app NetNewsWire.app, which is an app signed with Apple Developer ID. After downloading, the following warning message is display for the first time to run it:


No Open for None Identified Apps

For example, I tried to download MesaSQLite from CNET downloads. For the time bing, this app has no Apple Developer ID signed. Therefore, I could not run this app on my Mac.

No Open for Other Macs

I tried to copy this app to another Mac. Still I cannot run it. It seems that the Mac OS quarantined the app upon its download.

Anywhere

This is the most open option, as same as previous Mac OS or Windows. You can download any apps from Web and use them. The interesting thing is that I tried to temporally set to this option to get apps which I trust with no harm. Then I reset option to Identified Developers. The file I got from anywhere are free to be copied to another Mac by USB, Airdrop or network shared drivers. Therefore, Gatekeeper is only for web browsers.

Authenticated Developer ID

The key point in Gatekeeper is the concept to sign an app with an authenticated developer ID. In the WWDC demo, one interesting demo is a hijacked app. That is, to modify an app, either signed or none-signed. For those apps, Gatekeeper would identify them as potential malicious apps.

To test this case, I opened the content of the app NetNewWire by Show Package Contents from its context menu. I copied one image to the root of its content. Then I uploaded it to my Dropbox's Public area. From there I downloaded the app again. Here is the image of original app, on the left, and modified app, on the right side, on my Mac:

No matter my Gatekeeper setting is Anywhere or not, I just cannot run this app. This app is quarantined by OS upon its download. Nor I can run this by copy to another Mac (I mean copy the downloaded app).

However, if I modify the app on my Mac, I can still run it and I can copy it to another Mac. Gatekeeper is just a security gate at browser between Mac and Web.

I think Apple's Gatekeeper strategy is an innovation change in OS level. It is a very effective way to protect Mac users from attacks by malicious apps, which most sneaked in, either accidentally or social engineered downloading from web browser.

Gatekeeper is just the forefront tier of Mac OS security layers. For developers, this is a big change and it will be new trend we have to face to. If you sign your app with your ID, your app will be treated as good citizen in binary world, or white list, until you intentionally make crime, attack user computers or steal private information, for example.

This is analogous to the case of border gates of US, Canada or any country in the World, passport is a practical identify as to citizenship when you across border gates. This is by far the most effective and less costly way to protect countries. Just image how you can secure your country if you have to check periodically each one in your country to see if they are not malicious. In theory, the strategy of internally up-to-bottom thoroughly checking periodically may be the most secure method, but impossible in practice.

Reference


Read More...

Tuesday, October 30, 2012

Chinese Blog Site: diandian

Weibo is my favorite twitter. In Chinese it means micro blog. Weibo is very populate in China. I have seen some English tweets there. Today, I noticed one my of followers has moved his blog from Sina blogger to Diandian web site. This caused my interest.

Actually I like Sina blogger very much. It has some nice features. However, the only thing I miss is the CSS and HTML control. I cannot define my CSS classes and HTML scripts there. That's why I prefer Google's Blogger. I have my duplicate Chinese blog at Blogger as well. For sure, it is also for backup purpose.

点点 or dian dian in Chinese means bit by bit. As it says in Diandian's about page, all the complicated contents starts from simple points, then lines, curves, pixels, text and more. Its motto is Let blog start simple"(in Chinese). The overall look of dian dian blog site is very simple and clean. Of course, the most attractive point is the feature of customized CSS and HTML with Javascript.

Based on some articles on TechRice, Diandian is a copy of Tumblr, which is popular web based blog service. I tried to explore Tumbler, but I could not find a reason to switch to this site, even it says that you can customized everything.



Although the following diandian.com home page looks like Trumblr.com, there is difference, blank page on diandian.com. According to diandian's plan, they will have some distinctive features for bloggers.



There are many great web services in China. I don't mean I want to get the best blog web site, but I am interested in one with features I want. In addition to that, the popularity and reliability are also very important. I am going to ask my Weibo follower about it. I really like to move my Sina blog to another simple and powerful blog site in China.

I'll keep my update about Chinese blog if I make any significant changes.

References

Read More...

Sunday, October 21, 2012

Mac OS Security: Gatekeeper (1)

Mac Mountain Lion OS 10.8.2 introduced some new changes in the area of OS security. In this blog I am going to explore the first one: Gatekeeper. It is a very interesting concept. Security concern has been with computer OS since it started. How to protect user data, information, and their privacy has become one of most important issues in personal computers. Even Apple's Mac OS has been very strong in terms of fighting computer virus or malware, with the population of Internet, Apple has realized the potential danger of malware invading Mac OS. Macs still takes very  small market share, comparing to Microsoft Windows. This has been used as an excuse for Mac not having much malware attach. However, Apple is aware the potential attack, and has been keeping very close eyes on the battles of malware against to personal computers.

Based on the information from the past WWDC, there some seminars on Mac security issues. I noticed that Apple has learned lessons in this battle. In this battle, most security focuses have been mainly on defensive side. For example, wildly used anti-virus softwares are always one step behind malware. As a result, Windows treats apps from Internet as potential malware and prompt daunting warning messages to let user to make decision to accept them or not. Apple thinks that this would be a never-win-war.

In Mountain Lion OS, Apple introduced Gatekeeper concept. This is based on a very different concept. In stead of black-kist strategy, Apple implements white-list strategy. This is very analogous to security gate in reality. Security guard will allow any one to enter as long as they have proper id card. Alarm will be on if a faulty or unauthorized id is present. As a part of Gatekeeper strategy, Apple asks all the Mac application developers to apply for Apple developer's id. Apple recomments developers to sign their applications with their ids.

Hence Mountain Lion OS introduced a big change. In order to smooth the transition to this new security practice, the new Mac OS provides three convenient options for Mac users to install apps:

  • Mac App Store 
  • Mac App Store and identified developers
  • Anywhere
With those options, users can temporally loose control on Gatekeeper if they want to install known apps without developer id. You can keep your gate door wide open by allowing Any one, but I think most people will choose the first or second option.


I think this will be a new change in app development. Any developer will require to obtain his/her id if he/she wants to distribute apps through internet.

Read More...

Monday, October 15, 2012

VIM Tips: Multiple Commands

This tip may be too simple and not not the best way to do it. However, it saves my tremendous time. Last week, I was going to bring my Visual Studio solution to my work. This solution contains a lots of projects. I realized that there are some namespaces and copy right issues to be updated. I could use VS to do it. But the VS at work is a new one, without tools like Refactory tool, CodRush Express, Resharper.

I did not like the native Find & Replace in VS. I decided to use VIM to do the job. The challenge I faced was that, first, I had to find all the files contains the strings I would like to replace, and secondly, do the find and replace for each file.

I used TotalCommander tool to do the search. It has built-in find feature and it is very powerful. I can easily get the search result files in one panel. Then I added a tool bar associated with VIM (set parameter %P%N). It is a very cool tool.

Next, I tried to use VIM to do replacement manually. I had too many .cs files. It was just to tedious. Then I searched for a way to do replacement, then save the changes and quit. Can I do three commands in one line? Soon I found a way to do it:

:%s/searchpattern/replacement/g | write | q

In VIM the pipe char is used to link a list of commands. This made my job much quicker. Afterward, I found that this could be done on command line like this:

gvim -c "%s/searchpattern/replacement/g | write | q" test.cs

I think that there must be a better way to run a chained command in a Windows command console: first finding all the files containing expected strings, and next using gvim to do the replacement.

Reference




Read More...

Wednesday, October 03, 2012

VIM Tips

Recently I was working on a project to set up a new server. The new server is a replacement of existing one. One of issues I tried to resolve is to migrate permissions from the existing server to the new server. The problem is that there are too many folders to be checked, 4k folders. I need to find a way to export permissions for each folder to a text file.

Quickly I found a command to get permissions:

cacls.exe folderName

It was very nice to find out this command. Then I use Tree to export folders to text file and edited the text file as a batch file. This is a simple batch file, but a long list of folders.

@cacls folder1 > perm.txt
@cacls folder2 >> perm.txt
...
@cacls folder4000 >> perm.txt

I encountered a problem. Some of path was wrong. I think I may missed some parts of their paths. To find out which one is not valid is a challenge. I need to find a productive way to do that. I knew the following command is a convenient way to detect valid path:

@IF NOT EXIST %folder1 ECHO %folder1

I used VIM to help me to create another batch file based on my above batch file. I used the following VIM replacement command to trim my batch file:

:%s/@cacls //g
:%s/ > perm.txt//g
:%s/ >> perm.txt//g

Those are simple VIM find and replace commands. Now I have a list of paths left:

folder1
folder2
...
folder4000

Then I use find and replace with group command to repeat folders with ECHO command:

:%s/\(.*\)/\1 ECHO \1/g

where \(xxx\) is a group. Finally I insert prefixing IF command at each line the the command:

:%s/^/@IF NOT EXIST /g

where ^ is the beginning of line. With above commands, my new batch file was created.

@IF NOT EXIST folder1 ECHO folder1
@IF NOT EXIST folder2 ECHO folder2
...
@IF NOT EXIST folder4000 ECHO folder4000

Soon I found invalid folders and quickly I fixed my scripts.

Read More...

Friday, September 28, 2012

Open Excel File by Double Click

Recently I had experience a problem at work. I cannot open Excel files by double click them. I tried to open from Excel Open menu and it works fine. I have no problems to open other files such as word or txt files.

I checked my other colleagues and they don't have the issue. One of my friend recommended me to find solution from web by googling. Soon I found a solution. This is something related to Excel registry settings. Since the complexity of Windows registry, it is not recommended to directly edit or change settings there. I found that there is file association from File Explorer. Here is what I did.

First, open File Type from Tools menu, locate the XLS (notice the upper case):



Click Advanced button, the following dialog is displayed.



Select Open in Action list. Click on Edit button:



Make sure to clear Use DDE, then click OK. Apply changes. This will be double click on Excel default behavior back.

Reference


Read More...

Tuesday, September 11, 2012

iOS and New iPhone in Tomorrow's Special Event

Apple has been doing special event to release news about devices and software in past years. I have been kept close look at those events since I got my first iMac in 2007. Tomorrow, September 12, 2012, will be another special event.

A lots of rumors are focused on new iPhone or new hardware devices. What I am actually interested in is the formal release date of iOS 6. I have been waiting XCODE update with iOS 6 support this Fall. I have watched WWDC 2012 videos about iOS 6. I really like the new features in iOS 6, both in Objective-C and new UI components. My next app will use some of those new features.

I'll update this blog after all the news will be released in tomorrow's Apple special event. This will determine how I'll be back working on my apps.

Today, September 12, 2012, Apple made a long list of announcements. iPhone 5 looks gorgeous. The most interesting news for me is the iOS 6 release date. It will be available in one week time, next Wednesday, September 19, 2012, before iPhone 5 release (on September 21, 2012). Not sure when the XCODE update will be available.

I am still watching today's Keynote speech, 1 hour 53 minutes. First time in almost 2 hours. I think my internet has some problems, or the Apple site streaming may have issues. I had several times frozen during AirPlay Mirroring. When I went back to my iMac, I still has similar issue. The reason I suspect internet provider issue is that my QQ app lost connections several times. Anyway, I am going to back to the speech.

Read More...

Sunday, September 09, 2012

Get Caller Class Context and Caller Method Names

In my MyLog class, I prefer to print class name and method name in my log messages. What I did before was to use hard coded strings. This practice makes the maintenance difficult, specially when class or method names are changed.

Later I found two nice Cocoa C-Functions to achieve the same result, without any hard-coded strings. Those functions are great way to get context class and method names. Therefore, I added them to MyClass as convenient macros:


#define CALLER_SELECTOR_NAME NSStringFromSelector(_cmd)
#define CALLER_CONTEXT       NSStringFromClass([self class])

Here are examples to use CALLER_CONEXT to initialize MyLog instance and use CALLER_SELECTOR_NAME to get method name:

// ExampleClass1.m
#import "MyLogger.h"
...
@property (strong, nonatomic) MyLogger* logger;
...
@implementation ExampleClass1
...
@synthesize logger;
- (MyLogger *) logger {
   if (!_logger) {
       _logger = [[MyLogger alloc] initWithContext:CALLER_CONTEXT];
   }
   return _logger;
}
...
- (void) viewWillAppear:(BOOL)animated {
   [super viewWillAppear:animated];

   [self.logger debug:
    ^{
        return [NSString stringWithFormat:@"'%@' is called!",
               CALLER_SELECTOR_NAME];
     }
   ];
...
}
...
@end

Here is the result in the debug console:

2012-09-09 14:23:44.990 TapToCount[5260:c07] [DEBUG] ExampleClass1 - 'viewWillAppear:' is called!

Reference

Read More...

Monday, September 03, 2012

Update: MyLog with Block

I wrote a utility class to log messages in Objective-C long time ago. I updated the class with block early this year, which is similar as delegate in C#. The reason I like to use blocks is that I think, it will improve my app performance.

Here is what I did before, taking info as an example:

- (MyLogger*) info:(NSString*)messageFormat, ...;

A message string is passed to info method by using a list of dynamic string parameters. No matter if I enabled info logging level or not, the message string would be built on call.

By using a block, the string is built within a dynamic block of codes. The bock is actually a pointer to a function. The block of codes may not be executed at all if the logging level is not enabled. Therefore, I think this strategy would improve app performance.

typedef NSString* (^MessageBuildBlock_t)();
...
- (MyLogger*) info:(NSString* (^)(void))msgBuildBlock;

The block is defined as a function returning a string. Then the block is used as a parameter for info method.

Reference

Read More...

Sunday, August 26, 2012

Objective-C: Using Swapping to Mock Method Impelmentaion

Recently I read an interest blog on Unit test in Objective-C. A customized class is defined as method-swizzling helper. With this helper class, two methods in two difference class can be easily swapped at runtime. Therefore, by using this strategy, you can easily mock method calls avoid calling to database or making HTTP requests.

The key points for this helper class is based on Objective-C runtime functions.

class_getClassMethod(...)
method_exchangeImplementations(...)

The first method is used to get a class method as a data type Method. The original and swapped methods can be obtained by this function call. Then the second method is used to make an exchange of method implementation.

The blog has an example of this usage. It looks very easy to make a mock of a method implementation, which is a key practice in unit tests.

Reference


Read More...

Saturday, August 18, 2012

Scrollbar in Mac OS

Since 2007, my interest has been shift to iOS and Mac. One thing interesting UI is scroll bar. Apple has changed the behaviour of scrollbar in iOS. The purpose of this change is to utilize the maximum territory space in a scrollable view. The scrollbar will disappear after the view stays static within seconds. To bring it back, you can user touch gestures to swipe the view. All these are handled by OS. This has been in iOS devices for long time.

Since Lion OS,  Apple introduced the similar support in Mac OS. It is a very interesting design. Here is my understanding. The scrollbars (horizontal and vertical ones) are two UI components. When they are visible, they are UI elements with two main purpose:

  1. They provide visual vision of positions of its content, and
  2. They respond to user interaction, moving or scroll to a position when they are clicked or dragged.
When scrollbars are invisible, not only cannot users see content positions or if content is scrollable, users also have no way to interact with scrollbars. In iOS and Mac native applications, this normally does not present any issue. Users can user touch like swipe to check or move content positions.

However, I had a case recently that invisible scrollbars do cause me some trouble. I use web based RDC to connect to Windows. The RDC window was developed in Java, which is based on Java UI component. It does not support swipe gesture. When I saw a blue window, I had no way to scroll its contents even I knew the Start menu there on the bottom behind the window.


What I found there are two solutions to resolve the issue. The first method method is limit to Mountain Lion OS. Windows in ML are resizable by dragging any boarders. By dragging boarders, the scrollbar will appear for a short period of time. With that period, just quickly touch the scrollbar to make a move.


The second solution is to make scrollbars always visible. This can be set in System Preference | General.



Actually, the scrollbar-always-visible looks really ugly after I am getting used to the new-and-clearn views. However, this solution is the only solution when a window is not sizable.

Read More...

Saturday, August 11, 2012

DataGrid and Object Binding

Last week, one of my good friends asked me some questions about using DataGrid in Windows Form app. I looked at his codes. My first reaction, after I saw his codes, was to recommend him using object or class as data source binding instead of SQL or LINQ binding. I have experience using ASP.Net DataGrid with object binding in my previous work proejcts. I like this strategy very much. By using class as data source, as a developer, I have total control of how data being pumped into DataGrid. The comlicated SQL data structure should be left at SQL server side. The .Net project should forcuse on data and UI.

I quickedly showed him an example. First I added an example class MyData as a data object template. Then I added a DataGrid control on a Windows form. I used data source wizard from the form's DataGrid to set up its object data source to MyData. That was very quick and easy, based on my ASP.Net experience. However, the wizard does not provide a way to let me to tell which method the DataGrid to get data. It seems that DataGrid for Window Form is very different from the one for ASP.Net.

After that meeting, one day, I created an example project and tried to figure it out. Now I got the solution. Basically, in the case of Windows Form application, the data source for DataGrid should a be collection, not an object class. It is very different from the case of ASP.Net DataGrid. Since the data source is a collection, the data binding to DataGrid has to be manually added from DataGrid UI wizard. That's very easy to do: adding column header text and data binding property of DataPropertyName.

Here is the simple Windows Form application. I added a DataGrid to Form1.



DataGrid has a designer wizard. Leave the Data Source as default (none). Click on Add Column... to  define data grid columns. For this demo, add two columns: Name and Age, with column header names as: Column Name, Column Age.




In order to bind data to DataGrid, I need to edit columns from Edit Columns... in DataGrid designer. From there, change DataPropertyName to Name and Age.





With above DataGrid settings, I add a simple class of MyData, which will be used as objects to be displayed on the DataGrid with only two properties: Name and Age. I added another static method to return a collection of MyData objects. Here are my simplified codes:

Public Class MyData
 Private m_name As String
 Private m_age As Integer

 Public Sub New(ByVal nameValue As String, _
     ByVal ageValue As Integer)
   m_name = nameValue
   m_age = ageValue
 End Sub

 Public Property Name() As String
   Get
     Return m_name
   End Get
   Set (ByVal value As String)
     m_name = value
   End Set
 End Property

 Public Property Age() As Integer
   Get
     Return m_age
   End Get
   Set (ByVal value As Integer)
     m_age = value
   End Set
 End Property

 Public Shared Function GetObjects() As List(Of MyData)
  Dim list As List(Of MyData)
  list = New List(Of MyData)
  list.Add(New MyData("John", 12))
  list.Add(New MyData("Mike", 21))
  Return list
 End Function
End Class

In reality, this method (GetObjects) should contain codes to get data from database, or to call data bridge to get mapped data from database.

For the Form, the codes are very simple:

Public Class Form1
...
 Private Sub Button1_Click(ByVal sender As System.Object, _
   ByVal e As System.EventArgs) Handles Button1.Click
   Me.DataGridView1.DataSource = MyData.GetObjects()
 End Sub
...
End Class

The basic concept of this strategy is to make the app as simple as possible: only two element in the Windows Form application:

  • a Form with DataGrid as UI; and 
  • MyData as data source template.

In this way, the focuse can be placed on UI, to provide convenient and nice format for client. The data bridge part, which provides data, can be placed in another class, library, or SQL server.

Here is the result of the application:

Read More...

Friday, August 03, 2012

Finished Watching WWDC2012 Videos

Today I finished watching all available WWDC 2012 videos. There 111 video talk shows. I downloaded them in SD format, which are good enough. To view outlines, I found that I can go to HD area to get PDF files. In this way, I can separate videos from PDF files.

WWDC 2012 shows in iTunes grouped in serials. I started from 400 serial, Developer Tools, with 14 shows. Then 700 serial, Core OS, has 14 shows. 200 serial has 42 shows, which is the largest group. Next is 500, with 24 shows in Graphics , Media and Games. 300 serial is for App services, with 11 shows. The last serial, 600, has 6 shows.

I took some notes in Chinese for the first two serials. I cannot keep taking notes for all of the shows.

Reference


Read More...

Tuesday, July 31, 2012

Blogger Challenge

Recently, I have been puzzled by one challenge: update my blogger with a new view. I have been put image as an indicator of the topic in my blog post for long time. What I would like is to place the icon image off the main column just beside my post title, so that it would be much easy to see the topic for each topic, instead of reading title text. It seems simple task, however, with the limitation of Blogger I just cannot make it happen.

Here are what I tried. Starting from blogger template. I found a place to add a div just right before my post title. The div  has a margin like this style:

....
marin:0 -150%;
....

It does show on the left side of my post title. However, within the div, I could not find a way to change image, the icon for my post.

The icon image is defined in my post. It seems that there is no way to set a reference to a blog post element, such as image's src attribute value. There is a variable in blogger's template, but the values are defined within the template.

I might be possible by using Javascript codes. The difficult point is that how I can define a unique DOM element so that I can retrieve element's attribute value? In addition to that, the Javascript codes have to be trigger on Windows load to update out-fly icon images  from posts.

By the time being, I still could not resolve this puzzle. Any suggestions?

Read More...

Sunday, July 15, 2012

Stackoverflow Flaire is added to my blog

Today I finally fulfill my promise to add SO flair to my blog. I found this promise when I searched my blog for "stackoverflow" to see my previous blog on this web service. I soon found my promise on Feb 18, 2011.

To add this section of HTML codes to my blog template should be easy. However, I spent about half hour to do it. For my record, here is what I did.

First open my blog template and edit it. The place I can add is at almost end of the template:

....
<div id='sidebar-wrapper'>
 <b:section class='sidebar' id='sidebar' preferred='yes'>
   <b:widget id='AdSense1' locked='false' title='' type='AdSense'/>
   ....
 </b:section>
 
 <!-- David Chu added this StackOverflow claire here -->
 <br/>
 <p/>
 <p>David Chu&#39;s programming Q&amp;A at stack<b>overflow</b>:</p>
 <a href='http://stackoverflow.com/users/62776/david-chu-ca'>
   <img alt='SO profile for David.Chu.ca'
   src='http://stackoverflow.com/users/flair/62776.png'
   title='SO profile for David.Chu.ca'
   width='208'/>
 </a>
</div>
....

Now the above section of HTML appears at the end of this blog.

By the way, my SO reached to 4k on July 6, 2012. Actually, I have done almost nothing in the past month. It is the time and effort I invested in the past years, the contribution which programmers recognized, to bring my SO this milestone. My reputation points continues to grow, up to 4054 at the time I am writing this blog.

Read More...

Sunday, July 08, 2012

Animation Views

Navigation and Tab Bar controls provide a way to change views. This kind of change looks like one view being completely replaced with another view, or with animation from one view to another view. Sometimes, you may want to both views visible, with one view in transparent mode on the top of another view. This can be done by using UIView animation methods.

Here are some experience when I tried to use technique.

The basic animation method I use is:

[UIView transitionFromView:fromView
                   toView:toView
                 duration:default_animation_duration
                  options:animationTransiationMode
               completion:completion];

I had one issue with this practice with storyboard (iOS 5.0). The view (toView) being on the top of fromView was positioned with an offset from the top.



The above example shows a gap between the navigation bar and the toView (fromView is on the background). As a result, the bottom bar buttons are not visible because it is out of the screen.

This problem can be easily resolved in storyboard. In the storyboard, select the View Controller first. From the right inspector panel, UNCHECK the property: Resize the view from NIB.



With this fix, the result view is displayed as expected.



Reference

Read More...

Monday, July 02, 2012

Reset SQL Server sa Password

Recently I had a request to reset SQl server sa password. The sa was set up long time ago, but it was not documented. SQL as log in was required to set up administration configurations. This kind of case is very common at work. The following are my notes about this experience.

I soon found a solution to resolve the issue. Basically, you need to restart SQL server in single mode first. Then log in to the server machine by using user with Administrative privilege. The steps are very straight forward, however, I was caught for a while with one mistake. You have to put "-m;" in start up parameter at the beginning with no space afterwards.

The following is the screen snapshot of the property page within SQL server configuration tool. By adding "-m;" right at the beginning line of Startup Parameters, the SQL server will be in single mode in the next start up.



Although I was able to reset sa password by using SQL management studio after  SQL server was restarted, I could not log in to SQL server by sa afterwards. It was interesting that the sa Log was set to blocked. I had to unblock it with single mode on second try.  The following was my snapshot of correct setting. Note: the check box of "Login is blocked out" was set when I reset sa password first time.



Reference


Read More...

Tuesday, June 19, 2012

WWDC 2012 Videos Available Now

Today I got news about WWDC 2012 Videos available from Apple's Development site from Weibo. I will be busy to watch all those training videos. The following is the snapshot of iTunes.



Today I only downloaded the first section: Developer Tools with total 28 tracks (14 videos and 14 PDF  slides). HDs are nice but they take too much space and download bandwidth. I only got SD instead, good enough for my, and much quick and less space.

Reference


Read More...