Core Data in Action: Application Layout

จากตอนที่แล้ว (Introduction to Persistent Data in iOS)ได้พูดถึงการใช้งาน plist เพื่อบันทึกข้อมูลต่างๆ ที่ผู้ใช้แก้ไขภายในแอพพลิเคชั่น ซึ่งการใช้ไฟล์ plist นั้นเหมาะกับข้อมูลไม่มาก เช่น รายการข้อมูลที่ผู้ใช้สามารถเปลี่ยนแปลงแก้ไขเองได้ ชื่อผู้ใช้ ในกรณีที่ข้อมูลมีขนาดใหญ่หรือต้องการนำเอามาประมวลผลอื่นๆ เช่น วาดกราฟ ทำรายงาน ส่งต่อไปยังผู้ใช้อื่น การใช้ plist ย่อมไม่เหมาะแน่ เพราะการอ่านเขียนไฟล์ขนาดใหญ่บนโทรศัพท์มือถือ นั่นไม่ใช่เรื่องที่ดีแน่นอน นั่นส่งผลให้เราต้องเปลี่ยนไปใช้ SQLite เพื่อเก็บข้อมูลการทำงานต่างๆ ซึ่ง SQLite เป็นการเก็บข้อมูลในรูปแบบของ Relational Database ซึ่งใน iOS มี SQLite APIs พร้อมใช้งานอยู่แล้ว ซึ่ง API จะอยู่ในรูปของ C Function หากสนใจอ่านต่อได้ที่ techotopic.com
Continue reading

Introduction to Persistent Data in iOS

การพัฒนาแอพพลิเคชั่นบน iOS Device, เครื่องคอมพิวเตอร์, หรือแพลตฟอร์มอื่นๆ เรื่องหนึ่งที่สำคัญมาก นั่นก็คือการเก็บข้อมูลต่างๆ ที่ผู้ใช้เคยกำหนดไว้แล้ว เช่น ข้อมูลการลงชื่อเข้าใช้งาน (สำหรับแอพพลิเคชั่น facebook บนมือถือ), การกำหนดกั้นหน้ากั้นหลัง (ในโปรแกรมประเภทประมวลผลคำ) หรือ ค่าต่างๆ ที่กำหนดให้ผู้ใช้อัตโนมัติเมื่อเริ่มทำงานเป็นครั้งแรก ซึ่งแต่ละแพลตฟอร์มการพัฒนานั้น ก็จะมีวิธีการเก็บค่าเหล่านี้ไว้ด้วยวิธีการที่ต่างกันออกไป แต่สามารถแบ่งได้เป็น 2 วิธีใหญ่ๆ คือ การบันทึกลงไฟล์แล้วใช้การเรียกคืนในลักษณะของคำสำคัญที่ชี้ไปยังค่าที่ต้องการนั้น (key-value) เช่น properties file ของ java ซึ่งข้อดีของวิธีการแบบนี้คือเข้าถึงได้สะดวกรวดเร็วในกรณีที่มีข้อมูลไม่มาก แต่ข้อเสียคือต้องบริหารจัดการคำสำคัญ (key) เหล่านั้นให้ดี เพราะมีโอกาสซ้ำกันได้

# Fruit.properties
fruit.durain.name = Durain
fruit.durain.price = 90.00
fruti.durain.fruitNote = Teasty fruit

Continue reading

String Replace in Objective-C

เริ่มต้นด้วยการสร้างรายการตัวอักษรที่ไม่ต้องการ เนื่องจากทำงานกับ deviceToken เลยมีตัวอักษรที่ไม่ต้องการ 3 ตัว ได้แก่ “<", " ", ">” ก็สร้างชุดของตัวอักษรด้วย NSCharacterSet จะได้ว่า

NSCharacterSet *unwantedCharactersInDeviceToken = [NSCharacterSet characterSetWithCharactersInString:@"< >"];

ตอนนี้เราจะได้ชุดตัวอักษรที่ไม่ต้องการเรียบร้อยแล้ว (ตัวแปร unwantedCharactersInDeviceToken) ถัดไปคือการสร้าง NSArray จากข้อความที่เราสนใจ โดยใช้ชุดของตัวอักษรเป็นตัวแบ่ง จะได้ว่า

NSArray *filteredPharses = [[NSString stringWithFormat:@"%@", deviceToken] componentsSeparatedByCharactersInSet:unwantedCharactersInDeviceToken];

โดยที่ filteredPharses คือ ความความที่ถูกแบ่งออกเป็นช่วง ตามตำแหน่งที่พบตัวอักษรที่เราไม่ต้องการ

สุดท้าย คือการรวมเอาข้อความที่แบ่งไว้ด้วยตัวอักษรที่เราไม่ต้องการให้เป็น ข้อความ (NSString) ตามเดิม จะได้ว่า

NSString *finalJoinedMessage = [filteredPharses componentsJoinedByString:@""];

โค้ดสำเร็จรูปจะหน้าตาประมาณนี้

