Archive for 5月, 2016

2016/05/31 デスクトップピクチャを白いピクチャとトグルで差し替え

ソフトウェアの説明書などを作る際に、ウィンドウやメニューなどの画面のスクリーンショットを撮ることが多々あります。そのような場合に、一時的にデスクトップピクチャを白い色にしておきたいことがあります。通常デスクトップピクチャと白いピクチャの切り替えを行うAppleScriptです。

普通にスクリプトエディタで本スクリプトをオープンしておいて、実行するたびにトグルで状態が切り替わります。

img_3596_resized.png
▲通常のデスクトップピクチャの表示状態

img_3597_resized.png
▲スクリーンショットを撮るために背景を白い画像に設定した状態

AppleScript名:デスクトップピクチャを白いピクチャとトグルで差し替え
– Created 2016-05-31 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”

property aSwitch : false
property desktopPictures : {}
property aColpath : “”

if aSwitch = false then
  –デスクトップを白くする
  
set desktopPictures to getDesktopPicturePathList() of me
  
–白い画像を作成してデスクトップピクチャに設定
  
set aColpath to makeColordImageToTmp(255, 255, 255, 255) of me –R,G,B,A(それぞれ 0〜255)
  
setDesktopPicture(aColpath) of me
  
set aSwitch to true
else
  –保存しておいたDesktop Pictureのリストを戻す
  
setDesktopPicturePathList(desktopPictures) of me
  
do shell script “rm -f “ & quoted form of aColpath
  
set aSwitch to false
end if

–デスクトップピクチャの状態を復帰する
on setDesktopPicturePathList(aliasList)
  if aliasList = {} then
    display notification “保存しておいたデスクトップピクチャのリストが空になっています”
    
return
  end if
  
  
tell application “System Events”
    set dCount to count every desktop
    
repeat with i from 1 to dCount
      set j to contents of item i of aliasList
      
tell desktop i
        set picture to (POSIX path of j)
      end tell
    end repeat
  end tell
end setDesktopPicturePathList

–デスクトップピクチャの強制指定
on setDesktopPicture(aPathStr)
  tell application “System Events”
    set picture of every desktop to aPathStr
  end tell
end setDesktopPicture

–デスクトップピクチャのパスをaliasリストで取得
on getDesktopPicturePathList()
  set pList to {}
  
tell application “System Events”
    set dCount to count every desktop
    
repeat with i from 1 to dCount
      tell desktop i
        set aPic to (picture as POSIX file) as alias
        
set end of pList to aPic
      end tell
    end repeat
  end tell
  
return pList
end getDesktopPicturePathList

–テンポラリフォルダに指定色の画像を作成
on makeColordImageToTmp(rDat as integer, gDat as integer, bDat as integer, aDat as integer)
  set rCol to 255 / rDat
  
set gCol to 255 / gDat
  
set bCol to 255 / bDat
  
set aCol to 255 / aDat
  

  
set aColor to current application’s NSColor’s colorWithDeviceRed:rCol green:gCol blue:bCol alpha:aCol
  
set aDesktopPath to current application’s NSString’s stringWithString:(POSIX path of (path to temporary items))
  
set savePath to aDesktopPath’s stringByAppendingString:((current application’s NSUUID’s UUID()’s UUIDString())’s stringByAppendingString:“.png”)
  
set aRes to makeImageWithFilledWithColor(1, 1, savePath, aColor) of me
  
return (savePath as string)
end makeColordImageToTmp

–指定サイズの画像を作成し、指定色で塗ってファイル書き出し
on makeImageWithFilledWithColor(aWidth, aHeight, outPath, fillColor)
  –Imageの作成  
  
set anImage to current application’s NSImage’s alloc()’s initWithSize:(current application’s NSMakeSize(aWidth, aHeight))
  
  
–描画実行
  
anImage’s lockFocus()
  
set theRect to {{x:0, y:0}, {height:aHeight, width:aWidth}}
  
set theNSBezierPath to current application’s NSBezierPath’s bezierPath
  
theNSBezierPath’s appendBezierPathWithRect:theRect
  
fillColor’s |set|()
  
theNSBezierPath’s fill()
  
anImage’s unlockFocus() –描画ここまで
  
  
–生成した画像のRaw画像を作成
  
set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to current application’s NSBitmapImageRep’s imageRepWithData:imageRep
  
set myNewImageData to (aRawimg’s representationUsingType:(current application’s NSPNGFileType) |properties|:(missing value))
  
  
–書き出しファイルパス情報を作成
  
set pathString to current application’s NSString’s stringWithString:outPath
  
set newPath to pathString’s stringByExpandingTildeInPath()
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
return aRes –成功ならtrue、失敗ならfalseが返る
  
end makeImageWithFilledWithColor

★Click Here to Open This Script 

2016/05/30 Pure ASでチルダ入りパス文字列展開

チルダ入りのPOSIX path文字列(例:~/Library)をフルパス(/Users/me/Library)に展開する処理を行うAppleScriptです。

チルダの展開については、Cocoaの機能を用いるルーチンばかり使っていましたが、Pure AppleScript(Cocoaの機能を利用しないものをあえてこう呼ぶ)でも実行できるものを見つけて(ひとりで)腰を抜かしていました。

yyyeyoyycyaye-2016-05-30-183747_resized.png

一応1,000回繰り返し実行してスピードを計測してみたところ、ASOC版のほうが18倍ぐらい速いようです。ただ、そうむやみに実行するような内容でもないため、この程度なら速度よりも「思い出しやすさ」あたりがキーになりそうです。

AppleScript名:ASOCでチルダ入りパス展開
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set bPath to “~/Desktop”
set pathString to current application’s NSString’s stringWithString:bPath
set newPath to pathString’s stringByExpandingTildeInPath() as string
–>  (NSString) “/Users/me/Desktop”

★Click Here to Open This Script 

AppleScript名:Pure ASでチルダ入りパス展開
– Created 2016-05-13 by Christopher Stone

set aPath to “~/Desktop”
set aRes to expandTildeInPath(aPath) of me
–>  ”/Users/me/Desktop”

on expandTildeInPath(thePath)
  tell application “System Events”
    return (POSIX path of (disk item thePath))
  end tell
