MILLEN BOX

音楽好きの組み込みソフトエンジニアによるプログラミング(主にiOSアプリ開発)の勉強の記録

リリースアプリのアップデート

iOSアプリの開発を始めて2年半経ちました。そして5本のアプリをリリースすることができました。

始めた当初はとにかくリリースすることが精一杯。
それに反して溢れてくるアイデアとの折り合いをつけるのがとても大変でした。
なので出したら出しっぱなし。メンテナンスなんてしてませんでした。と言うかできませんでした。
新しいものを作りたい、けどコード書くのは遅い。そしたら出したもののケアは「取り敢えず後回し」になって。そして次第にそのことを忘れちゃって。

このようなループから最近抜け出しつつあります。
出したものについてある程度のケアをする (=アップデートをする) よう心がけています。

なぜ抜け出しせたのか? 順を追って説明していきましょう。

事実1 直近リリースした2つのアプリを気に入っている

一つ目としては、直近リリースした二つのアプリ、 ポーン - プロフェッショナルな名言をカウントしようぼかすん - 背景ぼかし & 消したい部分を簡単に隠せる への思い入れが強いことが関連しています。
かわいい子達の手入れを出来るだけしてあげたい。そんな思いが生まれます。

事実2 新規でアプリを起こすのに大変エネルギーがいるようになった

二つ目としては、先に述べた二つのアプリのお陰でリリースしようと思うハードルが自分の中で上がってしまったことが関連しています。
それまでは気にしていなかった部分についてもケアするようになり、アプリ一つを新規で起こすことが大変エネルギーのいる作業と感じるようになってしまっているのです。

事実3 新しいことは試したい

新規でアプリを起こすのは大変だけど、新しいアイデアや新しく覚えたことは試したいのです。

じゃあリリース済みのアプリをアップデートすることで新しいことを試せばいいんじゃない?

そう。新規でアプリで作るにはエネルギーはいるものの既存のアプリに新機能を追加するのであれば、新規で起こすのに比べれば全然負担は楽。
尚且つ、可愛いアプリ達がよりいいものになるので一石二鳥。

と言うわけで最近はそれ以前のものも含めて、楽な気持ちでアップデート出来るようになってきました! これは良いことだなぁと個人的には感じています。

ポーン - プロフェッショナルな名言をカウントしよう は名言メモ機能(以下の画像や動画の保存)の追加、ぼかすん - 背景ぼかし & 消したい部分を簡単に隠せる はぼかしエフェクト(モザイクとクリスタル)のリリース時に比べ追加しています。 もし良かったら試してみて下さい!

f:id:anthrgrnwrld:20170915183250j:plain f:id:anthrgrnwrld:20170915183352p:plain

swiftでの配列の初期化方法について

本日は配列の宣言についてメモ書きしておきます。 勘違いからミスってしまって解決するまでの流れを書いていきます。

以下みたいな感じでfor文で配列imageArrayにボコボコ値(UIImage型)を入れていきたい場合を考えます。

for i in 0 ..< numberOfPicture {  
    imageArray.append(UIImage(named:"\(i).png")!)  
}  

この場合、上記処理の前に配列imageArrayについて宣言をしておかなければなりません。
僕、初め以下のように宣言しちゃっていたんですね。

var imageArray: [UIImage] = [UIImage()]

この誤った宣言で処理を進めるとどうなるのか。

例えばpngファイルが1.pngから5.pngの5枚あった場合を考えましょう。つまりnumberOfPicture = 5の場合です。
期待する処理A後の要素数 imageArray.count は勿論5です。 しかしながら誤った宣言で処理Aを実行した後の imageArray.count は6になってしまうのです。 期待値としては1.pngはimageArray[0]に入っていてほしいし、5.pngはimageArray[4]に入っていて欲しいですが、1.pngはimageArray[1]、5.pngはimageArray[5]に入っています。

なぜ期待した値より1増えたメンバー数となるのか。

