Categories
Fun iPhone app Life Tips

Back up iPhone iPad photos

Reading Time: < 1 minute

I learned the lesson the hard way. Almost a year ago, I left my former employer, and I had to turn in my iPhone 4s. Being a computer professional, I knew the backup thing, so I backed up the photos to iTunes, both via iCloud and via iTunes to PC. But I forgot one more backup, to the iPhoto on my Mac. The backups on iCloud and iTunes are good, but I can not view the individual photos from there, and eventually I got a new iPhone 5s and got the backup iPhotos to my new iPhone this way. The first thing I did after I receiving my new iPhone is to restore the photos, and backup to iPhoto on my Mac.

I did one more thing, as I learned from my Nexus 4 experience, is turn on auto back up on google+. I paid $20 extra for the additional 10gb space on iCloud (for one year), when the time of renewal comes, I plan to cancel it, as now I will do backup via iPhoto, iTunes and google+.

Personally I felt the management of all these photos on iPhone/iPad is an interesting project. With Apple TV, I did see I play videos on iDevices more, and sometimes even slide show the photo. I did this quite a few times to my young daughter, when I found that’s more fun than the Netflix TV shows 🙂

Categories
advice and tips Fun

I failed persuade Yoyo go to Gymnastics class

Reading Time: < 1 minute

And I regret it now, because she appears have a lot energy after getting home. But at pre-school when I picked her up, she was complaining about “lip hurts” (probably due to cold weather, and low moisture indoors), and “fear of doing high beam”. No matter what I offer (snack, chocolate), she was not motivated, and cried while asking for “go home”. I can understand both factors, and I feel the high beam is probably a more important factor, but I chickened out eventually. It’s also one of the coldest day this winter (minus 10 c). And I feel a lack of energy myself, so I “let it slide” (borrowing Steve Job’s word).

But I quickly regret it as I saw she is full of energy after getting home, esp. when doing the Skype with grand parents and her aunt/cousin back home.

Categories
Life Life Tips

Year 2013 in review

Reading Time: 2 minutes

Job
I changed too much. Three W-2 in one year. I hope to stick with my current employer for a while.

Family
Our daughter grew up quickly. She brings us joy that words can not be easily described. And frustration sometimes, too. I think patience is very important being parent. Near the year end, we have some exciting news, as my writing (couple days ago Jan 14, 2014 we knew we will welcome a new baby girl in this July 🙂

iOS apps
I did update the myNestEgg app, after 2 years, from iOS 3.1.2 to iOS 7. And I released a new app “To Market ~ farmers market around St. Louis”, this is a free iOS app. I am experimenting some new features there.

Stocks
I was looking at my stock trades in last few years. I realized year 2012 is not good, while 2013 is ok (has not beat market in my Scottrade IRA brokerage account because again I tried to do too much). Looking back a bit more, in year 2010 I made some mistakes on Palm and other stocks, in 2012 it was the Coal stocks (ACI and ANR). It seems I tend to lose money on high volatile cheap stocks (the former high flyer etc, hope it goes back).

The more I think about it, as I was also reading “year 2012 in review“. Once again I am thinking if I can not beat the market, I should pick the index fund, or go with the fund manager I believe in (Steve Romick). His FPA Crescent has done very well for me in last 4 years.

(01-23-2014) I gave it more thought after seeing Logitech (LOGI) jumped more than 20% this morning on beat estimates on earning, and on the news its transition from PC mouse to iPad keyboard worked out. I bought the stock a year ago at about 7.50, hold it only a day. Similar can be said for Logmein (LOGM), which also more than doubled in a year (I owned more LOGM at one time). Anyway, have faith on bad news, though near term when looking back, at the time it’s not easy.

(02-06-14) This annual review is partially inspired by Kirby Turner (whitepeaksoftware.com), congrats to Kirby on his 10 years anniversary of his company. I met him once at an iOS conference in 2010 and was impressed by his iOS/Mac knowledge.

I also recall Kyle Richter talk about doing iOS consulting at RayWenderlich.com to be interesting.

Categories
iPhone app Life Tips

UP band a few months later

Reading Time: < 1 minute

(Update 02-06-2014) My UP band died. I fully charged it, tried both soft reset and hard reset, as discussed below, but seems could not revive it.

The following was written on Nov. 14, 2013. I have a bit more experience with UP band since then, note Jawbone also came up with new UP 24, which has bluetooth connectivity with the smartphone. Also, Fitbit released the app for iPhone 5s which has the basic pedometer functionalities, I just started using it and so far so good.

Good
Does the job, record walking steps and sleeping time

Bad
Need to reboot the iPad sometimes to get sync

The corrosion, partially my dumb mistake

Odd
The switch from “sleep” to “walk” is automatically most of the time. but not the other way around. Occasionally I saw the UP band flashes (both sleep and walk indicators), or would not sync. There is this soft-reset, and I found turn off iPad (iPhone) and turn it back on solves most sync issue.

Categories
advice and tips iPhone app

Prepare for shipping of Nexus 4 phone

Reading Time: < 1 minute

I sold it much quickly than I thought (sold right after I posted on Amazon on Nov. 18, 2013), and I did back up photos using 3 approaches.

1) Dropbox;