end expandTildeInPath

★Click Here to Open This Script 

2016/05/30 “GUI Scripting”と”UI element Scripting”

Mac OS X上の指定アプリケーションの指定のGUI(メニューやボタンなど)を強制的に動かしたり(そのためのイベントを送ったり)、各種プロパティを取得したりする、強制コントロールのための機能を、一般的に「GUI Scripting」と呼んでいます。

AppleScriptから見れば一部の特殊機能(AppleScriptに対して機能を解放していないメニュー項目など)を利用するための例外的に使用する機能です。Automatorの「記録」機能がこのGUI Scriptingを用いて実装されているため(GUI Scriptingのコードを生成するため)、AutomatorからAppleScriptを覚えたというユーザーにとっては「AppleScriptは部品や座標をクリックする命令で書くものだ」という誤解を与えがちで、実際にTwitter上でそのようなユーザーに何人か遭遇しています。

さて、このGUI Scriptingについて、Appleが公式にどのような名称で呼んでいるかといえば、それは「UI element Scripting」です。この、知っていても自慢にならず、世間一般にも認知されていない言葉が公式に(だけ)使われ続けているのかは不明ですが、実際にMac OS Xにデフォルトインストールされているサンプルスクリプトに、その姿を見つけることができます。

/Library/Scripts/UI Element Scripts

フォルダに(確認はOS X 10.11.5上で実施)、一般的にはGUI Scripting、Apple公式にはUI element Scriptingと呼ばれるもののサンプルScriptが入っています。

uie3.jpg

そして、これらのサンプルScript冒頭にあるCopyright表記部分には、「UI element scripting」と明記されています。WWDCのAppleScript関連のセッションでも「UI element scripting」と呼んでいるのを見かけました。

さらに、System Events.appのAppleScript用語辞書中にも「UI elements enabled」の予約語が確認できます。これは、GUI Scriptingが有効かどうかをAppleScriptのプログラム側から確認するためのプロパティです。

uie1_resized.png

uie2.jpg

ただ、AppleScriptのRelease NotesやWeb上の資料でこの「UI element scripting」の名前に遭遇することはほとんどありません。不思議です。

「GUI Scripting」という言葉では他社の商標にひっかかるとか、自社独自のテクノロジーであることを主張できないとか、おそらくApple社内のリーガル(法務部)が名称を問題視した結果、すでに周知された一般名称とは別に正式名称を作ったと推測するものです(ありがち)。ただ、無理やり作ったので社内外で誰も使っていない、と。

同様の不思議な言葉に、Appleも誰も使っていない「AppleScript/Objective-C」という言葉があります。これは、AppleScriptObjC(ASOC)のことを指す言葉なのですが、何年か(2013年?)のWWDCのセッションでSal Soghoianが突然使い始めたものです。

従来のASOCと何が違うのかと悩んだものでしたが、これも恐らく「新しい言葉を商標登録するのは面倒だし却下されたので、すでに登録してある単語の組み合わせで表記しろ」(ありがち)という指摘がリーガルからあって、仕方なく嫌々使っているものと推測するものです。こちらは幸いなことにWWDCのセッション以外ほとんど遭遇したことはありません。

pathtosamples_resized.png

AppleScript名:Get User Name.applescript
(*
Get User Name

This script uses UI element scripting to get the name for the
current user.

Copyright © 2013 Apple Inc.

You may incorporate this Apple sample code into your program(s) without
restriction. This Apple sample code has been provided “AS IS” and the
responsibility for its operation is yours. You are not permitted to
redistribute this Apple sample code as “Apple sample code” after having
made changes. If you’re going to redistribute the code, we require
that you make it clear that the code was descended from Apple sample
code, but that you’ve made changes.
*)


tell application “System Preferences”
  activate
  
set current pane to pane “com.apple.preferences.users”
end tell

try
  tell application “System Events”
    tell tab group 1 of window “Users & Groups” of process “System Preferences”
      delay 2
      
click radio button “Password”
      
delay 2
      
set theResult to value of text field “Full name:”
    end tell
  end tell
  
activate me
  
display dialog “Full name: “ & theResult
on error errMsg
  display dialog “Error: “ & errMsg
end try

★Click Here to Open This Script 

AppleScript名:Check If UI Element Scripting is enabled
tell application “System Events”
  set aRes to (UI elements enabled)
end tell

★Click Here to Open This Script 

2016/05/18 Security Update 2016-003でOS X 10.10.5もSafari 9.1.1に

昨日のOS X 10.11.5アップデートに引き続き、OS X 10.10.5にもSecurity Updateがリリースされました。

Safariのバージョンも同様にv9.1.1となり、「開発」メニューの「Apple EventsからのJavaScriptを許可」が新設され、デフォルト設定でのAppleScriptからのdo javascriptコマンドの実行が抑止されるようになりました。

AppleScriptからのコントロールを行う場合には、あらかじめこの「Apple EventsからのJavaScriptを許可」にチェックを入れておく必要があります。

2016/05/17 Duet DisplayのMac側プロセスの死活判定を定期的に実行

iOS用のDuet Displayは、iOSデバイスをUSB経由でMac/Windows機とつなぎ、iOSデバイスを外部ディスプレイ化するアプリです。

AppStoreで1,900円(記事作成時現在の価格)でiOSアプリを購入+インストール、Mac側にはDuet Displayのホームページから無料ダウンロード可能なツールをインストールします。

このDuet Displayを使って、ちょっと使い道のなかったiPadなどをMacのサブディスプレイにすることができます。以前は、Air Displayを使って無線LAN経由でiPadを外部ディスプレイ化してもみましたが、パフォーマンスがいまいちなうえにソフトウェアの安定性が残念なレベルだったので使用をやめてしまいました。

img_3577_resized.png

Duet Displayはさすがにゲームを快適に行えるほどではありませんが、ちょっとした用途であれば違和感なく使えるパフォーマンス。

3・4日ほどは便利に使っていたものの、途中でMac側のduetプロセスがコケたりして、急にディスプレイ表示が消える現象に直面。サブディスプレイとして使っている場合には冗談ぐらいで済みますが、メインディスプレイとして使っていた場合には悲惨です(メインディスプレイとして使ってほしくない雰囲気)。

