web系確認チェックリスト(フロント編)

web系作業ってなにかと気にしなければいけないことが多くて、作業するのも大変だし、チェックしたり確認したりするのもいちいち大変。何か漏れてたりするとつど凹む。

しょうがないっちゃしょうがないけどさ、俺らプロだぜ?漏れるとか、ミスとかは無くして行きたいと思うのは、普通の考え。

とりま、しばらくはフロント周りのお仕事をやることになりそうだから自分のためのめも。めっちゃ細かいこと書いたけど、それも、いいwebページを世に提供するため。自分のために・・

f:id:igatann:20190405002714p:plain

pcでコーディングしているイラスト

新規webページの作成編

  • リンク先はあっているか( 違うところに飛ばさない。 )
  • 画像切れはない
  • meta情報はあっているか
  • cssの汚染はされていない。
  • 想定どおりのcssになっているか
  • デザインどおりにページは作成した
  • コンソールエラーになっていないだろうか
  • パンくずは問題ないか
  • ページのURLはおかしくないか(意味のあるURLになってるだろうか)
  • そのページへの動線はんあるだろうか
  • デザイン通りに作っても使い勝手か悪くないか考える(使い手のことを考える)
  • 全角半角を混合させていないか
  • imgタグのaltは入れたか
  • canonicalはつけた
  • alternateはつけた
  • table summaryは記述したか

web製作って臨機応変がめっちゃ求められる。めっちゃいや。こっちの方がいいとか、提案するとか。自分の考えを持つってことが大事だなと最近思うようになった。よくも悪くも。

※都度更新予定

UserDafaultsを使ってみる

データベース接続する必要のなデータを扱いたい時、データを簡単に保存し、扱いたい時に使用するのがUserDafaults。

詳細に

・データの永続化(アプリを再起動させた初期画面には保存したデータを読みだして表示する)
・アプリのデフォルト設定を含むオブジェクト

 

使い方

今回は配列に入れる、保存した内容を表示するだけのいたって簡単なUserDefaultsの使い方。

 

  • 配列変数の定義

  • UserDefalutsのインスタンス

  • デフォルト値の設定

  • userdefaultの内容を取得する(なければスルー)

  • 何かされたらuserdefualtsを追加する

 

配列の定義

var commentaryList = [[String]]()

 

インスタンスの定義

let userQuestionInfo = UserDefaults.standard

 

userDefaultsがあるかないかの判定

あったらuserDefaultsの内容をcommentaryList内に入れる。
if userQuestionInfo.object(forKey: "questionKey") != nil{ commentaryList = userQuestionInfo.object(forKey: "questionKey") as![[String]] }

commentaryList 配列に要素を追加する。

commentaryList.append([questionCategory.QuestionDataList[questionCount].questionText,questionCategory.QuestionDataList[questionCount].review])

userDefaultsの保存

userQuestionInfo.set(commentaryList,forKey:"questionKey")

github

引数に配列を指定する

class QuestionCategory{ var QuestionDataArray:[QuestionData]; init(QuestionDataArray:[QuestionData]){ self.QuestionDataArray = QuestionDataArray } }

引数に配列を入れる方法もあるのだが、 可変長引数を利用すれば、すっきりかける。

■可変長引数

class QuestionCategory{ var QuestionDataList:[QuestionData]; init(QuestionDataList:QuestionData...){ self.QuestionDataList = QuestionDataList } }

引数の型の後ろに…を置いてあげれば、 関数の呼び出しのときに、配列であることを意識させない。 関数内部では、 Array型として扱われる

時間ない!テキトーすまん!また書き直す!

Storyboardを複数に分割して管理する方法

背景

1つのstoryboardだけでは、画面が多くなっていくにつれて管理が大変になるので、Storyboardを分けたいと思った。そのメモ。

overView

storyboardを追加と紐ずけについて 
StoryBoard Referenceを使うみたい

予備知識

最初に表示させるviewControllerを Is Initial View Controller にチェックを入れる 
→「初期View Controllerです」
  
