Code Log

プログラミングの勉強メモを残していきます。

AngularJSで繰り返し処理を実装する

ng-repeatを使ってみる

ng-repeatを使えば繰り返しを簡単に実装できます。
リストの繰り返し処理や絞込みに使われることが多いです。

○HTML

<div ng-controller="MainCtrl">
  <ul ng-repeat="name in names">
    <li>{{name}}</li>
  </ul>
</div>


○JavaScript

var app = angular.module('myApp', []);
app.controller('MainCtrl', function($scope) {
  $scope.names = [
  	'Kazuhito nakamura',
  	'Takeshi matsumoto',
  	'akihiro Tanama',
  	'sayaka takeda',
  	'yoko yamada'
  ];

});

ng-repeatで使うことができる特殊変数

$index: 0から始まる現在のループの位置を示す
$first: ループの一回目ならtrue,それ以外のときはfalse
$middle: ループの最初と最後でなければtrue,それ以外のときはfalse
$last: ループの最後であればtrue, それ以外のときはfalse
$even: $indexが偶数の時はtrue, 奇数の時はfalse
$odd: $indexが奇数の時はtrue, 偶数の時はfalse


○HTML

<div ng-controller="MainCtrl">
  <table>
    <tr>
      <th>value</th>
      <th>$index</th>
      <th>$first</th>
      <th>$middle</th>
      <th>$last</th>
      <th>$even</th>
      <th>$odd</th>
    </tr>
    <tr ng-repeat="name in names">
      <td>{{name}}</td>
      <td>{{$index}}</td>
      <td>{{$first}}</td>
      <td>{{$middle}}</td>
      <td>{{$last}}</td>
      <td>{{$even}}</td>
      <td>{{$odd}}</td>
    </tr>
  </table>
</div>


○JavaScript

var app = angular.module('myApp', []);
app.controller('MainCtrl', function($scope) {
  $scope.names = [
  	'Kazuhito nakamura',
  	'Takeshi matsumoto',
  	'akihiro Tanama',
  	'sayaka takeda',
  	'yoko yamada'
  ];

});


Webアプリ構築のためのAngularJS

Webアプリ構築のためのAngularJS

NSURLSessionを使ってインターネット通信を行う。

import UIKit
import XCPlayground

XCPlaygroundPage.currentPage.needsIndefiniteExecution = true

let session = NSURLSession.sharedSession()

let url = NSURL(string: "http://www.yahoo.co.jp")!

let request = NSURLRequest(URL: url)