いろいろ実験(長期間起動させっぱなしとか、スリープからの回復を連続して行うとか)を行ったところ、duetプロセスが落ちることは避けられないという結論に至りました(落ちるものは落ちる)。

そこで、Mac側のduetプロセスの死活判定を定期的に行い、死んでいた場合には起動し直すAppleScriptアプレットを作って運用してみました。このプロセス死活判定は、以前に作成したものを使いまわしたため、プログラムはほぼ2〜3行追加しただけです。

このような仕組みを用意したおかげで、iPadをMac miniのメインディスプレイに設定して、duetプロセスがコケて表示が消えても自動で表示が回復するようになりました。idleハンドラ内のタイマー割り込み時間(秒)を現在は10秒にしていますが、もうちょっと短い間隔でチェックしてもよいと思います。

本AppleScriptはスクリプトエディタで「アプリケーション」として保存し、オプションで「ハンドラの実行後に終了しない」を指定することで立ち上げっぱなしの運用が可能です。また、Dock上から「ログイン時に開く」にチェックすることで、電源オン時→ログイン時に自動起動されるため、おすすめです。

AppleScript名:restartDuet
on run
  idle
end run

on idle
  set aRes to detectAppAliveByID(“com.kairos.duet”) of me
  
if aRes is not equal to true then
    tell application id “com.kairos.duet” to launch
  end if
  
return 10
end idle

–指定プロセスの死活判定(Bundle IDで判定)
on detectAppAliveByID(aProcBundleID)
  set aProcBundleID to aProcBundleID as string
  
  
–Phase 1 psコマンド経由で状態を確認してみる
  
set aRes to false
  
try
    tell application “System Events”
      set aList to bundle identifier of every process
      
if aProcBundleID is in aList then
        
        
set tmpList to name of every process whose bundle identifier = aProcBundleID
        
set aProcName to contents of first item of tmpList
        
        
set aRes to true
        
tell process aProcName
          set processID to unix id –プロセスIDを取得
        end tell
        
        
set processID to processID as string
        
        
–指定プロセスがゾンビプロセス化しているかどうかを判定
        
set procState to (words of (do shell script “/bin/ps “ & processID & ” | cut -d ’ ’ -f 6″)) as string
        
        
if procState contains “Z” then
          –ゾンビプロセスを殺す
          
do shell script “/bin/kill -9 “ & processID
          
return “killed”
        end if
      else
        –指定したBundle IDのプロセスが存在しない場合falseでリターン
        
return false
      end if
    end tell
  on error
    –異常発生時にはさっさとリターン
    
return false
  end try
  
  
–Phase 2 指定アプリに直接コンタクトして反応を見る
  
try
    with timeout of 3 seconds
      tell application id aProcBundleID
        set aTmpvar to name –これができない(Scriptableな)アプリはほとんどないだろう(多分)
      end tell
    end timeout
  on error
    –名称を取得できなかった場合にはコケていると見なしてプロセスを殺す
    
do shell script “/bin/kill -9 “ & processID
    
return “killed”
  end try
  
  
return aRes
end detectAppAliveByID

★Click Here to Open This Script 

2016/05/17 OS X 10.11.5+Safari 9.1.1、新たなAS制限機能が増える

本日、OS X 10.11.5が正式リリースされました。OS X 10.11, El Capitanの最終リリースということになるのでしょう。OS X 10.12がWWDCで発表になり(多分)、2016年10月ごろにリリースになるというのが通例のスケジュールです。

OS X 10.11.5およびSafari 9.1.1では、AppleScript的には大きな変化を経験することになります。

4ac2e0d2-5af0-4a5c-88e6-7811e4b4fe71.jpg

いままで野放図にSafariをdo javascript命令でこづきまわしていましたが、この機能がデフォルトではオフになります。

fb082ac7-6e16-482b-a542-1147a9d548b1.jpg

Safariの「環境設定」>「詳細」で「メニューバーに”開発”メニューを表示」コマンドを実行して「開発」メニューを表示させ、「開発」メニューの「Apple EventsからのJavaScriptを許可」を実行してはじめてdo javascript命令が有効になります。

# 1回実行すれば、その状態が維持されます

このため、Safariでdo javascript命令を使って処理を行う場合には、無難なコマンドを最初に実行してエラーが発生しないかどうかを確認し、エラー発生時には「Apple EventsからのJavaScriptを許可」を実行してもらうようにダイアログを出して実行終了するよう、処理を追加すべきでしょう。

2016/05/12 表計算ソフトの選択範囲のデータをMarkdown形式の表テキストに変換する

「技術書典」に向けてAppleScript本をMarkdownエディタ「MacDown」で快調に執筆中の今日このごろ。世の中にあふれるMarkdownエディタから厳選してMacDownに行き着きました。

md0.png

一応、最低限レベルながらAppleScriptに対応しているMarkdownエディタは「MacDown」だけでした。

AppleScript対応/非対応を問わず、メジャーなエディタを調べてこれが一番よかったのは……本Blogに掲載している色分けプログラムリスト(HTML)を本文中にペーストして、テキストとしてではなくそのままHTMLとして解釈して表にレンダリングしてくれたこと(仕様的に微妙な点なので、将来にわたって維持されるかどうかは不明)。

md11_resized.png

他のエディタでは本文中にHTMLのタグを入れるという手は使えませんでした(Tableタグだけで実験したので、もしかするともうちょっといろいろやってみると認識されたのかも??)。

そんな、自分のニーズにばっちり合っているMacDownですが、使っているうちにいろいろ山のように不満も出てくるもので、そのうちのひとつに「表データを入れにくい」というものがありました。

スクラッチでゼロから表を起こすのには、Markdown書式の軽量マークアップの表タグはとてもいいと思うのですが、「ありもののデータがすでに存在している」場合には、少々困ってしまうところです。

あまりにあまねく誰もが直面する問題なので、すでにどこかで誰かが同じような変換ツールを書いている可能性が高いですが、この程度ならたいした手間はかからないので、AppleScriptで書いてしまいました。

まずは、Markdown書式における表の作り方を確認。

header1|header2|header3
—|—|—
col1|col2|col3
col4|col5|col6
col7|col8|col9