1つのstroyboardだけではsegueなどで画面を繋げると画面が多いとか管理が難しくなるので分割がしたい
 
 

新規ファイルでStory boardファイルを作成する。

 
Story board Referenceを用意する

f:id:igatann:20190131235024p:plain

 
StoryBoard Referenceを遷移元のStoryBoardを設置していく
Segueで配置でボタンとStoryBoard Referenceを結ぶ
StoryBoard ReferenceのStoryboardに遷移したいstoryboardを指定する
 

f:id:igatann:20190131235117p:plain

 

referenced IDの部分に〇〇.storyboardで設定したStoryboard IDを入れる

Storyboard ID の設定の方法

遷移させたいstroyboard内にあるTOPのviewController(viewControllerじゃなくてもいい、navigationControllerでもいいし)を指定してして、Storyboard IDを入れる
 
 

WebViewを使ってツイッターを表示したい

xcodeを使ってwebviewを使ってついったーを表示するプログラムを書いてみた。

前知識

webVIewを使うためにはUIWebViewクラスはiOS12.0で廃止されたので、WKWebViewを使うようにする

https://developer.apple.com/documentation/webkit/webview

ソースコード

import UIKit
import WebKit

class WebViewController: UIViewController ,WKUIDelegate{
    
    var webView:WKWebView!
    
    override func loadView(){
        let webConfiguration = WKWebViewConfiguration()
        webView = WKWebView(frame:.zero, configuration: webConfiguration)
        webView.uiDelegate = self
        view = webView
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        let myURL = URL(string:"https://twitter.com/")
        let myRequest = URLRequest(url:myURL!)
        webView.load(myRequest)
    }
    
}

    

公式サイト

https://developer.apple.com/documentation/webkit/wkwebview

これを翻訳して行けばとりあえずできる。公式サイトみて(て言っても、サンプルソースが簡単でとても助かった。)何かをやったの初めてかも。とりあえず、少し成長。

loadViewメソッド

Viewをカスタムする使用する場合に記述する。ViewControllerが管理するwebViewを作成する。この場合はWebViewを作成(しているの?)

        
    override func loadView(){
        let webConfiguration = WKWebViewConfiguration()
        webView = WKWebView(frame:.zero, configuration: webConfiguration)
        webView.uiDelegate = self
        view = webView
    }
        
    

WKWebViewConfigurationオブジェクトをインスタンス化。

WKWebViewConfigurationはwebビューを初期化するための設定

WKWebViewインスタンス

WKWebViewインスタンス化のインスタンス化には、引数のframeとconfigurationを設定する必要がある

frame
新しいWebビューのフレーム。zeroは原点とサイズがゼロのフレーム
configuration
新しいWebビューの設定。

webView.uiDelegate = self

デリゲートを自身に設定

viewDidLoad

myURLに表示したいサイトのURL入れる

          let myURL = URL(string:"https://twitter.com/")
    

myURLはオプショナルなURL型!

URLRequestメソッド

引数にURL型を入れる。myURL!としているのはmyURLがオプショナル型だから !にとって非オプショナルに変えてあげる。

webViewにmyRequestをロードさせてあげて、無事、ついったーのページが表示される。

webビューのフレームや初期化の設定をしたインスタンスを作成して、loadメソッドでリクエストするURLを入れてあげればOK

Core Image を使ってモノクロ画像を生成する

ios開発の勉強日記。今日はCore Imageを使った画像の処理についてです。snowなどの撮影した画像やライブラリ上にある画像を編集したりするにはCore Imageってのを使っているのだなと思ったり。
エフェクトを使うには、画像形式を変えなきゃいけないのが複雑っぽい

github

https://github.com/Yuto-Igarashi/MyCamera/blob/master/MyCamera/EffectViewController.swift