NSCharacterSet *unwantedCharactersInDeviceToken = [NSCharacterSet characterSetWithCharactersInString:@"< >"];
NSString *finalJoinedMessage = [[[NSString stringWithFormat:@"%@", deviceToken] componentsSeparatedByCharactersInSet:unwantedCharactersInDeviceToken] componentsJoinedByString:@""]];

ปล. เขียนไว้อ่านเองกันลืม

Google Maps V3 + HTML5

จากบล็อคก่อนหน้านี้ที่แนะนำการใช้งาน Google Maps V3 ให้ลองไปใช้ดูกันแล้วนั้น อย่างหนึ่งที่ไม่ชอบก็คือตำแหน่งเริ่มต้นนั้นมันตายตัวไปหน่อย คือกำหนดแล้วฝังเข้าไปในโค้ด JavaScript เลย แล้วถ้าเราต้องการทำเว็บแอพพลิเคชั่น (เพื่อให้มันสั้นลงต่อไปจะเรียก ‘แอพ’ หรือ ‘app’) ที่คำนึงถึงตำแหน่งผู้ใช้เป็นสำคัญ เช่น ตำแหน่งร้านอาหารที่น่าสนใจใกล้เคียงนั้นๆ หรือ ร้านค้าลดราคาใกล้ๆ เป็นต้น ดังนั้นอย่างแรกที่จำเป็นก็คือตำแหน่งที่เราอยู่ปัจจุบัน เพื่อนำมาข้อมูลที่เกี่ยวข้องมาแสดงผล

ซึ่งในตัวอย่างที่จะทำนี้เป็นการพัฒนาต่อจากบล็อคก่อนหน้านี้ดังนั้นก็ให้ดาวน์โหลดไฟล์ maps-demo.html.zip มาไว้ที่เครื่องก่อนเพื่อเตรียมตัวแก้ไข ซึ่งด้านในมีโค้ดด้านล่างนี้ (ดูตัวอย่างการแสดงผล)

<!DOCTYPE html>
<html>
  <head>
    <title>Google Maps V3 Demostrate</title>
    <script src="http://maps.googleapis.com/maps/api/js?sensor=true"></script>

    <script>
      function initWithMapStart() {
        var latlng = new google.maps.LatLng(13.75, 100.517);
        var mapOptions = {
                            zoom: 12,
                            center: latlng,
                            mapTypeId: google.maps.MapTypeId.ROADMAP
                        };
        var maps = new google.maps.Map(
                         document.getElementById('map-canvas'),
                         mapOptions
                   );

        var marker = new google.maps.Marker({
                            position: latlng,
                            map: maps,
                            animation: google.maps.Animation.DROP,
                            title: "Welcome to Thailand"
                        });

        var info = new google.maps.InfoWindow({
                            content: '<h1>Hello</h1>'
                        });
        google.maps.event.addListener(marker, 'click', function(){
            info.open(maps, marker);
        });
      }
    </script>

    <style>
      header,
      footer {
        text-align: center;
      }
      #map-canvas {
        display: block;
        margin: 20px auto;
        height: 400px;
        width: 640px;
        background-color: #ccc;
      }
    </style>
  </head>
  <body onload="initWithMapStart()">
    <header>
      <h1>Google Maps Demo</h1>
    <header>
    <article>
      <div id="map-canvas"></div>
    </article>
    <footer>
      <small><a href="http://we.in.th/">we.in.th</a></small>
    </footer>
  </body>
</html>

fig.1: โค้ดเดิมสำหรับแสดงผลแผนที่

จากที่บอกในข้างต้นว่าจะพัฒนาต่อจากของเดิมที่มีอยู่แล้ว โดยสิ่งที่เพิ่มขึ้นมากก็คือคุณสมบัติที่เรียกว่า Geolocation ซึ่งอยู่ใน HTML5 ทำสามารถดึงข้อมูลตำแหน่ง เช่น พิกัด (Latitude, Longitude) หรือ ที่อยู่ปัจจุบัน ของผู้ใช้ขณะนั้นมาแสดง แต่ก่อนที่จะแสดงนั้นเบราเซอร์จะขออนุญาตจากผู้ใช้ก่อนเสมอ หากไม่ต้องการให้เว็บไซต์นำตำแหน่งไปใช้งานก็ปฏิเสธได้ ใช้งานได้กับ IE9+, Firefox 3.5+, Safari5+ และ Google Chrome 4+ โดยที่ ดังนั้นให้เพิ่มโค้ดด้านล่างถัดจากบรรทัดที่ 32 ลงไป ดังนี้

if ( (typeof( window.navigator) != 'undefined') && !!navigator.geolocation ) {
    navigator.geolocation.getCurrentPosition(
        function(position) {
            panToCurrentLocation(position, maps, marker);
        },
        errorOccur
    );
}

fig.2: โค้ดสำหรับพิกัดที่ได้จากเบราเซอร์มาแสดงผล