最低限、こんな風に書いておけば表として認識されるようです(MacDown v0.6上で確認。他のエディタでは傾向が違うかも)。

md00_resized.png

ヘルプファイルやサンプルなどではもっとスペースを入れてきれいに書いてありましたが、そんなきれいに書く必要はないことがわかりました。

excel1.png

まずは、Microsoft Excel版(バージョン14.6.3にて確認)。Excel上のデータを選択してAppleScriptを実行すると、Markdown形式の表データがクリップボードに転送されます。MacDownにはselection(選択範囲)という予約語がないので、選択範囲に対して転送するという手が使えないため、クリップボードに転送しておいてユーザーにペースト動作を行ってもらおうというところです。

numbers1_resized.png

次に、Numbers(v3.6.2)版。Numbersのドキュメント上でデータを選択しておくと、Markdown形式の表データがクリップボードに転送されます。Excelバージョンのプログラムを流用するために、Excelと同様のデータの取得方法を行うルーチンをもってきました(すでに作ってあった)。Numbersの選択範囲のデータの返し方がアレでナニなのでやや苦労していますが、サブルーチンの再利用ですぐに差し替えできました。

md10_resized.png

AppleScript名:Excelの選択範囲を取得してMarkdown書式の表に変換する
– Created 2016-05-12 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set aSeparator to “|”
–set aCell to “—:” –Align Right
set aCell to “:—:” –Align Center
–set aCell to “:—” –Align Left

set aLineTerminator to return

tell application “Microsoft Excel”
  set aSel to string value of selection
end tell

if aSel = “” then
  tell current application
    display dialog “Excelのワークシート上で何も選択されていません” with icon 2 buttons {“OK”} default button 1 with title “選択範囲エラー”
    
return
  end tell
end if

–選択範囲の横幅チェック、ヘッダー部のデータ作成
set colNum to length of (contents of first item of aSel)
set sepList to {}
repeat colNum times
  set end of sepList to aCell
end repeat

–ヘッダーセパレータを配列の2番目に挿入する
set newList to insListItem(aSel, sepList, 2) of me

–Markdown書式の表を文字列で作成し、クリップボードに転送する
set outStr to “”
repeat with i in newList
  set outStr to outStr & retStrFromArrayWithDelimiter(contents of i, aSeparator) of me & aLineTerminator
end repeat

set the clipboard to outStr –クリップボードに転送

–指定のリスト(2次元配列)に、要素(1次元配列)を、指定箇所(1はじまり)にインサートする
on insListItem(aList as list, insList as list, insertItemNum as integer)
  set newList to {}
  
set itemCounter to 1
  
repeat with i in aList
    if itemCounter = insertItemNum then
      set the end of newList to insList
    end if
    
set end of newList to (contents of i)
    
set itemCounter to itemCounter + 1
  end repeat
  
return newList
end insListItem

–リストを指定デリミタをはさんでテキスト化
on retStrFromArrayWithDelimiter(aList as list, aDelim as string)
  set anArray to current application’s NSArray’s arrayWithArray:aList
  
set aRes to anArray’s componentsJoinedByString:aDelim
  
return aRes as text
end retStrFromArrayWithDelimiter

on retArrowText(aList as list, aDelim as string) –自分のASでよく使うハンドラ名称なので、同じものを用意
  return my retStrFromArrayWithDelimiter(aList, aDelim)
end retArrowText

★Click Here to Open This Script 

AppleScript名:Numbersの選択範囲を取得してMarkdown書式の表に変換する
– Created 2016-05-12 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set aSeparator to “|”
–set aCell to “—:” –Align Right
set aCell to “:—:” –Align Center
–set aCell to “:—” –Align Left

set aLineTerminator to return

–Numbersの選択範囲からExcel仕様で2Dリストを返す
set aSel to get2DListFromNumbersSelection() of me

if aSel = “” then
  tell current application
    display dialog “Numbersのワークシート上で何も選択されていません” with icon 2 buttons {“OK”} default button 1 with title “選択範囲エラー”
    
return
  end tell
end if

–選択範囲の横幅チェック、ヘッダー部のデータ作成
set colNum to length of (contents of first item of aSel)
set sepList to {}
repeat colNum times
  set end of sepList to aCell
end repeat

–ヘッダーセパレータを配列の2番目に挿入する
set newList to insListItem(aSel, sepList, 2) of me

–Markdown書式の表を文字列で作成し、クリップボードに転送する
set outStr to “”
repeat with i in newList
  set outStr to outStr & retStrFromArrayWithDelimiter(contents of i, aSeparator) of me & aLineTerminator
end repeat

set the clipboard to outStr –クリップボードに転送

–指定のリスト(2次元配列)に、要素(1次元配列)を、指定箇所(1はじまり)にインサートする
on insListItem(aList as list, insList as list, insertItemNum as integer)
  set newList to {}
  
set itemCounter to 1
  
repeat with i in aList
    if itemCounter = insertItemNum then
      set the end of newList to insList
    end if
    
set end of newList to (contents of i)
    
set itemCounter to itemCounter + 1
  end repeat
  
return newList
end insListItem

–リストを指定デリミタをはさんでテキスト化
on retStrFromArrayWithDelimiter(aList as list, aDelim as string)
  set anArray to current application’s NSArray’s arrayWithArray:aList
  
set aRes to anArray’s componentsJoinedByString:aDelim
  
return aRes as text
end retStrFromArrayWithDelimiter

on retArrowText(aList as list, aDelim as string) –自分のASでよく使うハンドラ名称なので、同じものを用意
  return my retStrFromArrayWithDelimiter(aList, aDelim)
end retArrowText

–テキストを指定デリミタでリスト化
on parseByDelim(aData, aDelim)
  set aText to current application’s NSString’s stringWithString:aData
  
set aList to aText’s componentsSeparatedByString:aDelim
  
return aList as list
end parseByDelim

on get2DListFromNumbersSelection()
  –Numbersで選択範囲を縦に区切ったリストを返す
  
tell application “Numbers”
    tell document 1
      tell sheet 1
        tell table 1
          try
            set selList to value of every cell of selection range –選択範囲のデータを取得
          on error
            return “” –何も選択されてなかった場合
          end try
          
          