コード説明にあたって 前画面で撮影した画像はUIImage クラスとして保存される


    //(1) 撮影が終わった後に呼ばれるdalegateメソッド
    func imagePickerController(_ picker:UIImagePickerController,didFinishPickingMediaWithInfo info:[UIImagePickerController.InfoKey:Any]){
        
        /*
        //(2) 撮影した写真を、配置したpictureImageに渡す
        pictureImage.image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
        //(3) モーダルビューを閉じる
        dismiss(animated: true,completion:nil)
        */
        
        //(2) 撮影した写真を、配置したcaptureImageに渡す
        captureImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
        //(3) モーダルビューを閉じる
        dismiss(animated: true, completion: {
            //(4)エフェクト画面に遷移
            self.performSegue(withIdentifier: "showEffectView", sender: nil)
        })

で、撮影した画像をprepareを使ってEffectViewControllerに渡してあげる


//次の画面遷移する時に渡す画像を格納する場所
var captureImage : UIImage?
override func prepare(for segue:UIStoryboardSegue, sender:Any?) {
    //次の画面のインスタンスを格納する
    if let nextViewController = segue.destination as? EffectViewController  {
        //次の画面のインスタンスに取得した画像を渡す
        nextViewController.originalImage = captureImage
    }
}

↓前画面のviewCntrollerのソースコード

https://github.com/Yuto-Igarashi/MyCamera/blob/master/MyCamera/ViewController.swift

フロー

前画面で撮影した画像はUIImage クラスとして保存される

  1. 取得した画像をアンラップ。(オプショナルだから)
  2. フィルタ名を指定する。ここではもの黒にしたいからCIPhotoEffectMonoを指定する
  3.  (まだ何もしない、指定するだけ)
  4. 画像の回転角度を取得する(CIImage形式に処理すると回転角度を取得できないから処理前に、撮影した画像の回転角度を取得すること)
  5. UIimage形式の画像をCIImage形式の画像へ変換する
  6. CIFilterインスタンスにフィルター名を指定する(このインスタンスがないとエフェクト処理ができない。)
  7. CIFilterインスタンスに画像の形式を渡してあげてCIImage形式の画像を指定してエフェクト処理をしていく。
  8. エフェクト後の画像(CIImage形式)を取り出す。
  9. 画像の加工を行い(createCGImage)、cgImageを生成する
  10. フィルタ加工済みの画像をUIImageに変換する。
  11. ImageViewに変換する

エフェクトを扱うには

エフェクトを扱う、CIFilterを使うには、CIImage形式の画像である必要がある。
元々のUIImage形式である画像をCIImage形式に変換する処理を行う。

CIImage
Core Imageフィルタによって処理または生成される画像

画像が格納された変数をアンラップする

エフェクト前の画像をアンラップしてエフェクト用の画像として取り出す。
(※originalImageはオプショナル型)


if let image = originalImage{

}

フィルター名を指定する

フィルター名を指定して、変数 filterNameに格納する

let filterName = "CIPhotoEffectMono"

ここでやってるのは、なんのフィルターを使うの?
→CIPhotoEffectMonoだよ

○CIPhotoEffectMonoってなに?

モノクロのエフェクトを追加してくれっていうフィルター

○公式リファレンス

https://developer.apple.com/library/archive/documentation/GraphicsImaging/Reference/CoreImageFilterReference/index.html#//apple_ref/doc/filter/ci/CIPhotoEffectNoir

回転角度を取得する

let rotate = image.imageOrientation

本体(iphone自身てことね)を縦で撮影したのかの情報が格納されています。
Core imageで使えるデータ型に変換する際に、画像の回転角度の情報は失われている
ので、ここで画像の角度を取得すあとで、エフェクト処理後に画像を設定する際に回転角度も付与しておく。

○もっとわかりやすく。

Core imageで処理する時には、画像の回転角度の情報はなくなるので、 ここで、Core imageで処理する前に撮影した(またはライブラリから引用した)画像を記憶させておく。 なんで記憶させておくか、あとでcoreImageでエフェクト処理後に、画面へ画像を設定する時に「この画像の角度なんだっけ?」っていうのを防止するためにここで記憶させておく。

ここのimageってのは、アンラップした変数だから実体のある変数(まだUIImage型)
image.imageOrientationは角度を取得するプロパティ

UIImage形式の画像をCIImage形式の画像に変換する

let inputImage = CIImage(image:image)

何しているの?(復習)

フィルターを使うためには、CIImage形式の画像を使わないといけないからここで変換している!

フィルターの種類を引数で指定された種類を指定してCIFilterのインスタンスを取得

guard let effectFilter = CIFilter(name:filterName)else{
    return
}/code>

CIFilterクラスは引数にフィルター名を指定して、そのフィルターのインスタンスを指定する
(インスタンス作成時に引数 イニシャライザを使っているのかな?)
ここで作成したフィルタに画像を設定して、エフェクト処理をしていく

エフェクトのパラメータを初期化する

effectFilter.setDefaults()

CIFilterのインスタンスに、エフェクトで必要なパラメータのデフォルト値を指定する
※今回はデフォルト値をそのまま使う。

CIFilterのインスタンスにエフェクトする画像を取り出す。

effectFilter.setValue(inputImage, forKey: kCIInputImageKey)

setValue はCIFilterのメソッド

第一引数にエフェクトしたい画像をセットする。
第二引数は forKeyってなんだろう?

  1. CIFilterのインスタンス (effectFilter)作成時にエフェクトしたいフィルター名を指定する
  2. そのCIFilterのインスタンス (effectFilter)のメソッド setValueでエフェクトしたい画像を指定する。

フィルターを適応させるには、CIFilterのインスタンスが必要。

エフェクト後のCIImage形式の画像を取り出す

guard let outputImage = effectFilter.outputImage else{
    return
}

そのCIFilterのインスタンス (effectFilter)のプロパティ outputImage

画像加工するための作業領域を確保する

let ciContext = CIContext(options: nil)
  • CIContextのインスタンスを作成する
  • エフェクトなどの画像処理する時に、画像を加工するための作業領域を確保する

エフェクトの加工が終わった画像を取得するために、CIContextの機能を使って、エフェクト後の画像を生成する。

Filter加工済みのCGImageを生成する

guard let cgImage = ciContext.createCGImage(outputImage,from:outputImage.extent)else{
    return
}

エフェクト後の画像の処理をCIContext上に描写して、結果として
CGImage形式の画像を取得する

CGImageはCIContextインスタンスのcreateメソッドを使用して生成している。
第一引数にCIImageを指定する
第二引数に描写範囲を設定する(outputImage.extentは全体という意味)

Image viewに格納まで

effectImage.image = UIImage(cgImage:cgImage,scale:1.0,orientation:rotate)

エフェクト後の画像をCGImageからUIImageに変換する
(変換しないとImage viewに格納できない)
UIImageに変換する時に回転角度を指定する。

型の変換

  1. 撮影後のもと画像 (UIImage型)
  2. Core Image用の画像にする(CIImage型)
  3. フィルタ(CIFilter型)に画像入力する
  4. フィルタ加工を行う情報の生成(effectFilter.outputImageメソッド)
  5. 画像の加工を生成する(CGImage型)
  6. エフェクトされた画像をImageViewに表示する(UIImage型)

2019年の20の目標

あけおめことよろです。

今年の目標を20個考えました。ふわふわした内容もありますが、どうか許してくださいね。これを目標に2019年頑張っていこうかなと。

f:id:igatann:20181216205448p:plain

20個の目標

  1. 行きたくないと思った飲み会に行かない
  2. 本を100冊読む
  3. 映画を50本観る
  4. 陰口を言わない
  5. 嫌な人に近寄らない
  6. Twitterで知り合った人に会う
  7. プログラミングセミナーに行ってみる
  8. 英語の学習をする
  9. swiftの基礎をマスターする
  10. 個人でiosアプリ3つリリースする
  11. 無駄遣いをしない
  12. ブログを月に5記事は書く
  13. githubで何か公開、自由に扱えるようにする
  14. 禁煙をする
  15. ios開発の仕事をする
  16. 明るく振る舞う
  17. 嫌なことがあっても酒に逃げない
  18. 年収を2018年よりプラス50万
  19. クラウドワークス案件を10件こなす
  20. 引越しをする