NSUserDefaults Issue on xCode6 Simulator

xCode 6.0.1
在模擬器上砍掉 App 重裝,會發生 NSUserDefaults 無法清除的問題,實機上是正常。

解法方法:
iOS Simulator -> Reset Content and Settings

Using CLLocationManager in iOS8/9/10

iOS8 之後取得授權的方式有所改變。

iOS7:

[_locationManager startUpdatingLocation];

iOS8:

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
if ([_locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
  [_locationManager requestAlwaysAuthorization];
//  [_locationManager requestWhenInUseAuthorization];
}
#endif
[_locationManager startUpdatingLocation];

iOS9:

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8) {
    [_locationManager requestAlwaysAuthorization];
}
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9) {
    _locationManager.allowsBackgroundLocationUpdates = YES;
}

[CLLocationManager authorizationStatus]:

// iOS7
kCLAuthorizationStatusAuthorized
// iOS8
kCLAuthorizationStatusAuthorizedWhenInUse
kCLAuthorizationStatusAuthorizedAlways

You have to update the app's Info.plist file for iOS8.

<key>NSLocationWhenInUseUsageDescription</key>
<string>Hello World</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Hello World</string>

Enable Background Mode for iOS9

target -> Capabilities -> Background Modes -> open the background Modes

Google Maps SDK for iOS

// 抓取螢幕四個角落座標
- (void)showVisibleRegion
{
  NSLog(@"\n%@,%@\n%@,%@\n%@,%@\n%@,%@\n",
        [NSNumber numberWithDouble:_mapView.projection.visibleRegion.farLeft.latitude],
        [NSNumber numberWithDouble:_mapView.projection.visibleRegion.farLeft.longitude],
        [NSNumber numberWithDouble:_mapView.projection.visibleRegion.farRight.latitude],
        [NSNumber numberWithDouble:_mapView.projection.visibleRegion.farRight.longitude],
        [NSNumber numberWithDouble:_mapView.projection.visibleRegion.nearLeft.latitude],
        [NSNumber numberWithDouble:_mapView.projection.visibleRegion.nearLeft.longitude],
        [NSNumber numberWithDouble:_mapView.projection.visibleRegion.nearRight.latitude],
        [NSNumber numberWithDouble:_mapView.projection.visibleRegion.nearRight.longitude]);
}

#pragma mark - delegate

- (void)mapView:(GMSMapView *)mapView willMove:(BOOL)gesture
{
    // ...
}

// This is invoked once the camera position on GMSMapView becomes idle, and specifies the camera positon in question.
// At this point, all animations and gestures have stopped.
- (void)mapView:(GMSMapView *)mapView idleAtCameraPosition:(GMSCameraPosition *)position
{
  if (_isNeedsRemoveMarkers) {
    [self removeMarks];
//  [self showVisibleRegion];
    [self prepareDataFromMemoryWithTimeId:_currentTimeId];
  }
  else {
    _isNeedsRemoveMarkers = YES;
  }
}

- (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker
{
  _isNeedsRemoveMarkers = NO;
  [_mapView animateToLocation:marker.position];
  _mapView.selectedMarker = marker;
  return YES;
}

- (void)mapView:(GMSMapView *)mapView didTapInfoWindowOfMarker:(GMSMarker *)marker
{
  NSLog(@"clicked title:%@",marker.title); // And now this should work.
  _clickItem = marker.userData;
  [self performSegueWithIdentifier:@"SegueFromMapToStoreDetail" sender:nil];  
}

Checking Visible Region

- (void)prepareDataFromMemoryWithTimeId:(NSInteger)TimeId
{
  // filter data by the lat and lon
  NSPredicate *predicate = [NSPredicate predicateWithFormat:@"Lat <= %f AND Lat >= %f AND Lng <= %f AND Lng >= %f", _mapView.projection.visibleRegion.farLeft.latitude, _mapView.projection.visibleRegion.nearRight.latitude, _mapView.projection.visibleRegion.farRight.longitude, _mapView.projection.visibleRegion.nearLeft.longitude];
  _sortedArrayDataSource = [_sortedArrayOriginDataSource filteredArrayUsingPredicate:predicate];
  
  [self generateMarkers];
}

Changing the color of unselected UITabBar icons in iOS7

// tab bar color
self.tabBarController.tabBar.barTintColor = [UIColor colorWithWhite:0.050 alpha:1.000];
self.tabBarController.tabBar.translucent = true;
self.tabBarController.tabBar.tintColor = [UIColor redColor];

// tab bar item color
for(UITabBarItem *item in self.tabBarController.tabBar.items) {
  // use the UIImage category code for the imageWithColor: method
  item.image = [[item.selectedImage imageWithTintColor:[UIColor colorWithRed:0.400 green:0.000 blue:0.000 alpha:1.000]] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
}

Ref

Gradient Mask in iOS

Gradient Alpha Mask in iOS

CAGradientLayer *gradientLayer = [CAGradientLayer layer];
NSArray *colors = [NSArray arrayWithObjects:
                   (id)[[UIColor colorWithWhite:0 alpha:0] CGColor],
                   (id)[[UIColor colorWithWhite:0 alpha:1] CGColor],
                   nil];
[gradientLayer setColors:colors];
[gradientLayer setStartPoint:CGPointMake(0.0f, 1.0f)];
[gradientLayer setEndPoint:CGPointMake(0.0f, 0.6f)];
gradientLayer.frame = uiimageview.bounds;
gradientLayer.layer.mask = gradientLayer;

Gradient View

UIImageView *uiimageview = (UIImageView *)[self viewWithTag:100];
if ([[uiimageview.layer sublayers] count] < 1) {
  CAGradientLayer *gradientLayer = [CAGradientLayer layer];
  NSArray *colors = [NSArray arrayWithObjects:
                     (id)[[UIColor colorWithWhite:0 alpha:0.9] CGColor],
                     (id)[[UIColor colorWithWhite:0 alpha:0.1] CGColor],
                     nil];
  [gradientLayer setColors:colors];
  [gradientLayer setStartPoint:CGPointMake(0.0f, 1.0f)];
  [gradientLayer setEndPoint:CGPointMake(0.0f, 0.2f)];
  gradientLayer.frame = uiimageview.bounds;
  [uiimageview.layer insertSublayer:gradientLayer atIndex:0];
}

Customize User Agent in UIWebView for iOS7

UIWebView 會去 NSUserDefaults 裡找...很神奇...:)

- (void)setDefaultWebViewUserAgent
{
  // Get Default UserAgent.
  UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectZero];
  NSString *agent = [webView stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];
  // Mozilla/5.0 (iPhone; CPU iPhone OS 7_1_2 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Mobile/11D257

  // Save it.
  NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"%@;V Pass WebView", agent], @"UserAgent", nil];
  [[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];
}