set selName to name of selection range –選択範囲のrange情報を取得
          
set {s1, s2} to parseByDelim(selName, “:”) of me
          
          
–始点の情報を取得する
          
set s1Row to (address of row of range s1) as integer
          
set s1Column to (address of column of range s1) as integer
          
          
–終点の情報を取得する
          
set s2Row to (address of row of range s2) as integer
          
set s2Column to (address of column of range s2) as integer
          
          
–選択範囲の情報を取得する
          
set selHeight to s2Row - s1Row + 1 –高さ(Height of selection range)
          
set selWidth to s2Column - s1Column + 1 –幅(Width of selection range)
          
        end tell
      end tell
    end tell
  end tell
  
  
set aLen to length of selList
  
set aaLen to selHeight
  
  
set bList to {}
  
repeat with i from 1 to aaLen
    set aHoriList to {}
    
    
repeat with ii from 1 to selWidth
      set j1 to ii + (i - 1) * selWidth
      
set tmpCon to contents of item j1 of selList
      
      
set aClass to class of tmpCon
      
if aClass = number or aClass = integer or aClass = real then
        set tmpCon to tmpCon as integer
      end if
      
      
set the end of aHoriList to tmpCon
    end repeat
    
    
set the end of bList to aHoriList
  end repeat
  
  
return bList
  
end get2DListFromNumbersSelection

★Click Here to Open This Script 

2016/05/11 FileMaker Pro v15, Keynote v6.6.2, Pages v5.6.2, Numbers v3.6.2が登場

今日は大物プリケーションのアップデートが集中してやってきました。

FileMaker Proの新バージョン、v15のお試し版をダウンロードしてためしてみました。主にモバイル(iPhone、iPad)での機能アップが中心で、Mac上での開発および運用環境としては、スクリプト記述がやりやすくなった(エラーが発生したステップの色が変わるとか)、というあたりで「小幅な改善」という印象を受けます。

FileMaker v14からのAppleScript用語辞書の変更はとくにありません。

FileMakerのWeb系ソリューションについては、AmazonのAWSみたいなクラウド・ホスティングサービスでもないと正直手を出しにくい印象を受けています。

これらのほかに、AppleのKeynote、Pages、Numbersも小幅なアップデート。前バージョンからのAppleScript用語辞書の変更点はとくにありません。

keynote_sdef.png
ツール(ASDictionary)でアプリケーションの用語辞書をHTMLに書き出しして、diffツールで比較。有意な差分が認められた場合にはラベルをつけています

2016/05/11 ShangriLa Anime API V1のデータを取得する

技術書典の一般向けサイトで、参加サークルの詳細な説明文が見られるようになったので、ひととおり見てみました。すると、ノーマークだったサークルが面白いことをやっていることが分かったので、ちょっと見てみました。

ブースB-11の「秋葉原IT戦略研究所」さんが「SNSデータ解析で見る2016年アニメ界の展望」という本を出されるそうで、それだけだと何のことかわからなかったのですが、Twiter上でハッシュタグをつけてつぶやいている膨大なデータを分析してみた、という話だと理解しました。

その活動の一環として、「秋葉原IT戦略研究所」さんではRESTful APIで呼べるアニメ情報データベースを公開されており、とくに認証も何もかかっていないので気楽に呼べそうです。

そこで、実際にAppleScriptから呼んでみることにしました。実行にはShane StanleyのAppleScript Libraries「Bridge Plus」のインストールを必要とします。

まずは、このデータベースが対象にしているクール(1クール13話、1年を52週と仮定したときに1年は4クール)の情報を取得してみました。各クールが何年何月何日から何年何月何日までなのか、という情報は提供してくれないため、各自でカレンダー計算を行う必要がありそうです(4/1なのに前クールの最終回を放映していたというパターンもあるので、そのあたりどうなるのかルールが少々不明)。

AppleScript名:GET method REST API_Anime API_get cours
– Created 2016-05-11 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use BridgePlus : script “BridgePlus”

set reqURLStr to “http://api.moemoe.tokyo/anime/v1/master/cours”

set aRes to callRestGETAPIAndParseResults(reqURLStr) of me

set aRESTres to json of aRes
set aRESCode to responseCode of aRes
–>  200
set aRESHeader to responseHeader of aRes
–>  {Connection:”keep-alive”, Access-Control-Allow-Origin:”*”, Content-Type:”application/json; charset=utf-8″, Content-Length:”353″, Server:”nginx/1.8.0″, Date:”Wed, 11 May 2016 01:14:49 GMT”}

return aRESTres
–>  (NSDictionary) {7:{id:7, year:2015, cours:3}, 3:{id:3, year:2014, cours:3}, 8:{id:8, year:2015, cours:4}, 4:{id:4, year:2014, cours:4}, 9:{id:9, year:2016, cours:1}, 5:{id:5, year:2015, cours:1}, 1:{id:1, year:2014, cours:1}, 6:{id:6, year:2015, cours:2}, 10:{id:10, year:2016, cours:2}, 2:{id:2, year:2014, cours:2}}

–GET methodのREST APIを呼ぶ
on callRestGETAPIAndParseResults(aURL)
  load framework
  
–Request  
  
set aRequest to current application’s NSMutableURLRequest’s requestWithURL:(current application’s |NSURL|’s URLWithString:aURL)
  
aRequest’s setHTTPMethod:“GET”
  
aRequest’s setCachePolicy:(current application’s NSURLRequestReloadIgnoringLocalCacheData)
  
aRequest’s setHTTPShouldHandleCookies:false
  
aRequest’s setTimeoutInterval:60
  
–CALL REST API
  
set aRes to current application’s NSURLConnection’s sendSynchronousRequest:aRequest returningResponse:(reference) |error|:(missing value)
  
–Parse Results
  
set resList to aRes as list
  
set bRes to contents of (first item of resList)
  
set resStr to current application’s NSString’s alloc()’s initWithData:bRes encoding:(current application’s NSUTF8StringEncoding)
  
set jsonString to current application’s NSString’s stringWithString:resStr
  
set jsonData to jsonString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
  
set aJsonDict to current application’s NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value)
  
–Get Response Code
  
set dRes to contents of second item of resList
  
