20
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

iBeaconAdvent Calendar 2013

Day 6

iBeaconでクリスマスに備えよう!

Last updated at Posted at 2013-12-05

お初の方は初めまして、夏休みの宿題は夏休みが終わった後にやる派のyoutenです。
この投稿は2013年のiBeacon Advent Calendarの6日目の記事です。

みなさん、Advent Calendar楽しんでますか?

iBeacon Advent Calendar担当の当日、帰宅したらLightningケーブルを会社に忘れてきたことに気づいたのです。Xcode5のシミュレータではiBeaconは動作しないのです。よって肝心の動作確認をいっさい行えていないのですがなんとかなるでしょう。人生にトラブルはつきものです。

さて、そもそもAdvent Calendarってなんでしたっけ?
そうです、クリスマスを楽しみに待つためのものです。

皆さんクリスマスが待ち遠しいですか?僕は24日に休みを取ろうと考えております。
考えている以上のことはありません。

さて、そんなAdvent Calendarらしさを求めて、iBeaconでクリスマスに備えることにしましょう。

ここで振り返って、iBeaconってなんでしたっけ?

「特定の何かがどんな感じで近づいているか、ゆるふわな感じで分かる」

そう、これがiBeaconです。

「クリスマス」「近づく」「ハッピー!」

このキーワードでもうお分かりですね、クリスマス・イブの夜に俺のことを温かく出迎えてくれる嫁をiBeaconで作りましょう。

小さい方のも悪くないですが、やっぱり大きい方がいいですよね、まずiPadを用意します。女房と畳は新しい方がいいって言いますよね、ちょっとスリムなiPad Airで出だしからパーフェクトです。

続いて絵心の無い俺を手助けしてくれるコミPo!さんに手伝っていただいて、嫁の写真を準備します。

xmas_001.png xmas_002.png

xmas_003.png xmas_004.png

もう賢明な皆様には、素晴らしい嫁がどう出迎えてくれるか分かりましたよね。
しかし、ここでさらにiOS7から登場した+αのエッセンスを加えます。手は抜きません。

//
//  ViewController.m
//  XmasBeacon
//
//  Created by youten on 2013/12/06.
//  Copyright (c) 2013年 youten. All rights reserved.
//

#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>
#import <AVFoundation/AVFoundation.h>

@interface ViewController () <CLLocationManagerDelegate>

@property (nonatomic) CLLocationManager *locationManager;
@property (nonatomic) NSUUID *proximityUUID;
@property (nonatomic) CLBeaconRegion *beaconRegion;

@end

@implementation ViewController {
    NSArray *YOME_IMAGE;
    NSArray *YOME_SPEECH;
    AVSpeechSynthesizer *_speechSynthesizer;
    int _yomePhase;
    CLProximity _privProximity;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    YOME_IMAGE = @[@"xmas_001.png", @"xmas_002.png", @"xmas_003.png", @"xmas_004.png"];
    YOME_SPEECH = @[@"あ、帰ってきたかな?",
                   @"おかえりなさい、ごはんにします?おふろにします?",
                   @"それとも、わ・た・し?",
                   @"メリークリスマス、ちゅっ!"];
    
    // iBeacon
    if ([CLLocationManager isMonitoringAvailableForClass:[CLBeaconRegion class]]) {
        self.locationManager = [CLLocationManager new];
        self.locationManager.delegate = self;
        self.proximityUUID = [[NSUUID alloc] initWithUUIDString:@"E0760C30-457E-48DA-80CA-ECF0B8ECD1FA"];
        self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:self.proximityUUID
                                                               identifier:@"yome"];
        [self.locationManager startMonitoringForRegion:self.beaconRegion];
    }
    
    // AVSpeechSynthesizer
    _speechSynthesizer = [[AVSpeechSynthesizer alloc] init];
    
    // Tap
    UITapGestureRecognizer *yomeTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(yomeTapped:)];
    yomeTap.numberOfTapsRequired = 1;
    _yomeImage.userInteractionEnabled = YES;
    [_yomeImage addGestureRecognizer:yomeTap];
    [self updateYome:0];
}

- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region
{
    [self.locationManager requestStateForRegion:self.beaconRegion];
}

- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
    switch (state) {
        case CLRegionStateInside: // リージョン内にいる
            if ([region isMemberOfClass:[CLBeaconRegion class]] && [CLLocationManager isRangingAvailable]) {
                [self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
            }
            break;
        case CLRegionStateOutside:
        case CLRegionStateUnknown:
        default:
            break;
    }
}

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
    if ([region isMemberOfClass:[CLBeaconRegion class]] && [CLLocationManager isRangingAvailable]) {
        [self.locationManager startRangingBeaconsInRegion:(CLBeaconRegion *)region];
    }
}

- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
    if ([region isMemberOfClass:[CLBeaconRegion class]] && [CLLocationManager isRangingAvailable]) {
        [self.locationManager stopRangingBeaconsInRegion:(CLBeaconRegion *)region];
    }
}

- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
{
    if (beacons.count > 0) {
        CLBeacon *nearestBeacon = beacons.firstObject;
        if (_privProximity != nearestBeacon.proximity) {
            switch (nearestBeacon.proximity) {
                case CLProximityImmediate:
                    [self updateYome:3];
                    break;
                case CLProximityNear:
                    [self updateYome:2];
                    break;
                case CLProximityFar:
                    [self updateYome:1];
                    break;
                default: // unknown
                    [self updateYome:0];
                    break;
            }
        _privProximity = nearestBeacon.proximity;
        }
    }
}

- (void) yomeTapped:(UITapGestureRecognizer *)sender {
    [self updateYome:(_yomePhase + 1) % 4];
}

- (void) updateYome:(int)phase {
    _yomePhase = phase;
    _yomeImage.image = [UIImage imageNamed:YOME_IMAGE[_yomePhase]];
    AVSpeechUtterance *utterance = [AVSpeechUtterance speechUtteranceWithString:YOME_SPEECH[_yomePhase]];
    utterance.rate = 0.3f;
    utterance.pitchMultiplier = 1.4f;
    [_speechSynthesizer speakUtterance:utterance];
}

@end

AVSpeechSynthesizerいい感じです。rateやpitchMultiplierを微調整するのをお忘れなく!

それでは皆様、良いクリスマスを!

20
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?