let task = session.dataTaskWithRequest(request) {
    (data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in
    
    if let data = data {
        let value = NSString(data: data, encoding: NSUTF8StringEncoding)
        print(value)
    }
}

task.resume()


App Transport Securityとは

ATS(App Transport Security)とは、iOS9から搭載された機能のこと。
通信処理のデフォルトをHTTPSにするもの。ATSを一時的に無効にする方法もAppleから公開されている。

NSUserDefaultsを使って自作クラスをシリアライズ/デシリアライズする

シリアライズとは、オブジェクトの内容をバイナリに変換すること。
バイナリからオブジェクトに復元することをデシリアライズという。

import Foundation


class MyData :NSObject, NSCoding {
    var valueString :String?
    
    override init() {
    }
    
    func encodeWithCoder(aCoder: NSCoder) {
        aCoder.encodeObject(valueString, forKey: "valueString")
    }
    
    required init?(coder aDecoder: NSCoder) {
        valueString = aDecoder.decodeObjectForKey("valueString") as? String
    }
    
    
}

上のようなクラスをNSUserDefaultsに保存して取り出す処理。

    override func viewDidLoad() {
        super.viewDidLoad()
        
        print("process start")
        //NSUserDefaultsの生成
        let userDefaults = NSUserDefaults.standardUserDefaults()
        
        //シリアライズ対象となるインスタンスを生成
        let data = MyData()
        data.valueString = "test"
        
        //NSUserDefaultsにシリアライズしたデータを保存
        let archiveData = NSKeyedArchiver.archivedDataWithRootObject(data)
        userDefaults.setObject(archiveData, forKey: "data")
        userDefaults.synchronize()
        

        //デシリアライズ処理
        if let storedData = userDefaults.objectForKey("data") as? NSData {
            if let unarchivedData = NSKeyedUnarchiver.unarchiveObjectWithData(storedData) as? MyData {
                if let valueString = unarchivedData.valueString {
                    print ("desirialize data:" + valueString)
                }
            }
        }
    }

iOSでデータ保存する仕組み

NSUserDefaults

NSUserDefaultsはiOSアプリのデータ永続性の仕組みのこと。
key=value形式でデータを保存することができる。

NSUserDefaultsで保存したデータはローカルストレージのアプリ内部にplist(プロパティリスト)形式で保存される。plist形式の実体はXMLである。

plistファイルは毎回読み込まれるわけではなく、アプリ起動時にキャッシュに保存される。

NSUserDefaultsは大きすぎる値の保存には向いていない。
なぜなら、キャッシュ動作があるためだ。
メモリに大量のデータを保存するのには向いていない。

Core Data

Core Dataはデータをレコード形式で保存するデータ永続性の仕組みのこと。
Core Dataが提供する関数を利用してレコードを参照する。

Keychain

KeychainはiOS内部のセキュアな場所に保存される仕組みのこと。

iOSのデータ保存場所一覧

AppName.app

アプリ本体そのもので、実行ファイルが含まれる。
アプリに内蔵されている画像データなどを読み取ることができる。

Documents/

ユーザが生成したデータの保存先に利用される。
このディレクトリに保存したデータは共有することができるため、ユーザに見えても問題ないデータの保存に利用する。

Documents/Inbox

ほかのアプリからデータを受け取るためのディレクトリ。
このディレクトリを所有するアプリ自身はこのディレクトリに新規データを生成できないが、読み取ることが可能。

Library

ユーザのデータを除いたデータのためのディレクトリ。
Library/Application Supportディレクトリにはアプリが生成したデータや設定ファイル、アプリ内で購入したゲームの新しいステージなどが配置される。

Library/Cachesディレクトリは高速にアクセスするためにデータを一時的にキャッシュして配置するディレクトリ。比較的簡単に再作成可能なデータの配置に利用する。

Library/PreferencesはNSUserDefaultsを利用して保存した値を格納する。

Tmp/

アプリ利用中にメモリに持ち続ける必要がない一時的なデータを配置できるディレクトリ。
そのデータが必要なくなったタイミングでデータを削除する。

絶対に挫折しない iPhoneアプリ開発「超」入門 増補改訂第4版【Swift 2 & iOS 9】完全対応

絶対に挫折しない iPhoneアプリ開発「超」入門 増補改訂第4版【Swift 2 & iOS 9】完全対応

Swiftでtry〜catch

unc myFunc(value :Int) -> Int {
    var resultValue :Int = 0
    resultValue = value
    return resultValue
}

myFunc(1)


//throw the error
enum MyError :ErrorType {
    case InvalidValue
}

func doubleUp(value :Int) throws -> Int {
    if value < 0 {
        throw MyError.InvalidValue
    }
    
    return value * 2
}


do {
    var doubleResultValue = try doubleUp(-5)
    print("normaly end")
} catch MyError.InvalidValue {
    print("some error occured")
}


//defer
func longMethod() throws {
    sleep(1)
}

do {
    defer {
        print("end up time: \(NSDate())")
    }
    try longMethod()
    print("start up time: \(NSDate())")
} catch {
    print("error occured")
}

if let文でOptional型でラップされた変数をアンラップする。


Optional型とは、値が存在しないかもしれない状態を持つ型のこと。
Optional型を利用するには型の最後に「?」を付ける。
そうすると、nulを代入可能な状態になる。このことを「Optional型でラップする」という。

Optional型でラップされた変数に対して、nilでないことを保証された状態にすることを「アンラップする」という。

ifとletを利用したアンラップ処理はif let文と呼ばれる。

var value :String?
value = "hello"
print(value)
if let value = value {
    print(value)
}

アンラップ後の変数を利用しない場合。

var value :String?

value = "hello"

if let _ = value {
    print("value in not nil")
}

SwiftのArrayとDictionary

import UIKit

var str = "Hello, playground"

let myLabel = UILabel(frame: CGRectMake(0,0,200,50))
myLabel.backgroundColor = UIColor.redColor()
myLabel.text = "Hello, swift"
myLabel.font = UIFont(name: "Georgia", size: 24)
myLabel

//mutable array
var array1 :[String] = [String]()
array1.append("apple")
array1.append("gollila")

//imutable array
let array2 :[String] = [String]()

//this is error
//array2.append("apple")

let array3 :[String] = ["apple","gollila"]
print(array3[0])

//Dictionary
var mutableDic1 :[String:String] = [String:String]()
mutableDic1["apple"] = "small"
mutableDic1["golilla"] = "big"

mutableDic1["apple"]

Swiftのif, for while

//: Playground - noun: a place where people can play

import UIKit

var str = "Hello, playground"


//if
let score = 70

if score>=80 {
    print ("合格です!")
} else {
    print("不合格〜!")
}

print("\(score)点でした。")


//switch
let color = "blue"

switch color {
case "red":
    print("赤やね!")

case "green":
    print("緑やね!")
    
case "pink","yellow":
    print("ピンクか黄色だね!")
    
case "blue":
    print("青やね")
default:
    print("お前の色はなんだーーー!")
}

//tupple
let data = (1000,100,10)
let (sen,hyaku,jyu) = data
let hoge = sen + hyaku
print(hoge)

//label tupple
let user = (name:"yoshida", age:20)
print(user.name)


//for
for num in 1...10 {
    print(num, terminator: ",")
}

for _ in 1...15 {
    let num = arc4random_uniform(100)
    print(num, terminator: ",")
}


let numList = [1,2,3,4,5,6]
var sum = 0
for num in numList {
    sum += num
}

print("合計: \(sum)")


for (var i=0; i<5;i++) {
    let v = i*2
    print(v)
}

C# 指定したプロセス名のprocessを取得し、稼働時間、開始時間、プロセスIDを表示する。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;

namespace ProcessKiller
{
    public partial class Form1 : Form
    {
        bool isRun = false;
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            timer1.Enabled = false;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (isRun)
            {
                string pName = textBox1.Text;
                Process[] pList = Process.GetProcessesByName(pName);
                StringBuilder sb = new StringBuilder();

                label1.Text = "";
                foreach (Process p in pList)
                {
                    DateTime startTime = p.StartTime;
                    TimeSpan runTime = DateTime.Now - startTime;

                    int limitAddTime = int.Parse(comboBox1.Text);
                    DateTime limitTime = p.StartTime.AddMinutes(limitAddTime);

                    sb.Append("[ID:"+ p.Id +"] [プロセス名:" + p.ProcessName + "] [稼働時間:" +
                    String.Format("{0:00}",runTime.Hours) + ":" + String.Format("{0:00}",runTime.Minutes) + ":" + String.Format("{0:00}",runTime.Seconds) + "] [停止予定時刻:" + limitTime + "]" + System.Environment.NewLine);

                    var limitTimeOfDay = limitTime.TimeOfDay;

                    if ((limitTimeOfDay - startTime.TimeOfDay) < runTime)
                    {
                        p.Kill();
                        label4.Text = p.ProcessName + "(ID:" + p.Id + ")をkillしました";
                    }

                }
                label1.Text = sb.ToString();
            }  
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string pName  = textBox1.Text;
            if (String.IsNullOrEmpty(pName))
            {
                MessageBox.Show("プロセス名を入力してください");
                return;
            }
            timer1.Enabled = true;
            isRun = true;
            label4.Text = "監視開始します";
        }

        private void button2_Click(object sender, EventArgs e)
        {
            isRun = false;
            label1.Text = "";
            label4.Text = "";
        }
    }
}