set resCode to ASify from (dRes’s statusCode())
  
–Get Response Header
  
set resHeaders to ASify from (dRes’s allHeaderFields())
  
return {json:aJsonDict, responseCode:resCode, responseHeader:resHeaders}
end callRestGETAPIAndParseResults

★Click Here to Open This Script 

次に、指定した年のアニメ作品に関する情報を取得。

AppleScript名:GET method REST API_Anime API_getInfo_in_a_year
– Created 2016-05-11 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use BridgePlus : script “BridgePlus”

set reqURLStr to “http://api.moemoe.tokyo/anime/v1/master/” & “2016″

set aRes to callRestGETAPIAndParseResults(reqURLStr) of me

set aRESTres to json of aRes
set aRESCode to responseCode of aRes
–>  200
set aRESHeader to responseHeader of aRes
–>  {Connection:”keep-alive”, Access-Control-Allow-Origin:”*”, Content-Type:”application/json; charset=utf-8″, Content-Length:”353″, Server:”nginx/1.8.0″, Date:”Wed, 11 May 2016 01:14:49 GMT”}

return aRESTres
–>  (NSArray) {{id:281, title:”機動戦士ガンダム サンダーボルト”}, {id:282, title:”プリンス・オブ・ストライド オルタナティブ”}, {id:283, title:”無彩限のファントム・ワールド”}, {id:284, title:”ハルチカ〜ハルタとチカは青春する〜”}, {id:285, title:”ノルン+ノネット”}, {id:286, title:”アクティヴレイド −機動強襲室第八係−”}, {id:287, title:”少女たちは荒野を目指す”}, {id:288, title:”僕だけがいない街”}, {id:289, title:”おじさんとマシュマロ”}, {id:290, title:”ファンタシースターオンライン2 ジ アニメーション”}, {id:291, title:”だがしかし”}, {id:292, title:”暗殺教室(第2期)”}, {id:293, title:”ディバインゲート”}, {id:294, title:”おしえて!ギャル子ちゃん”}, {id:295, title:”石膏ボーイズ”}, {id:296, title:”霊剣山 星屑たちの宴”}, {id:297, title:”GATE 自衛隊 彼の地にて、斯く戦えり(2期)”}, {id:298, title:”昭和元禄落語心中”}, {id:299, title:”紅殻のパンドラ”}, {id:300, title:”ブブキ・ブランキ”}, {id:301, title:”ラクエンロジック”}, {id:302, title:”デュラララ!!×2 結”}, {id:303, title:”ナースウィッチ小麦ちゃんR”}, {id:304, title:”虹色デイズ”}, {id:305, title:”大家さんは思春期!”}, {id:306, title:”Dimension W”}, {id:307, title:”灰と幻想のグリムガル”}, {id:308, title:”シュヴァルツェスマーケン”}, {id:309, title:”最弱無敗の神装機竜(バハムート)”}, {id:310, title:”赤髪の白雪姫(第2期)”}, {id:311, title:”てーきゅう(第7期)”}, {id:312, title:”魔法少女なんてもういいですから。”}, {id:313, title:”蒼の彼方のフォーリズム”}, {id:314, title:”この素晴らしい世界に祝福を!”}, {id:315, title:”亜人”}, {id:316, title:”FAIRY TAIL ZERO”}, {id:317, title:”ももくり”}, {id:318, title:”この男子、魔法がお仕事です。”}, {id:319, title:”SUSHI POLICE”}, {id:320, title:”血液型くん!4″}, {id:321, title:”迷家‐マヨイガ‐”}, {id:322, title:”宇宙パトロールルル子”}, {id:323, title:”機動戦士ガンダムユニコーン RE:0096″}, {id:324, title:”影鰐-KAGEWANI-承”}, {id:325, title:”ぼのぼの”}, {id:326, title:”フューチャーカード バディファイト トリプルディー”}, {id:327, title:”逆転裁判”}, {id:328, title:”学戦都市アスタリスク 2nd SEASON”}, {id:329, title:”僕のヒーローアカデミア”}, {id:330, title:”マクロス”}, {id:331, title:”コンクリート・レボルティオ〜超人幻想〜THE LAST SONG”}, {id:332, title:”くまみこ”}, {id:333, title:”怪盗ジョーカー(シーズン3)”}, {id:334, title:”ばくおん!!”}, {id:335, title:”聖戦ケルベロス 竜刻のファタリテ”}, {id:336, title:”ハンドレッド”}, {id:337, title:”薄桜鬼〜御伽草子〜”}, {id:338, title:”ジョーカー・ゲーム”}, {id:339, title:”双星の陰陽師”}, {id:340, title:”SUPER LOVERS”}, {id:341, title:”鬼斬”}, {id:342, title:”文豪ストレイドッグス”}, {id:343, title:”あんハピ♪”}, {id:344, title:”クロムクロ”}, {id:345, title:”ネトゲの嫁は女の子じゃないと思った?”}, {id:346, title:”甲鉄城のカバネリ”}, {id:347, title:”少年メイド”}, {id:348, title:”坂本ですが?”}, {id:349, title:”田中くんはいつもけだるげ”}, {id:350, title:”キズナイーバー”}, {id:351, title:”はいふり”}, {id:352, title:”ふらいんぐうぃっち”}, {id:353, title:”とんかつDJアゲ太郎”}, {id:354, title:”三者三葉”}, {id:355, title:”うさかめ”}, {id:356, title:”マギ シンドバッドの冒険”}, {id:357, title:”Re:ゼロから始める異世界生活”}, {id:358, title:”うしおととら(第3クール)”}, {id:359, title:”ワガママハイスペック”}, {id:360, title:”ジョジョの奇妙な冒険 ダイヤモンドは砕けない”}, {id:361, title:”テラフォーマーズ リベンジ”}, {id:362, title:”プリパラ(3rdシーズン)”}, {id:363, title:”エンドライド”}, {id:364, title:”ビッグオーダー”}}

–GET methodのREST APIを呼ぶ
on callRestGETAPIAndParseResults(aURL)
  load framework
  
–Request  
  
set aRequest to current application’s NSMutableURLRequest’s requestWithURL:(current application’s |NSURL|’s URLWithString:aURL)
  
