Golangにおけるポインタについて

これまで、Swiftをメインに書いてきましたが、最近golangを触る機会がありました。 Swiftでは考える機会がなかった ポインタメモリ についてまとめていきます。

初心者の方にわかりやすく伝わればいいなと思っています。

ポインタって?

まず、ポインタという言葉の前にメモリについて理解をすることが必要です。

n := 200

変数nが定義された時に、200を一時的に保存する場所が メモリです。

メモリは、複数存在しそれぞれのメモリに番号が振られています。

この番号を アドレス と呼びます。

実際にアドレスを確認してみます。 Goでは、&を定義した変数の前につけることでメモリを確認することができます。

func main() {
    n := 200
    fmt.Println(&n)
    // -> 0xc000084000

つまり、アドレス0xc000084000に変数nの200が保存されていることになります。

アドレスとメモリについて理解したところで、ポインタについて考えていきます。

ポインタを調べると、このようにまとめらていました。

  • メモリのアドレス情報のこと
  • アドレス情報を格納するための変数のこと

もう少しこの2つを詳細に見ていきます。

Golangには、 ポインタ型ポインタ変数

ポインタ型は、stringやintなどの方に*をつけることで定義します。

下では、nがポインタ変数にあたり、*intがポインタ型になります。

func main() {
    var pointer *int
    n := 100

    // 1.
    pointer = &n

    // 2.
    fmt.Println("pointerの中身:", *pointer)
}
  1. &nを使うことで、nのアドレスの番地をpointerに格納している
  2. pointer型から値を取得するためには、*をつけることで値を表示することができる

実際にポインタ型を使う時

ポインタ型は、参照渡しを行う時に用います。

Swiftでは、inoutを使いますね。

func main() {
    a, b := 100, 100

    checker(a, &b)
    fmt.Println(a, &b)
        // -> 100 101
}

//1
func checker(a int, b *int) {
    a++
    *b++

}
  1. 参照渡しを行うことで、呼び出しもとのbの値が変更される。

まとめ

多言語からGolangを始める方、初心者の方はこのポインタ型におそらく苦労されると思います。(自分がそうだった)

そこで、実際に手を動かして書くことで少し理解が深まると思います!

ぜひ、この記事を読みながら実際にパソコンでも手を動かして欲しいなと思います。

UIViewRepresentableとUIHostingController

UIViewRepresentable

SwiftUIの中で、UIKitのViewを使用したい時に継承します。

  • makeUIView(context:)
  • updateUIView(_:context:)

この2つの関数を呼ぶことで、Viewの実装を完結することができます。 makeUIView(context:)は、viewの初期化 updateUIView(_:context:)は、layout を決める時に使用しています。

struct MapView: UIViewRepresentable {
    func makeUIView(context: Context) -> MKMapView {
        MKMapView(frame: .zero)
    }
    
    func updateUIView(_ view: MKMapView, context: Context) {
        let coordinate = CLLocationCoordinate2D(
            latitude: 34.011286, longitude: -116.166868)
        let span = MKCoordinateSpan(latitudeDelta: 2.0, longitudeDelta: 2.0)
        let region = MKCoordinateRegion(center: coordinate, span: span)
        view.setRegion(region, animated: true)
    }
}

SwiftUIのチュートリアルでは、MapViewにUIViewRepresentableを継承させました。 このように継承させることにより、

struct ContentView: View {
    var body: some View {
        VStack {
            MapView()
                .edgesIgnoringSafeArea(.top)
                .frame(height: 300)
        }
    }
}

上のように、SwiftUIの中で、UIKitのコンポーネントを使用することができます。

UIHostingController

UIKitをメインにSwiftUIを用いたい時にUIHostingController を使用します。

let viewController = UIHostingController(rootView:  ContentView)

struct ContentView: View {
    var body: some View {
           Text("Joshua Tree National Park")
    }
}

1つのViewControllerとして扱えるようになるようです。

1年間休学したことの振り返り

ここ最近忙しく、更新をしていませんでしたが約1年間インターンをしていた、Popshootを2月18日にやめました。 4月からは、大学生活を送っています。

最近いろいろな人にプログラミングの勉強方法を聞かれることが多いです。 僕の経験は、エンジニアを始めたいと思う人のきっかけになるのではないかと思いこの1年を振り返ることにしました。

インターン先を見つける

17年の12月に、大阪でSkylandの木下さんと大山さん(Popshootの社長)が来られるイベントがあると東京でインターンをしていた友達から聞きました。 その友達は、半年前から東京に住んでいて、学校で会うたびに「考え方変わるし、絶対東京に来た方がいい」と言われていました。 そんな友達のオススメのイベントということもあり、興味半分でこのイベントに参加することにしました。 イベント後に大山さんが、春休みの2ヶ月間記事を書くライターとして、住み込みインターンを募集すると言いました。 春休みを関西で過ごすのか、東京でインターンをするのかを考えた時に、東京で過ごす方が濃密な時間を過ごせると感じ、大山さんにインターンをしたいとお願いをしました。

僕は何かを選択する時、それをした自分としない自分を比べ、選択肢が増える方を選択するようにしています。

春休みインターン

インターンには、2ヶ月前からインターンをしているエンジニアがいました。 初めて僕は、プログラミングができる友達と出会いました。 もともと、リッチマンプアウーマンが好きな僕はエンジニアに興味がありました。 近くにエンジニアがいるのは、プログラミングを勉強するいいきっかけなので、ライターの仕事が終わるとプログラミングの勉強をするようになりました。 コードを書きながらアプリが作られている過程に興奮をしたのを今でも覚えています。 勉強を始める時にまず、本屋で1冊本を買いました。そして、その本を毎日写す事から始めました。

休学をしてエンジニアの勉強を始める

春休みが終わる2週間ほど前に、友達から休学をすると「本格的にプログラミングを教える」と言ってもらいました。

この時も、インターンをする決断と同じ考え方をしました。休学を終えた1年間と関西で大学生活を送る自分を比較しました。そしてエンジニアという力をつけた方が選択肢が増えると思い休学を決意しました。

脱初心者

休学をして最初の2週間~1ヶ月は、「テックキャンプ」と「Udemy」のiOSの講座を何度も見て写経から始めました。 ・テックキャンプは、プログラミング未経験の人のための講座のため本当の初心者にはおすすめです。 ・Udemyは、比較的安くコンテンツも豊富で、初心者から中級者程度の人でも勉強になることが多くあります。

写経をした理由は、コードを1つずつ理解するのではなくパターンを覚えるのを優先したからです。 今でも、新しい言語に触れるときは、写経をし全体を捉えるようにしています。 エンジニアを始めるきっかけとして良かったのは、「わからないことを聴ける環境」と「プログラミングをする時間」があったことです。

自分でアプリを作成

リリースまでは至らなかったのですが、個人でアプリ作成を1ヶ月ほど行いました。 プログラミングの書き方は、言語が同じでも会社によって異なります。 インターン先の書き方に慣れるためにその書き方を真似しながらアプリを作ることにしました。 写経でインプットしてきたものをアウトプットすることで、これまでパターンで覚えたことを深く理解できるようになりました。

チーム開発に入る

ある程度、力がついて来たことを認められ開発チームに入れてもらうことになりました。 開発していたのは、「ぴたコイン」というアプリです。 ‎「ぴたコイン-ビットコイン予想、仮想通貨チャートfxゲーム」をApp Storeで

チーム開発は、個人開発とは違い「読みやすいコード」を意識して書くことが大事です。 これまでは、自分だけが理解できればよかったですがチーム開発ではチーム全員が書いたコードを理解できる必要があるからです。 また、すでにある膨大なコードを読むことにも苦労しました。 アプリを触りながら、この画面ではこんな風にコードが動いているんだなと地道に覚えていった記憶があります。 また、デザイナーの方とアプリの見た目や使いやすさについてもたくさん教えてもらいました。 この時期から新しいアプリが作られるたびにアプリを入れて、アプリのデザインや使いやすさの工夫を見るという日課ができました。

ある程度、コードを書けるようになるとどこかの会社でインターンをすることがおすすめです。 レビューといって、自分の書いたコードを見てもらいより良いコードを教えてもらったり、知らない知識を教えてもらうことができるからです。

サイバーエージェントインターン

iOSのプログラミングの勉強を初めて、半年がたち自分の力を試してみたいと思い、サイバーエージェントで1ヶ月のインターンをしました。 異なった環境での開発は、「もっともっと成長しないといけない」と改めて思う機会になりました。 また、メンターの方にも恵まれて毎日充実した時間を過ごす共に、成長を実感できる時間でした。 詳しくはこちらを参考にしてください。 https://blog.hatena.ne.jp/shanksryouop/shanksryouop.hatenablog.com/edit?entry=10257846132667628649

Popshootに戻って開発を続ける

サイバーエージェントインターンを終えてからは、再びPopshootでインターンを行いました。 戻ってからは、ピタコインのユーザー数が一気に何倍にも伸び、毎晩ユーザー数を見るのが楽しかったのを覚えています。 そして、新規機能の追加などのタスクも拾うようになり、とてもやりがいがある日々を過ごすことができました。

QuickeRをリリース

たまたまイベントで知り合った1つ上の先輩が、全く同じアイデアのアプリを開発していたので一緒にアプリを作ることになりました。 リリース後、知らない福岡県の方からTwitterで「こんなアプリが欲しかった!」というコメントをもらった時は、アプリ作りって良いなと思いました。 現在では、アメリカ、アイルランドなど世界中でこのアプリは使われています。

エンジニアのいいこと

周りの人が持っているたくさんの課題をプログラミングという技術で解決することができることです。そして、日本だけではなく世界中の人に使ってもらうことができます。

最後に

この1年間を振り返ると本当に多くの方に出会い、助けられて1日1日を過ごしてきました。 現在でも、多くの方にはお世話になりっぱなしですが、本当に感謝しています。

現在新しい会社で、アプリを作成しています。 もう少しでリリースができるので、楽しみにしていてください!

"プロダクトマネジメントのいろは" をVolareとTechTrain共催で開かせていただきました!

Peoplyticsの奥西さんを迎えて、VolareTech Trainプロダクトマネジメントについての勉強会を開かせていただきました。 そこで、勉強会の内容をシェアしていきたいと思います。

  • 将来、PMになりたいけどPMってどんな仕事?
  • エンジニアのキャリアってどんな種類があるの?

こんな人に読んでもらえたらと思います。

プロダクトマネジメントの印象は??

プロダクトマネジメント(PM)についてどんな印象を持っていますか?

僕は勉強会に参加するまで、

大まかなイメージしか持てていませんでした。

多くの人がこんな印象を持っているのでは無いでしょうか?

実際に勉強会で聞いてみると

  • タスクを管理する
  • サービスを成長させる
  • チームのマネジメント

と言った意見が出ました。

でも、PMってこれだけでは無いことを今回知ったのでそんなことを紹介していきます。

PMとは

PMの仕事のイメージが付きにくい理由はその役割の多さでした。

PMの最も重要な責任は、『ユーザーの満足度を高めながらプロダクトを作る』ことです。

プロダクトを作る責任を持つということから、役割の多さが伝わります。

これから、その役割をもう少し細分化して行きたいと思います。

今回お話を聞くまで知らなかったのですが、PMには大きく分けて2つの役割があります。

プロダクトマネジメント(PdM)プロジェクトマネジメント(PjM) です。

PdMの役割

  • ユーザーの課題解決
  • ビジネスモデルの構築
  • サービスの実現可能性の提案

PjMの役割

  • 品質や開発コスト
  • 開発のスケジュール管理

PdMは、プロダクトの WhatWhy に、PjMは、HowWhenにフォーカスします。

PdMは、プロダクトの決定権を多く持つため、ミニCEOと呼ばれているそうです。

PdMだからと言って、PjMをしないという訳ではなく

PdMへ比重は起きながらも双方の役割を行います。

PdMのフロー

プロダクトの規模によって、PdMの役割も大きく変化するそうです。

シード 〜 シリーズA * 事業起案 * マーケット調査, 競合の調査 * ユーザーのニーズの検証

シリーズB 〜 シリーズC * 利益率を検証した実現可能性 * 売り上げ、利益の最大化

これ、言葉ではわかりにくいですよね笑

シードからシリーズAは、こんなイメージでプロダクト開発を行います。

f:id:shanksryouop:20190912174510p:plain

イデアの起案→競合を調査 → 開発 → ユーザーのニーズを把握 → アイデアの制度をあげる

このようなサイクルで、プロダクト開発を行いきます。

このフローの中で起こるプロダクトに関する意思決定を、PMが担っています。

ある程度、プロダクトのニーズが見え、シェアが取れてくると

必要なマーケティング費用から利益を上げることが可能か検証していきます。

利益率が実現できると見込めば、プロダクトの拡大期に入ります。

マーケティングや新機能追加、などの意思決定を行います。

会社の成長を意思決定するのが、CEOなら

プロダクトの成長の意思決定をするのが、PMに当たります。

まさに、ミニCEOだなと思います。

CEOは、自分の会社が社会にどんな影響を及ぼすのかを考えますが、

PMは、プロダクトが社会にどんな影響を及ぼすかをイメージし、

そして、そのイメージを数値に落とし込み、実現できるかを検証することが大事だそうです。

サービスを生物と見立てる

どんな市場だとどんな機能が必要なのかを

生物に例えてお話をされていたのがわかりやすかったです。

実際に、PMになるとこういった意思決定をする機会が多いそうです。

マーケティングを生きる環境、ビジネスモデルを骨格、プロダクトを筋肉・見た目と考えます。

まず、マーケティングで自分たちが作りたいプロダクトの環境を明確にします。

ビジネスモデルは、一度作ると変えづらくサービスを作る中でグロースするかを決める重要な役割を持つので骨格にあたります。

プロダクトは、実際にユーザーに触れるため見た目の性質を持つのと同時に、

ビジネスモデルを動かすための機能的な要素を持つため、筋肉とも見ることができます。

今回の勉強会では、「木ノ実を食べる生物を考える」という例を考えました。

「鳥」「りす」「キリン」など様々な生物が出ました。

鳥は、いろんな環境に適しながらも飛ぶという機能が必要でリソースを食いそう。

キリンは、骨格が大きいからベンチャー企業では向かない。

りすは、一番骨格が小さいので簡単そう。

このような例えから、「規模」によって作る機能が異なって来ることが理解できました。

感想

冒頭でも書いたのですが、

これまで、PMになりたいと思っていたのですが、

実際に何をしているのかよくわかっていませんでした。

しかし、今回勉強会を通してイメージが湧いたのがすごくよかったと思います。

プロダクトに関する意思決定を多くできるのは、やりがいが感じれると思うし楽しそうだなと改めて思いました。

現在、Volareでサービス開発を行なっているので、

今回のPMの話を基に、サービス開発を進めて行けたらいいなと思っています。

また、奥西さんの話を聞くと自分の考えていることを言語化して、誰かに伝えることの必要性を感じました。

そのため、最近記事を書くことをやめていたのですが、

「わかったこと」「感じたこと」

を今回のように言語化してまとめて行きたいと思っています。

スライド

speakerdeck.com

まとめ記事

note.mu

note.mu

プロダクトマネジメントとは?(初めて勉強会に参加したお話) | 大学生エンジニアの日常

Herokuにデプロイする時に、Ginがデプロイできない

最近、サーバーサイドを実装してみたいという気持ちからHerokuにデプロイして個人でサーバーを書こうと思いました。

しかし、ginというライブラリがネックで ' git push heroku master ' エラーが出ていました。

' router/router.go:4:2: cannot find package "github.com/gin-gonic/gin" in any of '

上のエラーのような感じです!

そこで、メモがてらに上記のエラーがでた時の対処法について書いていきます。

修正方

今回のエラーの修正点は、' Procfile 'に以下のテキストが抜けていたからでした。

' echo web: gin_memcache > Procfile '

これを書くことで修正できました。

以下が参考記事です Scaling a Gin Application with Memcache | Heroku Dev Center

間違ったブランチ元から新しいブランチを生やしてしまった。

masterから生やしたいのに間違ったブランチから草を生やしてしまった。 git rebase --onto maser 派生元branch名 現在のbranch名

DeepLink導入に関して 詰まった所をまとめます

これまで、FirebaseのDeepLinkを使っていましたが新たに、AppsFlyerのDeepLinkを利用することになりました。 私は、今回が初めてのDeepLinkの実装であったためそこで詰まった点についてまとめておきたいと思います。 これから、FireabaseやAppsFlyerでDeepLinkを実装する方に少しでも理からになるようにまとめておきたいと思います。 この記事では、AppsFlyerを使って記事を作成していますが、Firebaseでも通じるところが多々あります。

SDKの導入

まずは、podを使ってSDKをインストールしていきます。

そして、AppDelegateに下記を記述します。

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
  AppsFlyerTracker.shared().appsFlyerDevKey = "<your-appsflyer-dev-key>";
       AppsFlyerTracker.shared().appleAppID= "123456789"

func applicationDidBecomeActive(application: UIApplication) { 
     AppsFlyerTracker.shared().trackAppLaunch() 
}

を実装していきます。これによりトラッキングが開始されます。

Appsflyerでは、この設定でイベントを取得することができます。

DeepLinkの実装

AppsFlyerのConfigure OneLink を選択します。

OneLinkは、FirebaseのDeepLinkに似たものでAppsFlyerが独自で用意したLinkです。

OneLinkの設定には、 App ID peefixiOS App Bundle ID が必要になります。

App ID prefixは、App Developer -> AppID -> Bundle IDと一致したアプリを選択すると確認することができます。 これで、OneLinkの設定は終了です。

しかし、ここからがドツボにハマる点でした。

AppsFlyerでは、3つの実装ができているかを確認するためのテストが用意されています。

  1. non organic install
    -> 流入してきたユーザーがorganicかそうではないかをhandleできるかをテストしています。
  2. In-app Events    -> Eventをしっかり取れているのかをテストしています。
  3. Deeplinking    -> DeepLinkが正しく押されているのかをテストしています。

1と2に関しては、非常に簡単に実装することができましたが3に10時間ほどハマりました。

なので、今回はそこを徹底的に紹介していきます。

Domain設定

iOSには、entitlementというものが存在しそこにdomainの設定を行う必要があります。 domainの設定は、 DeepLinkのpathを許容するために必要のようで設定するためには必須です。 そのDoamin追加の部分に、 applinks:mydomain.onelink.me を記述します。 まず、ここで5時間は使いました。 次に、このDomainを設定した後一度端末の電源をOFFにすることが必要のようです。

Universal Linksでアプリ起動時に利用され、自動的にiOSアプリのインストール時に自動的にダウンロードされるはずの「apple-app-site-association」ファイルが、iOS 11.2以上を使用している端末で、ダウンロードされないことがあるようです。このファイルなしでは、iOS端末はUniversal Linksはアプリを直接起動することができません。
ディープリンクのテスト時にこの事象が発生している場合、アプリをアンインストールし、ホワイトリストに登録済みのiOS端末を再起動した上で、アプリを再インストールしてください。それでも問題が解決しない場合、再度同じ手順を繰り返してください。
iOS11.2を使用している多数のiPhone端末で同様の問題が発生していることを確認していますが、どれだけこの問題が蔓延しているかは不確かです。iOSユーザーの3分の2に影響しかねないこの事象を、Appleがいち早く解決することを祈っています。

AppsFlyerでは、上記のように記述されていました。

この電源を切るか切らないかで、5時間はくらいました。

最後に、AppsDelegateで下記を設定すればテストも無事に終えることができました。

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
}

ということで、今後Deeplinkを実装される方は上のDomainの設定を忘れないようにしてください。