誤った宣言部をもう一度見てイコール以降の右辺部に注目して下さい。
[UIImage()]となっています。
この場合、配列の0番目には空っぽのUIImage型の何かが入ってしまうのです。
その配列に処理Aで書いたような形でappendを使用してメンバーを追加した場合はどうなるか?もうお分りと思います。
appendは既存の配列の最後にメンバーを追加するものなので、1.pngはimageArray[1]に追加されるし、5.pngはimageArray[5]に追加されてしまうのです。

解決策は?

誤った宣言部を以下のように直して下さい。

var imageArray: [UIImage] = []

これで期待通りの動作をするはずです。

思ったこと

実は空っぽの配列の宣言をする時、いつもどのように書こうか迷っていたんですよね。 今回スッキリできてよかったです。

新しいアプリをリリースしました!名前は「ぼかすん」です。

タイトルの通り、新しいアプリをリリースしました!
「ぼかすん」という名前の画像編集アプリでございます。

関西弁です。「ぼかすやつ」という意味になります。
指でなぞったところをぼかすことができます。

f:id:anthrgrnwrld:20170720231345p:plain

なぞってぼかすだけじゃなく、モードを変更することでタップによる円ぼかしも実行可能です。
またスライダーで調整することによりドローサイズも変更できます。
スライダー上部ボタン「サイズ」が有効時に反映されます。

f:id:anthrgrnwrld:20170720231557p:plain

ぼかし度の変更は「ぼかし」が有効時に反映されます。 実行済みすべての箇所に反映されます。

f:id:anthrgrnwrld:20170720232220p:plain

消しゴムモードでなぞった部分をぼかす前の状態に戻すことができます。 画面全体をぼかした後に強調したい部分にこの機能を使用することで、効果的な写真へ変化させることができます。

f:id:anthrgrnwrld:20170720232527p:plain

編集完了後にはカメラロールへの保存の他に、Twitter, Facebook, Instagram, 他のアプリへ直接シェアできます。
以下のリンクの時期にシェアの仕方を調べてました。

f:id:anthrgrnwrld:20170720232751j:plain

anthrgrnwrld.hatenablog.com

anthrgrnwrld.hatenablog.com

ちなみにBarの類の表示処理にはUIVisualEffectViewを使用しています。
このアプリのメニューのお洒落さを全力で感じるために
[設定→一般→アクセシビリティ→コントラストを上げる→透明度を下げる] をOFF設定にして使用頂きたいところですね。

anthrgrnwrld.hatenablog.com

anthrgrnwrld.hatenablog.com

このような感じのアプリですがいかかでしょうか??
制作期間は1年超…。
電車の中オンリーの開発とはいえ、時間をかけすぎました。
まぁしかしなかなか勉強になったのは事実でして、それは良かったなと感じております。

因みに公開開始から5日間でダウンロード数が200を超えております。
ヒットアプリなんかと比べると足元には及びませんが、なかなかいい手応えのダウンロード数と思っております。
すぐに新機能を追加したアップデートをして、この感じを途切れさせないようにしたいな〜と感じております。

UIButtonにセットした画像のcontentModeが効かない?そんな時の対処方法

お久しぶりの更新です。

通常はいつもMacを使って更新するんですが、実験的にiPhoneはてなブログアプリからアップしてみます。お見苦しい点ありましてもお許し願いたい!!

 

UIButtonにセットしたUIimageViewの画像のcontentModeが効かない問題

ある日、リリースされたばかりアプリを意気揚々と家族(妻)とダウンロードした時のことです。

まず私のiPhone 7では上々に動作。よしよし、いい子だ。

次に妻のiPhone 6s Plusへダウンロードし動作確認の段。

 

ん?

 

何かボタンちっちゃくね?

 

というか、

contentModeの設定きいてなくね??

 

わー!!めっちゃカッコ悪いぞこれー!!

 

すぐに公開停止し原因を探りました。

果たして何が原因だったのでしょうか?

 

実はcontentModeが効いていない訳ではない

いきなり見出しで答えの半分を書いてしまいました。