aRequest’s setHTTPMethod:“GET”
  
aRequest’s setCachePolicy:(current application’s NSURLRequestReloadIgnoringLocalCacheData)
  
aRequest’s setHTTPShouldHandleCookies:false
  
aRequest’s setTimeoutInterval:60
  
–CALL REST API
  
set aRes to current application’s NSURLConnection’s sendSynchronousRequest:aRequest returningResponse:(reference) |error|:(missing value)
  
–Parse Results
  
set resList to aRes as list
  
set bRes to contents of (first item of resList)
  
set resStr to current application’s NSString’s alloc()’s initWithData:bRes encoding:(current application’s NSUTF8StringEncoding)
  
set jsonString to current application’s NSString’s stringWithString:resStr
  
set jsonData to jsonString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
  
set aJsonDict to current application’s NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value)
  
–Get Response Code
  
set dRes to contents of second item of resList
  
set resCode to ASify from (dRes’s statusCode())
  
–Get Response Header
  
set resHeaders to ASify from (dRes’s allHeaderFields())
  
return {json:aJsonDict, responseCode:resCode, responseHeader:resHeaders}
end callRestGETAPIAndParseResults

★Click Here to Open This Script 

最後に、年およびクール(1〜4)を指定して作品情報を取得するものです。

AppleScript名:GET method REST API_Anime API_getInfo_in_a_year_and_cour
– Created 2016-05-11 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use BridgePlus : script “BridgePlus”

set aYear to 2016
set aCour to 1

set reqURLStr to “http://api.moemoe.tokyo/anime/v1/master/” & (aYear as string) & “/” & (aCour as string)

set aRes to callRestGETAPIAndParseResults(reqURLStr) of me

set aRESTres to json of aRes
set aRESCode to responseCode of aRes
–>  200
set aRESHeader to responseHeader of aRes
–>  {Connection:”keep-alive”, Access-Control-Allow-Origin:”*”, Content-Type:”application/json; charset=utf-8″, Content-Length:”353″, Server:”nginx/1.8.0″, Date:”Wed, 11 May 2016 01:14:49 GMT”}

return aRESTres
–>  (NSArray) {{id:281, title_short3:”", sex:0, sequel:0, created_at:”2016-01-01 23:40:06.0″, public_url:”http://gundam-tb.net/”, twitter_hash_tag:”gundam_tb”, title:”機動戦士ガンダム サンダーボルト”, updated_at:”2016-01-01 23:40:06.0″, twitter_account:”gundam_tb”, title_short1:”サンダーボルト”, title_short2:”", cours_id:9}, …….

–GET methodのREST APIを呼ぶ
on callRestGETAPIAndParseResults(aURL)
  load framework
  
–Request  
  
set aRequest to current application’s NSMutableURLRequest’s requestWithURL:(current application’s |NSURL|’s URLWithString:aURL)
  
aRequest’s setHTTPMethod:“GET”
  
aRequest’s setCachePolicy:(current application’s NSURLRequestReloadIgnoringLocalCacheData)
  
aRequest’s setHTTPShouldHandleCookies:false
  
aRequest’s setTimeoutInterval:60
  
–CALL REST API
  
set aRes to current application’s NSURLConnection’s sendSynchronousRequest:aRequest returningResponse:(reference) |error|:(missing value)
  
–Parse Results
  
set resList to aRes as list
  
set bRes to contents of (first item of resList)
  
set resStr to current application’s NSString’s alloc()’s initWithData:bRes encoding:(current application’s NSUTF8StringEncoding)
  
set jsonString to current application’s NSString’s stringWithString:resStr
  
set jsonData to jsonString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
  
set aJsonDict to current application’s NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value)
  
–Get Response Code
  
set dRes to contents of second item of resList
  
set resCode to ASify from (dRes’s statusCode())
  
–Get Response Header
  
set resHeaders to ASify from (dRes’s allHeaderFields())
  
return {json:aJsonDict, responseCode:resCode, responseHeader:resHeaders}
end callRestGETAPIAndParseResults

★Click Here to Open This Script 

放送されている番組の情報を提供する情報発信元としては、新聞などにテレビ番組のラテ欄情報を提供している東京ニュース通信社あるいは日刊編集センターか、EPGのメタデータを提供している(株)エムデータあたりがBtoB向け専門でやっています。BtoC向けにデータを出すかどうかは不明ですが、話をしてみるといいんじゃないでしょうか?

2016/05/05 技術書典の一般向けサイトがオープン

6/25に秋葉原・通運会館で行われる技術書オンリーの同人誌即売会「技術書典」(入場無料) の一般向けサイトがオープンしました。

参加サークルの一覧、および会場内の配置図を見ることができます。個人的には、量子コンピュータ本とTensorFlow本とVSTプラグイン本に興味津々ですが、実際に見て回ると興味深い本に巡り会えるかもしれません。

参加サークル内では、オライリー本のパロディ「O’creilly」が本家オライリーとほぼ真向かいに配置されるという「ネタ配置」に早くもどよめきが起こっているようです。

当ぴよまるソフトウェアは、地下1FのB-01という入り口に一番近いブース。非常時には真っ先に逃げ出せるという好ロケーションを獲得いたしました。

ただし、地下のため風通しがいまひとつで、かなり暑いか・・・あるいは、冷房が強力にかかって寒い思いをするか、それは実際に行ってみないとわかりません。

2016/05/04 Contacts(旧称:Address Book)のプラグインScriptのフォルダが変わった

最近利用していなかったので、気づかなかったのですが・・・Contacts(旧称:Address Book)のプラグインScriptを入れておくフォルダが(OS X 10.9で)変更になったとのこと。

# Release Notesに書いておくべき内容だと思うのですが(ーー;;

旧:~/Library/Address Book Plug-Ins/
新:~/Library/Application Scripts/com.apple.AddressBook/

plugin_resized.png
以前にアドレスブック用に作成したプラグインScriptも、問題なくContacts用に利用できています

2016/05/02 Google APIを用いてURLを短縮してより小さいQRコードを作成

Google APIを利用して指定のURLを短縮し、QRコードを作成するAppleScriptです。