Checking Location Service in iOS

- (void)checkingLocationService
{
  switch([CLLocationManager authorizationStatus]) {
    case kCLAuthorizationStatusNotDetermined:
      // User has not yet made a choice with regards to this application
      break;
    case kCLAuthorizationStatusRestricted:
      // This application is not authorized to use location services.  Due
      // to active restrictions on location services, the user cannot change
      // this status, and may not have personally denied authorization
      //break;
    case kCLAuthorizationStatusDenied:
    {
      // User has explicitly denied authorization for this application, or
      // location services are disabled in Settings
      UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Privacy Warning" message:@"Permission was not granted for Location"
                                                     delegate:nil
                                            cancelButtonTitle:@"OK"
                                            otherButtonTitles:nil];
      [alert show];
    }
      break;
    case kCLAuthorizationStatusAuthorized:
      // User has authorized this application to use location services
      break;
  }
}

切換 App 時回到首頁

切換 iOS App 時回到首頁,會用下列兩種方式
applicationDidBecomeActive(第一次執行也會觸發...etc)
applicationWillEnterForeground(只有從背景回到前景才會觸發)
這裡用applicationWillEnterForeground比較適合。

- (void)applicationWillEnterForeground:(UIApplication *)application
{
  UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];
  UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"IntroViewController"];
  self.window.rootViewController = vc;
}

storyboardWithName: Main.storyboard 大小寫有差
instantiateViewControllerWithIdentifier: ViewController's Storyboard ID

Getting Zip Code of Taiwan in iOS

- (NSString *)getZipCode:(NSString *)address
{
  NSString *zipCode = @"";
  
  if (address.length>0) {
    NSString *urlString = [NSString stringWithFormat:@"http://maps.googleapis.com/maps/api/geocode/json?address=%@&sensor=false",[self encodeUrlString:address]];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString] cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:10];
    [request setHTTPMethod: @"GET"];
    NSError *requestError;
    NSURLResponse *urlResponse = nil;
    NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&requestError];

    NSError *error;
    NSDictionary *result = [NSJSONSerialization JSONObjectWithData:response options:kNilOptions error:&error];
    for (NSDictionary *dic in [result valueForKeyPath:@"results.address_components"][0]) {
      if ([[dic valueForKey:@"types"][0] isEqualToString:@"postal_code"]) {
        zipcode = [dic valueForKey:@"short_name"];
      }
    }
    return zipCode;
}

How to Rename a File in iOS

- (void)renameFileWithName:(NSString *)srcName toName:(NSString *)dstName
{
  NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  NSString *documentsDirectory = [paths objectAtIndex:0];
  NSString *filePathSrc = [documentsDirectory stringByAppendingPathComponent:srcName];
  NSString *filePathDst = [documentsDirectory stringByAppendingPathComponent:dstName];
  NSFileManager *manager = [NSFileManager defaultManager];
  if ([manager fileExistsAtPath:filePathDst]) {
    //removing the old file
    NSError *error = nil;
    if (![[NSFileManager defaultManager] removeItemAtPath:filePathDst error:&error]) {
      NSLog(@"Could not remove old files. Error:%@",error);
    }
  }
  if ([manager fileExistsAtPath:filePathSrc]) {
    NSError *error = nil;
    [manager moveItemAtPath:filePathSrc toPath:filePathDst error:&error];
    if (error) {
      NSLog(@"Error: %@", error);
    }
  } else {
    NSLog(@"File %@ doesn't exists", srcName);
  }
}