Google Maps with Location Acquisition Notificationโดยที่

  • บรรทัดที่ 1 คือ การตรวจสอบว่าเบราเซอร์นี้รองรับ Geolocation หรือไม่
  • บรรทัดที่ 2-7 คือ การเรียกใช้งาน Geolocation ผ่านตัวแปร navigator ซึ่งก่อนจะดึงข้อมูลตำแหน่งของผู้ใช้เบราเซอร์จะขออนุญาตผู้ใช้ก่อนเสมอ เมื่อได้รับอนุญาตและได้ตำแหน่งผู้ใช้เรียบร้อยแล้วจะส่งไปยัง function(position) (บรรทัดที่ 3-5) โดยจะส่งไปให้ฟังก์ชั่น panToCurrentLocation ต่อไปพร้อมกับตัวแปร position, maps และ marker แต่ถ้าไม่สามารถอ่านพิกัดได้จะไปทำที่ฟังก์ชั่น errorOccur แทน

ถัดไปคือการสร้างฟังก์ชัน panToCurrentLocation และ errorOccur ขึ้นใหม่ ตามที่ได้ระบุไว้ใน fig.2 ดังนี้

function panToCurrentLocation(position, maps, marker) {
  var latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
  maps.setCenter( latlng );
  maps.panTo( latlng );

  marker.setPosition( latlng );
  marker.setAnimation( google.maps.Animation.DROP );
}

function errorOccur( error ) {
  console.log( error );
}

fig.3: JavaScript สำหรับเปลี่ยนตำแหน่งในแผนที่

โดยที่

  • บรรทัดที่ 2: สร้างพิกัดจากแผนที่ใหม่
  • บรรทัดที่ 3: กำหนดจุดศูนย์กลางให้แผ่นที่ใหม่
  • บรรทัดที่ 4: เลื่อนตำแหน่งของแผนที่ไปยังตำแหน่งใหม่ที่ได้
  • บรรทัดที่ 6: เปลี่ยนตำแหน่งของ marker ให้แสดงที่ตำแหน่งปัจจุบัน
  • บรรทัดที่ 7: กำหนดแอนนิเมชั่นที่จะใช้แสดงผล marker

จากที่ทดลองใช้งานการค้นหาตำแหน่งนั้นอาจคลาดเคลื่อนได้ไม่ถูกต้องทุกครั้ง ดูตัวอย่างได้ที่ไฟล์ maps-demo-navigation หรือดาวน์โหลดไฟล์ maps-demo-navigation.html

ข้อมูลเพิ่มเติม:

Google Maps V3 Introduction

ก่อนหน้านี้เคยเขียนวิธีการนำเอา Google Maps มาใช้งานกับเว็บไซต์ด้วยกัน 2 ตอน (1, 2) ตอนที่เขียนไปนั้น Google Maps เวอร์ชั่น 2.x ปัจจุบันอยู่ในสถานะ deprecated หรืออยู่ระหว่างการเลิกใช้งานนั้นเอง โดยตอนนี้ Google Maps เองก็พยายามเข็ญให้นักพัฒนาขยับไปใช้ Google Maps เวอร์ชั่นปัจจุบันคือเวอร์ชั่น 3 หรือเรียกสั้นๆ ว่า V3 ซึ่งการเรียกใช้งานนั้นง่ายกว่าเวอร์ชั่นเก่ามาก อย่างแรกที่เห็นได้ชัดคือเราไม่จำเป็นต้องสมัครเพื่อขอ API Key สำหรับใช้ดาวน์โหลด Google Maps Library อีกต่อไปแล้ว และการกำหนดค่าทั้งหมดใช้การกำหนดค่าผ่าน Object ที่เข้าใจได้ง่ายกว่าเวอร์ชั่นเก่ามาก
Continue reading

Install wget in OS X

พอดีว่าชอบโปรแกรมช่วยดาวน์โหลดที่ชือว่า wget ที่ทำงานใน Linux เอามาก ส่วนใหญ่จะมากับ Linux Distro อื่นๆ แต่กับ OS X แล้วไม่ได้ใส่ลงมาด้วย เลยต้องไปหามาดาวน์โหลดเอาเอง ซึ่งก็ไม่ได้มีขั้นตอนอะไรสลับซับซ้อนมากนัก
Continue reading

The Way To Lion

ไม่ได้เขียน blog มานานแล้วเหมือนกันแฮะ รู้สึกได้อย่างหนึ่งเลยว่า Social Network ดึงเอา content ที่อยู่ในหตัวแล้วอยากเขียนลง blog ออกไปเยอะทีเดียว

เมื่อวานก่อน (20 ก.ค.) นั่งหลังคดหลังแข็งดาวน์โหลด Lion มาใช้ ($29  ผ่าน Mac App Store) 3.7GB อ้วกเป็นเลือดกันเลยทีเดียว ตอนแรกยังไม่แน่ใจว่าจะลงแบบไหนดี สุดท้ายก็ตัดสินใจได้ว่าเอาแบบ Clean Install ไปเลยแล้วกัน
Continue reading