各種WebサービスをAppleScriptから呼び出して、日々便利に使っています。その中でまったく興味が湧かなかったURL短縮サービスAPI(URL Shortening API)。

たまたま、WebのURLからQRコードを作成して印刷することを検討していたときに、印刷面積を減らしたいというニーズが出てきました(TEPRAで印刷しようとしていたので)。

単純に縮小して印刷する物理的な大きさを小さくすれば、印刷できないこともないのですが、ゴミなどが付着したり経年劣化で退色した場合などに、むりやり小さく印刷するとエラーに遭遇する確率が上がってしまいます。また、解像度の低いプリンターで印刷するときには、エラー発生リスクが上がります。

そこで、長くなりがちなWebのURLを、短縮URLサービスを用いて短くしたうえでQRコード化することを思いつきました(Googleで探してみると、同様の先行事例多数 ^ー^;)。

qrcodes.png

上の図で、左がオリジナルのURLをQRコード化したもの。右がURL短縮してQRコード化したものです。URL短縮がQRコードのサイズの縮小に貢献することが見て取れます。ここで用いた元URLは、

 Original URL—-http://piyocast.com/as/archives/4067
 Shorten URL—-http://goo.gl/kT372B

クラウドストレージ上にあるファイル(Dropboxなど)やGoogle Map上の位置情報を示すURLは長くなりがちですが、いったんURL短縮サービスを経由することで、QRコードに印刷するのに抵抗感のない程度の長さの文字列に圧縮でき、たいへんけっこうなことです(Google Mapsにも短縮URL変換の機能がついていますね、、、)。

実行時には、Googleアカウントを作成してGoogle APIの利用申請を行い、API Keyを取得してAppleScript中に指定してください。また、実行にあたって実行環境にShane StanleyのAppleScript Libraries「Bridge Plus」がインストールしてあることが条件となります。

AppleScript名:POST method REST API_Google Shortener URL and make QR code
– Created 2016-05-01 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use BridgePlus : script “BridgePlus”

property APIKey : “XXxxXxXXXxXxX-XxXXxXXXxxxxXXXXxXxXXxXXX” –Google API Key

set aLongURL to “http://piyocast.com/as/archives/4067″ –Target Long URL
set aShortURL to shortenURL(aLongURL) of me
if aShortURL = “” then return –Error

set dtPath to POSIX path of (path to desktop) & ((current application’s NSUUID’s UUID()’s UUIDString())’s stringByAppendingString:“.png”)
set aRes to writeQRimageAsPNG(aShortURL, dtPath) of me

–指定パスにQRコードをPNG画像で出力
on writeQRimageAsPNG(aTargStr, aTargPath)
  set aStr to current application’s NSString’s stringWithString:aTargStr
  
set strData to aStr’s dataUsingEncoding:(current application’s NSISOLatin1StringEncoding)
  
set qrFilter to current application’s CIFilter’s filterWithName:“CIQRCodeGenerator”
  
qrFilter’s setValue:strData forKey:“inputMessage”
  
qrFilter’s setValue:“H” forKey:“inputCorrectionLevel”
  
set anImage to qrFilter’s outputImage()
  
saveNSImageAtPathAsPNG(anImage, aTargPath) of me
end writeQRimageAsPNG

–NSImageを指定パスにPNG形式で保存
on saveNSImageAtPathAsPNG(anImage, outPath)
  set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to current application’s NSBitmapImageRep’s imageRepWithData:imageRep
  
set pathString to current application’s NSString’s stringWithString:outPath
  
set newPath to pathString’s stringByExpandingTildeInPath()
  
set myNewImageData to (aRawimg’s representationUsingType:(current application’s NSPNGFileType) |properties|:(missing value))
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
return aRes –成功ならtrue、失敗ならfalseが返る
end saveNSImageAtPathAsPNG

–与えられたURL文字列を短縮する
on shortenURL(aLongURL)
  set myAPIKey to my APIKey
  
set reqURLStr to “https://www.googleapis.com/urlshortener/v1/url?key=” & myAPIKey
  
set aRec to {longUrl:aLongURL}
  
set aRes to callRestPOSTAPIAndParseResults(reqURLStr, aRec) of me
  
  
set aRESTres to json of aRes
  
set aRESCode to responseCode of aRes
  
set aRESHeader to responseHeader of aRes
  
  
if aRESCode is not equal to 200 then return “”
  
set aShort to (aRESTres’s valueForKey:“id”) as string
  
return aShort
end shortenURL

–POST methodのREST APIを呼ぶ
on callRestPOSTAPIAndParseResults(aURL, aPostData)
  
  
load framework
  
  
–Request  
  
set dataJson to current application’s NSJSONSerialization’s dataWithJSONObject:aPostData options:0 |error|:(missing value)
  
set aRequest to current application’s NSMutableURLRequest’s requestWithURL:(current application’s |NSURL|’s URLWithString:aURL)
  
aRequest’s setHTTPMethod:“POST”
  
aRequest’s setCachePolicy:(current application’s NSURLRequestReloadIgnoringLocalCacheData)
  
aRequest’s setHTTPShouldHandleCookies:false
  
aRequest’s setTimeoutInterval:60
  
aRequest’s setHTTPBody:dataJson
  
aRequest’s setValue:“application/json” forHTTPHeaderField:“Content-Type”
  
  
–CALL REST API
  
set aRes to current application’s NSURLConnection’s sendSynchronousRequest:aRequest returningResponse:(reference) |error|:(missing value)
  
  
–Parse Results
  
set resList to aRes as list
  
  
set bRes to contents of (first item of resList)
  
set resStr to current application’s NSString’s alloc()’s initWithData:bRes encoding:(current application’s NSUTF8StringEncoding)
  
  
set jsonString to current application’s NSString’s stringWithString:resStr
  
set jsonData to jsonString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
  
set aJsonDict to current application’s NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value)
  
  
–Get Response Code
  
set dRes to contents of second item of resList
  
set resCode to ASify from (dRes’s statusCode())
  
  
–Get Response Header
  
set resHeaders to ASify from (dRes’s allHeaderFields())
  
  
return {json:aJsonDict, responseCode:resCode, responseHeader:resHeaders}
  
end callRestPOSTAPIAndParseResults

★Click Here to Open This Script