実はこの通りcontentModeが効いていない訳ではないのです。

このcontentModeなんですが、コレ実は、UIButtonの中にあるUIImageViewのcontentModeなんですね。

つまりこの現象はUIButtonのUIImageViewが適切なサイズになっていないことが原因です。

 

「ん?」

「なんでそんなことが起きるんだ…?」

 

「いや…、ちょっと待てよ…。」

 

「まさか、AutoLayoutの仕業かー!!」

 

はい。その通りです。

AutoLayoutが働くタイミングとcontentModeが効くタイミングによっては、我々が普通に考えるのとは異なる見え方になっちゃうのです。

つまりUIButtonは大きくなっているのに、中のImageViewが小さいままという現象が起きてるんですね。

 

まぁ、以下のリンクの受売りなんですが。

UIButtonの画像をUIButtonに対してAspectFitする方法 - Qiita

 

対策は?

 上記リンクにも答えが書いていますが、UIButtonのcontentHorizontalAlignmentとcontentVerticalAlignmentというプロパティを設定します。

UIImageのアスペクト比を保ったまま拡げる場合に.fillを指定します。

 

(UIButton).contentHorizontalAlignment = .fill

(UIButton).contentVerticalAlignment = .fill

 

という訳で本日は終了です!

 

 

try! Swift Tokyo について

とても行きたいイベントがあります。「try! Swift Tokyo」です。
恐らく日本で開催されるSwiftのイベントでは最大のものと思われます。
Swiftのフジロックみたいなもんでしょう。
本日は try! Swift Tokyo について、私のような若輩者目線で書かせて頂こうと思います。

Swiftコミュニティー主催のカンファレンスです。
素晴らしくかっこいい響きです。カンファレンス。

「まだこのような催しに参加するレベルに私はないよな。」
そのようにお考えの方、ちょっと待って!
どんなにあなたのレベルが低いとしても、講演の内容が全く理解できないということはまずありません。

「ここまでは何となく分かったけど、そこからはチンプンカンプン」

うん。確かにそのようなことはあるでしょう。
ですが、それでいいのです。
このように実感することで、 「現状理解できていることと出来ていないこと」を見える化することが出来たわけです。
それだけではなく、「全然分からないけど何か凄そうなもの」という新しい地平線(ホライゾン)も見ることができるのです!

もしも、講演の内容がまーったく理解できなかったとしましょう。
それでも参加する意味がないことは決してありません。
try! Swift Tokyo にはもちろん沢山の方々が参加されます。
そんな方々に様々な相談をすることができるまたとないチャンスな訳です。
またその中には、普段は会えないようなとても有名な開発者の方も必ずいらっしゃいます。
そんな人とお近づきになれるこれまたまたとないチャンスな訳です! (何てたってSwift界のフジロックなんですから!)

個人的には最終日のハッカソンが気になります。
Swiftプログラマーが集まったハッカソン。決して「結局アイディアソンじゃん」ということはないはずです。
どんなものが出てくるのかとても楽しみです。

そのような環境で受けた刺激はプライスレス!
とても大切なモノに、そして血となり肉となるでしょう。

そんなtry! Swift Tokyo、本日(2017/1/16)の0時まで早割チケットを購入可能です!
(この記事書いている時点で後5時間!!!)
急げ!

www.tryswift.co

ん?お前は参加するのかって??
...私は遠く離れた大阪でサラリーマンをしている身。
検討しましたが、休みを取得するのが難しく今回は断念...! 将来的にサマソニのように東京・大阪同時開催になればいいね(んな訳ない)。

ただ真面目な話、オープンソースコミュニティであるSwiftに少しでも貢献したくこの記事を作成致しました。 Swiftの更なる活性化を願って!

フジロックに毎年今年こそはと行って結局サマソニに行っちゃう若輩Swift愛好家より。

「ポーン - プロフェッショナルな名言をカウントしよう」をリリースしました