2) Back up to PC using the backup utility on the Phone;

3) Google+

After using google+ backup on my Nexus 4 for a while, I liked it and decided to give it a try on my iPhone and iPad. I enabled the auto backup feature. There is a limit for each account, I believe. An interesting thing I found out about google+ in the new year, is it creates a slideshow (about one minute) using the photos in google+, for me it’s mostly about my daughter’s activities. This reminds me of Facebook year in review feature (kind like year book). One thing keep in mind is the privacy, if you decide to share it, the default setting it share to public, so use your judgement when you share.

Categories
iOS

UITableView update problem

Reading Time: < 1 minute

It appears the UITableView cells created via storyboard is not updating correctly, say, if we want to add or delete a row. It only update once. The workaround in this case is creating the rows programmatically (instead of static tags from storyboard).

Similarly, I recall the JSF Richfaces paging problem when add/delete a row which results in the number of pages change.

I am guessing one possible cause of this type of problem is the update process runs into deadlock.

Categories
iOS

Another simple data grid example on iOS

Reading Time: < 1 minute

I came across this example in Jan 2012 (almost 2 years ago :-). A lot has changed in iOS landscape, but the author did a good job designing the application, I think.
Displaying Tabular Data on iPhones (Tom Thompson, overview of UITableView)

Making Two-Way Tables in iOS

(a two dimensional table, with text field as input)

Categories
Featured iPhone app

Send Email via Cloud Code in Parse

Reading Time: 2 minutes

(Update 05-10-2016) Came across this post about hosting your own Parse server from raywenderlich.com