2016/12/21に新しいアプリをリリースしました。

  • 名前は「ポーン - プロフェッショナルな名言をカウントしよう」です。
  • お友達が名言を言った際にあの「ポーン」音を鳴らし、これによりドヤ感を演出することが出来ます。
  • また会話の中で何回名言を発言したのかを計測することも可能。(一応本来の機能はカウンタ)
  • 履歴から過去のポーン回数を確認することができます。
  • くだらないアプリですが、誰かの役に立つことが出来れば幸いです。

f:id:anthrgrnwrld:20161226200213p:plain

宜しければ以下からダウンロードお願いします!!

履歴の保存にはRealmを使用しています。
初データベースです。
データベースについての考え方自体ついてはまだまだ勉強しなければならないと感じましたが、Realm自体はとても簡単に使うことが出来ました!

因みにこのアプリもオープンソースにしてみました。

github.com

正直今回は今までに比べ、かなりやっつけで作成したのでとても恥ずかしいですが、 誰かの役に立てれば幸いです。

UIDocumentInteractionControllerを使ってOption Menuを表示する [UIDocumentInteractionController] [share] [swift2.3] [swift3]

前回Instagramへの投稿をやりましたが、今回は何でもアリのUIDocumentInteractionControllerを使用したOption Menuを表示する方法をメモしておきます。

こんなやつです。
f:id:anthrgrnwrld:20161014001005p:plain

Githubは以下です。

github.com

1. UIDocumentInteractionControllerDelegate

ViewControllerにUIDocumentInteractionControllerDelegateを追記します。

class ViewController: UIViewController, UIScrollViewDelegate, UIDocumentInteractionControllerDelegate {
    ...
}

2. IBAction内に以下のコードを記述

  • swift2.3
    @IBAction func pressOpenIn(sender: AnyObject) {
        let imageData = UIImageJPEGRepresentation(self.canvasView.image!, 1.0)
        let tmpDirectoryPath = NSTemporaryDirectory()   //tmpディレクトリを取得
        let imageName = "tmp.jpg"
        let imagePath = tmpDirectoryPath + imageName
        let imageURLForOptionMenu = NSURL(fileURLWithPath: imagePath)
        
        do {
            try imageData?.writeToURL(imageURLForOptionMenu, options: .AtomicWrite)
        } catch {
            fatalError("can't save image to tmp directory.")
        }
        
        interactionController = UIDocumentInteractionController(URL: imageURLForOptionMenu)
        interactionController?.delegate = self
        self.interactionController?.UTI = "public.jpg"
        interactionController?.presentOptionsMenuFromRect(self.view.frame, inView: self.view, animated: true)
    }
  • swift3
    @IBAction func pressOpenIn(_ sender: AnyObject) {
        //print("\(NSStringFromClass(self.classForCoder)).\(#function) is called!")
        
        let imageData = UIImageJPEGRepresentation(self.canvasView.image!, 1.0)
        let tmpDirectoryPath = NSTemporaryDirectory()   //tmpディレクトリを取得
        let imageName = "tmp.jpg"
        let imagePath = tmpDirectoryPath + imageName
        imageURLForOptionMenu = URL(fileURLWithPath: imagePath)
        
        do {
            try imageData?.write(to: imageURLForOptionMenu!, options: .atomic)
        } catch {
            fatalError("can't save image to tmp directory.")
        }
        
        interactionController = UIDocumentInteractionController(url: imageURLForOptionMenu!)
        interactionController?.delegate = self
        self.interactionController?.uti = "public.jpg"
        interactionController?.presentOptionsMenu(from: self.view.frame, in: self.view, animated: true)
        
    }
    

utiには開きたいファイルの種類を指定します。
詳細は以下をご参考ください。

developer.apple.com

3. interactionController: UIDocumentInteractionControllerを宣言

このままだとエラーが出てしまいます。
スコープが広いところに以下の宣言を記載します。

var interactionController : UIDocumentInteractionController?

以上で何でもアリのOptionMenuが表示されると思います。

URLスキームを使用したファイルの共有方法については以下のリンクを参照してみてください。

anthrgrnwrld.hatenablog.com