(Update 01-28-2016) All good things came to end (see today’s Facebook announcement on shutting down Parse on January 28, 2017, a year from today). They also listed migration path. A lot discussion on reddit on this topic. Also a tutorial on Firebase by raywenderlich, note Firebase is owned by Google (they are also famous for shutting down things 🙂

(Update 10-12-2015) Here is the “get started on Cloud Code“. This talks about how to set up the Parse cloud code (including email), the integration with Mandrill is also there. You will need two accounts (both are free for small apps): Mandrill and Parse. Just replace the keys in my code below and in the parse command with your own keys. I also create a github repo here. It has a README just like this blog post and has all the cloud code.

(Original 11-24-2013)
The cloud code (javascript)
refer to this stackoverflow thread; and this Parse documentation. Note I used ManDrill (free for up to 12,000 mails per month), the main things I noticed is they requires 10 letters password, and the API key can be created in Settings (this will be used later, we will use API key instead of SMTP server)

cat ./cloud/main.js

// Use Parse.Cloud.define to define as many cloud functions as you want.
// For example:
Parse.Cloud.define("hello", function(request, response) {
response.success("Hello world!");
});

Parse.Cloud.define("sendMail", function(request, response) {
var Mandrill = require('mandrill');
Mandrill.initialize('12AkxxxxxxxxxxxxxxrZEg');

Mandrill.sendEmail({
message: {
text: request.params.text,
subject: request.params.subject,
from_email: request.params.fromEmail,
from_name: request.params.fromName,
to: [
{
email: request.params.toEmail,
name: request.params.toName
}
]
},
async: true
},{
success: function(httpResponse) {
console.log(httpResponse);
response.success("Email sent!");
},
error: function(httpResponse) {
console.error(httpResponse);
response.error("Uh oh, something went wrong");
}
});
});

To test it out, do the “parse deploy” after put the code above in main.js (under cloud dir), then issue this command:
curl -X POST -H "X-Parse-Application-Id: your-parse-application-id" -H "X-Parse-REST-API-Key: your-parse-REST-API-key" -H "Content-Type: application/json" -d '{"toEmail":"major_xu@yahoo.com","toName":"Major Xu","fromEmail":"minjie.xu@gmail.com","fromName":"Minjie Xu","text":"testing ManDrill email","subject":"this is just a test"}' https://api.parse.com/1/functions/sendMail

Objective-C code
Refer to Parse documentation here. Note this is a simple “Hello World” example.
[PFCloud callFunctionInBackground:@"hello"
withParameters:@{}
block:^(NSString *result, NSError *error) {
if (!error) {
// result is @"Hello world!"
}
}];

My email code is a bit more complex compared to “HelloWorld” 🙂


[PFCloud callFunctionInBackground:@"sendMail"
withParameters:@{@"toEmail":toEmail,@"toName":@"Minnjie Xu",@"fromEmail":@"uudaddy@gmail.com",@"fromName":@"uudaddy",@"text":@"resetPasswordButtonPressed...",@"subject":@"myNestEgg ~ testing ManDrill email"}
block:^(NSString *result, NSError *error) {
if (!error) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Reset Passoword" message:@"Email Sent :-)"
delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil];
[alert show];

}
}];

Categories
advice and tips iPhone app

Two good articles on touch screen generation

Reading Time: 2 minutes

Atlantic

CS monitor

My take:
My daughter is 3 and half years old. My wife had iPhone (3g) before she was born, and I bought iPhone 4 when she was 6 months old. Then comes the iPad (1), and currently I have an iPad mini, and my wife has iPad 4. I spent about $30 buying apps for my daughter (mostly Toca Woca and Sigo Mini; also raywenderlich WildFable; and I see Ewe, I Hear Ewe). I felt the latter is better suitable for toddlers, while the former ones are more like games (which I have some reservations).

My observations on iPad app and screen time: my daughter also watches Netflix kids TV/Youtube for about half an hour a day. We tried pretty hard to make sure she did not watch too much TV before she was two (again, this is mostly from hearing her teachers’ advice; and from reading the articles about TV’s effect on growing children).

My thoughts:
1) Moderation, moderation, moderation. It’s not easy. I know, we all have been there. Grabbing iPad/iPhone from crying toddlers. “5 more minutes”. But we need to be firm. Otherwise the 5 more minutes will means 15 more minutes. And the flood gates started here. I found out, if I’m consistent, and if the child is tired of the silly game/TV, and if we can provide a better alternative (reading books, something more fun), she gives up iPad quickly.

2) Engagement, engagement, engagement. When she was very young (probably around 2), sometimes we let her watch the “Curious George” on Netflix, together with parents. And she will have a lot of questions. In that sense, watching TV is not purely passive, and that’s a good thing. Same can be said of reading/listening the wild fable, and the I see Ewe/I hear Ewe.

Categories
iPhone app

Some roadblocks and tips when updating app for iOS 7

Reading Time: 2 minutes

Recently I’ve worked on updating one of my app to make it works on iOS 7, and have encountered some roadblocks.

Push view controller
problem/symptom: the new view controller pushed from old view controller shows no content, on iOS 7. It works fine on iOS 6.1 (the deployment target is still iOS 6.1).

solution/diagnose: I found the following code snippets by Sourabh Kumbhar at mobinett very handy when debugging those kinds of issues.

Put the following in the viewDidload of the view controller got affected by iOS upgrade.
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7)
{
self.edgesForExtendedLayout = UIRectEdgeNone;
}

Back to the original problem. Animation problem? I did quite a few googles trying to find out if the animation change is the cause here, but to no vail. Depends on the view, fix it in viewWillAppear or use NSNotification to make sure the viewDidLoad calls after the view property gets reset (web view).

Old code
MarketDetailViewController *marketDetailViewController =
[[MarketDetailViewController alloc] initWithNibName:@"MarketDetailViewController" bundle:nil];

// Set the title of the detail page
[marketDetailViewController setTitle:product.name];

// Push the detail controller on to the stack
[self.navigationController pushViewController:marketDetailViewController animated:YES];

// Populate the details
[marketDetailViewController setLabelsForProduct:product];

-(void) setLabelsForProduct: (Market*) theProduct
{
NSLog(@"inside setLabelsForProduct, time =%@", theProduct.time);

// Set the text of the labels to the values passed in the Product object
[nameLabel setText:theProduct.name];
[manufacturerLabel setText:theProduct.city];
[detailsLabel setText:theProduct.state];
[priceLabel setText:theProduct.phone];
[quantityLabel setText:theProduct.produce];
[daysLabel setText:theProduct.days];
[self.timeLabel setText:theProduct.time];
[startDateLabel setText:theProduct.startDate];
[endDateLabel setText:theProduct.endDate];
[emailButton setTitle:theProduct.email forState:UIControlStateNormal];
[webButton setTitle:theProduct.web forState:UIControlStateNormal];
}

New code
- (void) viewWillAppear:(BOOL)animated{
NSLog(@" MarketDetailViewController::viewWillAppear");
[super viewWillAppear:animated];

[nameLabel setText:theMarket.name];
[manufacturerLabel setText:theMarket.city];
[detailsLabel setText:theMarket.state];
[priceLabel setText:theMarket.phone];
[quantityLabel setText:theMarket.produce];
[daysLabel setText:theMarket.days];
[self.timeLabel setText:theMarket.time];
[startDateLabel setText:theMarket.startDate];
[endDateLabel setText:theMarket.endDate];
[emailButton setTitle:theMarket.email forState:UIControlStateNormal];
[webButton setTitle:theMarket.web forState:UIControlStateNormal];
[self.view setAlpha:1];
}

-(void) setLabelsForProduct: (Market*) theProduct
{
NSLog(@"inside setLabelsForProduct, time =%@", theProduct.time);
...keep all those setters here...otherwise it will break iOS 6.1
theMarket = theProduct;
}

Web View
Similar idea, but I used NSNotification to fix the problem in iOS 7.

self.webViewController = [[WebViewController alloc] initWithNibName:@"WebViewController" bundle:nil];
// Set the title of the detail page
[self.webViewController setTitle:[nameLabel text]];

[self.navigationController pushViewController:self.webViewController animated:YES];

NSLog(@"[product web] = %@", [[webButton titleLabel] text]);

// The following works in iOS 6.1, but no longer in iOS 7
//[webViewController refreshView:[[webButton titleLabel] text]];

add the following to the viewDidLoad of parent view controller
// Listen for new image uploads so that we can refresh the image wall table
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(webPageDownloaded:)
name:N_WebPageDownloaded
object:nil];

In the web view controller, viewDidload, add
[[NSNotificationCenter defaultCenter] postNotificationName:N_WebPageDownloaded object:nil];

refreshView is the same:
-(void) refreshView:(NSString*)webAddress0
{
self.webAddress = webAddress0;
[self.myWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:webAddress0]]];

CGRect textFieldFrame = CGRectMake(kLeftMargin, kTweenMargin,
self.view.bounds.size.width - (kLeftMargin * 2.0), kTextFieldHeight);
UITextField *urlField = [[UITextField alloc] initWithFrame:textFieldFrame];
...some code to render the urlField, omit for the sake of readability...
[self.view addSubview:urlField];
}

// the call back being called when posting Notification
- (void) webPageDownloaded:(NSNotification *)notification
{
[self.webViewController refreshView:[[webButton titleLabel] text]];
}

Code signing
symptom: when submit to app store, it will say no valid provision profile can be found. In some cases Xcode will crash for that project. If the user tries to submit an ad-hoc package (ipa file) via Application Loader, Apple will send “invalid signature” email right away, reject that binary. And I found following solution at stackoverflow.com
old distribution provision profile no longer work, create a new one for Xcode5