Month: September 2023

  • Apple CarPlay P2

    Apple CarPlay P2

    Hi, Ở phần 1 mình đã giới thiệu đến các bạn tổng quan về CP (CarPlay). Phần này mình sẽ chia sẻ cách để xây dựng một ứng dụng hỗ trợ CP, cụ thể ở đây là ứng dụng hỗ trợ một trong 8 CP types mà apple cung cấp, còn type Automaker thì mình chia sẻ mở bài tiếp theo.

    Bắt đầu nào!!!

    Tạo Project

    Ứng dụng CP cũng là một ứng dụng bình thường, các bạn vẫn sử dụng xCode và tạo project như bình thường. Phần code của phone và CP sẽ là hai phần riêng biệt. Vì trên iPhone quá quen thuộc với các bạn rồi nên ở hướng dẫn này mình chỉ thực hiện hiển thị 1 dòng chữ ở giữa màn hình trên iPhone và tập chung vào việc hiển thị trên CP với các template

    Tạo entitlement file

    Như mình đề cập ở phần 1, với 8 type bình thường của Apple cung cấp thì đi kèm với nó là các entitlement key, thì key này sử dụng ở đâu?. Câu trả lời là key này sử dụng để config trong entitlement file.

    Select file -> New file -> choose Property List

    Điền tên file và chọn create

    Ở đây mình để tên file là CPTemplateSeminar.entitlements

    Sau khi tạo entitlement file thì chúng ta cần nhúng đường path dẫn đến entitlement file vào Code Signing Entitlements bằng cách chọn Project Setting -> Build Setting -> Code Signing Entitlements và set giá trị là path dẫn đến entitlement file

    Tip: Ngoài cách tạo file và nhúng đường path như ở trên, các bạn có thể enable bất kì một Capabilities nào đó trong xCode để xCode tự động tạo ra entitlement file và tự động nhúng đường path vào Code Signing Entitlements

    Sau khi setting Code Signing Entitlements xong, Chúng ta đến bước add entitlement key vào file vừa tạo.
    Ở đây mình sử dụng key com.apple.developer.carplay-audio. (Nếu các bạn chưa biết key này là gì và lấy ở đâu thì các bạn xem lại phần 1 của mình nhé!)

    Implement Template

    Tạo một class kế thừa CPTemplateApplicationSceneDelegate, delegate này có các methods như didConnect, didDisconnectInterfaceController …

    import CarPlay
    
    class CPSceneDelegate: UIResponder, CPTemplateApplicationSceneDelegate {
    
        var interfaceController: CPInterfaceController?
    
        // CarPlay connected
        func templateApplicationScene(_ templateApplicationScene: CPTemplateApplicationScene,
                                      didConnect interfaceController: CPInterfaceController) {
            self.interfaceController = interfaceController
        }
    
        // CarPlay disconnected
        func templateApplicationScene(_ templateApplicationScene: CPTemplateApplicationScene, didDisconnectInterfaceController interfaceController: CPInterfaceController) {
            self.interfaceController = nil
        }
    }
    

    Setting info.plist

    Tất cả các CP app đều phải khai báo CP scene để dử dụng CP Framework. Để khai báo CP scene thì chúng ta khai báo ở trong info.plist

    Khai báo thêm key CPTemplateApplicationSceneSessionRoleApplication theo như hướng dẫn dưới đây:
    Mình set UISceneConfigurationName là CarPlay, UISceneDelegateClassName là class mà mình đã tạo ở bên trên

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
    	<key>UIApplicationSceneManifest</key>
    	<dict>
    		<key>UIApplicationSupportsMultipleScenes</key>
    		<false/>
    		<key>UISceneConfigurations</key>
    		<dict>
    			<key>CPTemplateApplicationSceneSessionRoleApplication</key>
    			<array>
    				<dict>
    					<key>UISceneConfigurationName</key>
    					<string>CarPlay</string>
    					<key>UISceneDelegateClassName</key>
    					<string>$(PRODUCT_MODULE_NAME).CPSceneDelegate</string>
    				</dict>
    			</array>
    			<key>UIWindowSceneSessionRoleApplication</key>
    			<array>
    				<dict>
    					<key>UISceneConfigurationName</key>
    					<string>iPhone</string>
    					<key>UISceneDelegateClassName</key>
    					<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
    					<key>UISceneStoryboardFile</key>
    					<string>Main</string>
    				</dict>
    			</array>
    		</dict>
    	</dict>
    </dict>
    </plist>
    

    Setup Root Template

    Như một ứng dụng thông thường thì CP app cũng cần setup root view. Ở hướng dẫn này mình xây dựng CP app với root template là 1 tab bar bao gồm tab Home và tab Setting. Tab Home và Setting mình sẽ hiển thị list đơn giản

        // CarPlay connected
        func templateApplicationScene(_ templateApplicationScene: CPTemplateApplicationScene,
                                      didConnect interfaceController: CPInterfaceController) {
            self.interfaceController = interfaceController
            interfaceController.setRootTemplate(createTabTemplate(), animated: true, completion: nil)
        }
    import Foundation
    import CarPlay
    
    // MARK: - Tab Template
    extension CPSceneDelegate {
        func createTabTemplate() -> CPTabBarTemplate {
            var tabs: [CPTemplate] = []
    
            let homeItem = CPListItem(text: "Home", detailText: "")
            let homeSection = CPListSection(items: [homeItem])
            let homeTemplate = CPListTemplate(title: "Home", sections: [homeSection])
            homeTemplate.tabImage = UIImage(systemName: "house.fill")
    
            let settingItem = CPListItem(text: "Setting", detailText: "")
            let settingSection = CPListSection(items: [settingItem])
            let settingTemplate = CPListTemplate(title: "Home", sections: [settingSection])
            settingTemplate.tabImage = UIImage(systemName: "gearshape.fill")
    
            tabs.append(homeTemplate)
            tabs.append(settingTemplate)
    
            let tabBar = CPTabBarTemplate(templates: tabs)
            return tabBar
        }
    }
    

    Mình tạo một tab bar bằng cách sử dụng CPTabBarTemplate, và mình set tab bar này thành root template khi iPhone và màn hình trên ô tô được kết nối.

    Đến step này là đã hoàn thành việc coding một ứng dụng hỗ trợ CP rồi, Chúng ta có thể trải nghiệm ứng dụng bằng cách build lên simulator và sau đó mở cửa sổ xCode Simulator để xem thành quả. Tuy nhiên mình sẽ thêm phần action bấm vào item trên màn home và thực hiện di chuyển đến màn hình phát nhạc.

    Tạo Now Playing template

    import Foundation
    import CarPlay
    
    // MARK: - Playing now Template
    extension CPSceneDelegate {
        func createNowPlaying() -> CPNowPlayingTemplate {
            let playing = CPNowPlayingTemplate.shared
            playing.add(self)
            playing.isUpNextButtonEnabled = true
            playing.isAlbumArtistButtonEnabled = true
    
            return playing
        }
    }
    
    extension CPSceneDelegate: CPNowPlayingTemplateObserver {
        
        func nowPlayingTemplateUpNextButtonTapped(_ nowPlayingTemplate: CPNowPlayingTemplate) {
    
        }
    
        func nowPlayingTemplateAlbumArtistButtonTapped(_ nowPlayingTemplate: CPNowPlayingTemplate) {
    
        }
    }

    Thực hiện di chuyển khi bấm vào item trên màn hình Home. Mình sẽ thực hiện pushTemplate đến màn hình Now Playing được tạo bên trên, Các bạn có thể thực hiện push hoặc present tuỳ thích, tuy nhiên ở phần 1 mình cũng có warning là không phải template nào cũng có thể push và present được. Các bạn cứ thử thực hiện để trải nghiệm nhé!

    import Foundation
    import CarPlay
    
    // MARK: - Tab Template
    extension CPSceneDelegate {
        func createTabTemplate() -> CPTabBarTemplate {
            var tabs: [CPTemplate] = []
    
            let homeItem = CPListItem(text: "Home", detailText: "")
            homeItem.handler = { item, completion in
                self.interfaceController?.pushTemplate(self.createNowPlaying(), animated: true, completion: nil)
                completion()
            }
            let homeSection = CPListSection(items: [homeItem])
            let homeTemplate = CPListTemplate(title: "Home", sections: [homeSection])
            homeTemplate.tabImage = UIImage(systemName: "house.fill")
    
            let settingItem = CPListItem(text: "Setting", detailText: "")
            let settingSection = CPListSection(items: [settingItem])
            let settingTemplate = CPListTemplate(title: "Home", sections: [settingSection])
            settingTemplate.tabImage = UIImage(systemName: "gearshape.fill")
    
            tabs.append(homeTemplate)
            tabs.append(settingTemplate)
    
            let tabBar = CPTabBarTemplate(templates: tabs)
            return tabBar
        }
    }
    

    Ở đây mình chỉ sử dụng các template mà Audio type hỗ trợ, các bạn cũng có thể sử dụng các template mà Audio không hỗ trợ để trải nghiệm nhé, ví dụ như sử dụng Action Sheet template. (Lưu ý là app sẽ crash nhé!!!)

    Ngoài ra các bạn cũng có thể xây dựng ứng dụng của mình với các type còn lại để trải nghiệm nhé!

    Kết quả

    Sau khi build trên xCode Simulator mình được kết quả như sau:

    Trên đây là phần mình chia sẻ về cách tạo một ứng dụng hỗ trợ CP sử dụng type là template được cung cấp bởi Apple. Bài tiếp theo mình sẽ chia sẻ về cách tạo một ứng dụng hỗ tợ CP với type Automaker

    Mình hi vọng bài viết có thể giúp ích được cho các bạn. Chúc các bạn thành công!

  • Apple CarPlay P1

    Apple CarPlay P1

    Hi. Apple CarPlay không còn xa lạ với nhiều người, đặc biệt là các anh em sử dụng xe hàng ngày. Vậy làm sao để một ứng dụng hỗ trợ CP? (CarPlay). Trong bài này mình sẽ giới thiệu đến anh em về CP.

    CP là gì?

    CP là một cách an toàn để sử dụng iPhone trên xe ô tô, CP sẽ thực hiện các tác vụ mà người dùng muốn thực hiện với iPhone trong khi lái xe.

    CP Types

    Ở thời điểm hiện tại Apple cung cấp 9 CP types

    • Audio
    • Communication (Messaging & calling)
    • Driving task
    • EV charging
    • Fueling
    • Navigation
    • Packing
    • Quick food ordering
    • Automaker

    Đến đây chắc hẳn các bạn cũng thắc mắc tại sao type Automaker mình lại highlight lên như vậy. Thì đây là một type rất đặc biệt. Và ở phần 1 này mình chỉ chia sẻ về 8 types bên trên, riêng type Automaker mình sẽ chia sẻ ở phần tiếp theo.

    Mỗi CP type sẽ có một entitlement key, key này chính là để enable/disable tính năng CP trong các ứng dụng

    EntitlementKeyMinimum version
    CarPlay Audio App (CarPlay framework)
    App supports the CarPlay framework. Include both CarPlay audio app entitlements if your app supports the CarPlay framework and the Media Player framework.
    com.apple.developer.carplay-audio
    iOS 14
    CarPlay Audio App (Media Player framework)
    Deprecated. App supports the Media Player framework. Include both CarPlay audio app entitlements if your app supports the CarPlay framework and the Media Player framework.
    com.apple.developer.playable-content
    CarPlay Communication App
    App supports the CarPlay framework, and SiriKit intents for messaging or VoIP calling apps. May be combined with the optional CarPlay Messaging App and CarPlay VoIP Calling App entitlements to support iOS 13 and earlier.
    com.apple.developer.carplay-communicationiOS 14
    CarPlay Messaging App
    Deprecated. App relies solely on SiriKit and supports SiriKit intents to send, request, and modify messages. May be combined with the CarPlay Communication App entitlement, and the optional CarPlay VoIP Calling App entitlement to support iOS 13 and earlier.
    com.apple.developer.carplay-messaging
    CarPlay VoIP Calling App
    Deprecated. App relies solely on SiriKit and CallKit, and supports SiriKit intents for starting calls and requesting a list of calls. May be combined with the CarPlay Communication App entitlement, and the optional CarPlay Messaging App entitlement to support iOS 13 and earlier.
    com.apple.developer.carplay-calling
    CarPlay Driving Task App
    App supports the CarPlay framework.
    com.apple.developer.carplay-driving-taskiOS 16
    CarPlay EV Charging App
    App supports the CarPlay framework. May be combined with the CarPlay Fueling App entitlement.
    com.apple.developer.carplay-chargingiOS 14
    CarPlay Fueling App
    App supports the CarPlay framework. May be combined with the CarPlay EV Charging App entitlement.
    com.apple.developer.carplay-fuelingiOS 16
    CarPlay Navigation App
    App supports the CarPlay framework.
    com.apple.developer.carplay-mapsiOS 12
    CarPlay Parking App
    App supports the CarPlay framework.
    com.apple.developer.carplay-parkingiOS 14
    CarPlay Quick Food Ordering App
    App supports the CarPlay framework.
    com.apple.developer.carplay-quick-orderingiOS 14
    đây là các key của 8 types được cung cấp bưởi Apple

    Note: Khi xây dựng một ứng dụng có hỗ trợ CP, thì chúng ta chỉ được chọn một trong 8 type này. Và config với key tương ứng trong file entitlement, như vậy là compiler đã hiểu là ứng dụng này có hỗ trợ CP.

    CP Templates

    Apple cung cấp 12 templates để hiển thị trên CP. Chúng ta không thể thay đổi layout của của các template này mà chỉ có thể input data vào để hiển thị.

    1. Action Sheet
    2. Alert
    3. Grid
    4. List
    5. Tab bar
    6. Information
    7. Point of interest
    8. Now Playing
    9. Contact
    10. Map
    11. Search
    12. Voice control

    Hình ảnh của các templates có đầy đủ ở page 18, 19, 20, 21, 22, 23, 24

    Mối quan hệ giữa CP Types và CP Templates

    Ở trên mình đã giới thiệu đến các bạn types và templates trong CP. Vậy nó có mối quan hệ gì với nhau không?

    Câu trả lời là có, mỗi CP type sẽ hỗ trợ một vài templates.

    Ví dụ: với những ứng dụng CP Audio thì chỉ có thể hiển thị được với các templates như Alert, Grid, List, Tab bar, Now Playing

    Trong trường hợp chọn một template không hỗ trợ để hiển thị thì app sẽ crash.

    Ví dụ: ứng dụng CP Audio không hỗ trợ type Action Sheet, nếu chúng ta sử dụng type Action Sheet để hiển thị thì ứng dụng CP sẽ crash.

    Di chuyển màn hình

    • Như một ứng dụng chạy trên iPhone, thì CP cũng có thể di chuyển màn hình bằng hai phương thức chính là push và present. Nhưng bản chất ở đây là di chuyển giữa các templates
      Ví dụ: Chúng ta xây dựng ứng dụng CP Audio, màn hình root view là List template, khi bấm vào một item trong list thì di chuyển đến template Now Playing thì đơn giản là chúng ta sử dụng phương thức push hoặc present để di chuyển.
    • Không phải template nào cũng có thể push và present được.
      Ví dụ: khi các bạn push đên Grid template thì không vấn đề gì, còn khi các bạn present đến Grid thì CP sẽ crash và báo present không support Grid.
    • limit khi di chuyển màn hình, hầu hết các app sẽ có độ sâu phần cấp là 5, ứng dụng Fueling sẽ có độ sâu là 3, ứng dụng Driving task và Quick food ordering có độ sâu là 2. Tính từ màn hình root.
      Ví dụ: khi xây dựng CP Audio các bạn không thể di chuyển quá 5 màn hình
      Template1 -> Template2 -> Template3 -> Template4 -> Template5 -> Template6
      Di chuyển từ Template1 đến Template5 thì không sao, và app sẽ crash khi di chuyển từ Template5 đến Template6

    Hướng dẫn khi xây dựng ứng dụng CP

    Khi xây dựng một ứng dụng CP thì chúng ta phải tuân thủ theo 8 hướng chung sau đây: (Mình sẽ lấy nguyên các hướng dẫn của Apple cung cấp để cho các bạn tham khảo nhé)

    1. Your CarPlay app must be designed primarily to provide the specified feature to a user (e.g. CarPlay audio apps must be designed primarily to provide audio playback services, CarPlay parking apps must be designed primarily to provide parking services, etc.).
    2. Never instruct users to pick up their iPhone to perform a task. If there is an error condition, such as a required log in, you can let users know about the condition so they can take action when safe. However, user messages must not include wording that asks users to manipulate their iPhone.
    3. All CarPlay user flows must be possible without interacting with iPhone.
    4. All CarPlay user flows must be meaningful to use while driving. Don’t include features in CarPlay that aren’t related to the primary task (e.g. unrelated settings, maintenance features, etc.).
    5. No gaming or social networking.
    6. Never show the content of messages, texts, or emails on the CarPlay screen.
    7. Use templates for their intended purpose, and only populate templates with the specified information types (e.g. a list template must be used to present a list for selection, album artwork in the now playing screen must be used to show an album cover, etc.).
    8. All voice interaction must be handled using SiriKit (with the exception of CarPlay navigation apps, see below).

    Ngoài 8 hướng dẫn chung này ra thì một số CP types có các hướng dẫn đặc biệt nữa. Chúng ta có thể tham khảo ở page 6, 7, 8, 9, 10

    Môi trường phát triển

    Cũng như các ứng dụng trên iPhone khi các bạn muốn chạy trên device thật thì cần certificate và provisioning. Thì ứng dụng CP cũng vậy. Tuy nhiên khi chạy ứng dụng ra simulator thì không cần thiết.
    Ví dụ: Khi xây dựng một ứng dụng hỗ trợ notification thì cần enable notification ở capabilities, thì với ứng dụng CP cũng cần enable entitlement ở trong Additional Capabilities.

    Mục Additional Capabilities của tất cả các Apple Account đều là rỗng, developer phải request đến Apple và đợi họ approve thì mới có thể enable Capabilities để chạy trên device thật.

    Account của mình đã được Apple approve với type Audio, mình nhớ là mất khoảng 14 ngày để Apple approve.

    Đây là Link request nhé!

    CP Simulator

    Apple cung cấp cho chúng ta hai simulators để thực hiện test trong quá trình phát triển ứng dụng CP

    • xCode Simulator: đây là simulator tích hợp sẵn trong xCode. Chúng ta có thể mở simulator này lên bằng cách chọn I/O -> External Display -> CarPlay…
    • CP Simulator: đây là một tool riêng biệt, nó mô phỏng lại môi trường của xe ô tô và phải cài ứng dụng hỗ trợ CP lên iPhone, sau đó kết nối với máy tính và mở CP Simulator lên (sau khi tải tool về thì mở folder Hardware -> CarPlay Simulator), tất cả các apps hỗ trợ CP trên iPhone sẽ hiển thị trên CP simulator.
      Link tải tool đây nhé, lưu ý các bạn chọn đúng tool mà xCode của mình đang sử dụng nhé

    Trên đây là phần giới thiệu của mình về CP, phần tiếp theo mình sẽ chia sẻ việc implement một ứng dụng hỗ trợ CP.

    Mình hi vọng bài viết có thể giúp ích được cho các bạn. Chúc các bạn thành công!

  • If / switch expression – Swift 5.9 (P.1)

    If / switch expression – Swift 5.9 (P.1)

    Chúng ta chắc là đã quá quen thuộc với ternary conditional operator ( toán tử ba ngôi ) như trên rồi nhỉ. Nhưng với swift 5.9, chúng ta đã có thêm một cách viết khác tường minh hơn đó là sử dụng if / switch. Và trong bài viết này chúng ta sẽ tìm hiểu về nó nhé.

    If / switch expression là gì?

    Với Swift 5.9. If và switch đã có thể được sử dụng dưới dạng biểu thức. Nói đơn giản thì toán tử ba ngôi được sử dụng như thế nào thì if và switch bây giờ đều có thể sử dụng như vậy.

    Ví dụ như bình thường chúng ta đang viết như thế này:

    Thì chúng ta hiện nay đã có thể viết như thế này:

    Đối với switch có vẻ như là mới mẻ và xịn xò hơn hẳn rồi nhỉ. Nhưng còn if thì sao. Trông cũng không khác gì đối với toán tử ba ngôi mà lại còn phải viết nhiều hơn. Vậy thì nó có gì khác biệt so với toán tử ba ngôi nhỉ.

    • Đầu tiên: Sử dụng if trông rõ ràng là giúp code được tường minh và dễ theo dõi hơn rồi. Đặc biệt là với những lúc mà có các điều kiện rẽ nhánh lồng nhau thì sự tường minh của if sẽ được thể hiện rõ hơn.
    • Thứ Hai: Toán tử ba ngôi thì kiểm tra kiểu dữ liệu một cách đồng thời còn if sẽ kiểm tra nó một cách độc lập. Nghe có chút trừu tượng nhỉ. Vậy thì chúng ta sẽ tới với ví dụ nhé:

    Ở đây chúng ta có thể thấy. Do toán tử ba ngôi kiểm tra kiểu dữ liệu một cách đồng thời vậy nên 1 ở đây hệ thống sẽ tự hiểu là 1.0. Với If thì không như vậy mà chúng ta cần viết rõ ra hơn.

    Lưu ý:

    Để sử dụng được if và switch như một biểu thức thì chúng ta cần lưu ý một vài yếu tố sau:

    • Với mỗi nhánh của if hay switch chỉ được thực thi duy nhất một biểu thức.
    • Mỗi biểu thức được tạo ra ở các nhánh đều phải cùng một kiểu dữ liệu.
    • If luôn đi kèm với else

    Và bài viết này chúng ta đã được tìm hiểu về If / switch expression ở trên swift 5.9. Vẫn còn rất nhiều thứ mới nữa ở swift 5.9 và chúng ta sẽ tiếp tục tìm hiểu chúng ở các phần tiếp theo nhé. Xin chân trọng cảm ơn!

  • Raw String in Swift

    Raw String in Swift

    Xin chào tất cả các bạn, lại là mình đây

    Hôm nay chúng ta sẽ nâng cấp thêm vũ khí giúp anh em iOS Developer tự tin chiến đấu hơn . Đây là một chủ đề khá nhỏ trong iOS & Swift nói chung, tuy nhiên nó lại có một tầm ảnh hưởng khá là lớn. Nên khi bạn nắm bắt được Raw String, thì có sẽ có thêm một công cụ khá là mạnh trong tay. Let’s goooooo !

    Raw String là gì?

    Raw String lần đầu được giới thiệu ở Swift 5, cho chúng ta khả năng viết chuỗi tự nhiên hơn, đặc biệt khi sử dụng dấu gạch chéo ngược và dấu ngoặc kép. Trong một số trường hợp, chẳng hạn như biểu thức Regex, chúng ta sẽ thấy được sức mạnh của Raw String.

    Swift 5 cung cấp cho chúng ta khả năng khai báo một dấu phân cách chuỗi tùy chỉnh bằng cách sử dụng ký hiệu "#" hay còn được gọi là dấu thăng. Khi bạn sử dụng "#" với một chuỗi, nó sẽ ảnh hưởng đến cách Swift hiểu các ký tự đặc biệt trong chuỗi: “\” không còn hoạt động như một ký tự để thoát chuỗi, vì vậy \n được hiểu là dấu gạch chéo ngược rồi đến chữ “n” thay vì ngắt dòng và \(variable)sẽ được bao gồm dưới dạng các ký tự đó.

    Công dụng của Raw String

    Đầu tiên hãy đi vào một ví dụ nhỏ

    let regularString = "\\Hello \\World"
    let rawString = #"\Hello \World"#

    Như bạn có thể thấy, ở string thứ 2 sử dụng # để đánh dấu đó là một Raw String, output của hai chuỗi này sẽ như nhau nhưng khi dùng Raw String trông có vẻ sáng sủa hơn nhỉ ?.

    Thêm ví dụ nữa cho mọi người thấy công dụng của Raw String:

    let swift4 = "This is \"Swift 4.x\"."
    print(swift4)
    let swift5 = #"This is "Swift 5.x"."#
    print(swift5)

    Trông có vẻ rõ ràng hơn rồi, khai báo & kết thúc một String với dấu #, ta có thể sử dụng các kí tự đặc biệt như là một kí tự bình thường trong chuỗi, giúp chúng ta không phải sử dụng thêm các dấu \ làm code trông khá là lú ?.

    Raw String với Variable

    let name = "Techover"
    let greeting = #"Hello, \#(name)!"#
    print(greeting)

    Với String bình thường, ta sẽ sử dụng cú pháp \(variableName) để đưa giá trị biến vào chuỗi. Còn với Raw String ta sẽ phải thêm dấu # vào nữa như ví dụ bên trên.

    Raw String với Multi-line

    let example = "Hello bro"
    let message = #"""
    This is rendered as text: \(example).
    This uses string interpolation: \#(example).
    """#
    print(message)

    Cũng khá là easy và tiện lợi nhỉ, không như String xuống dòng linh tinh cái là đi ngay ?‍?

    Raw String với dấu #

    Khi muốn sử dụng dấu # trong một Raw String sẽ khác một chút đó

    let str = #"My dog said "woof"#gooddog"#

    Xcode sẽ ngăn cản bạn thực hiện đoạn code trên. Vì nó sẽ xác định dấu # tiếp theo là kết thúc chuỗi Raw String rồi. Do đó, phần còn lại sẽ trở thành lỗi. Chế cháo đi một tí mới hết lỗi nè

    let str = ##"My dog said "woof"#gooddog"##
    print(str)

    Như trên, output của chúng ta sẽ có đầy đủ các dấu " & # luôn. Như vậy, khi ta khai báo bao nhiêu dấu # ở đầu, thì sẽ phải có bấy nhiêu dấu # ở cuối của Raw String. Lúc này, Raw String của ta mới có ý nghĩa.

    let zero = "This is a string"
    let one = #"This is a string"#
    let two = ##"This is a string"##
    let three = ###"This is a string"###
    let four = ####"This is a string"####

    Lan man một hồi giờ tổng kết lại nè

    Raw String hữu ích vì một lý do: Đơn giản hóa String, giúp chúng ta dễ đọc dễ tiếp cận và dễ dàng sửa chữa

    Đặc biệt trong các biểu thức Regex, khi mà chúng ta phải sử dụng rất nhiều kí tự đặc biệt, một ví dụ về một biểu thức Regex khá là nhiều dấu \

    let regex = try NSRegularExpression(pattern: "\\\\\\([^)]+\\)")

    Tuy nhiên với Raw String, chúng ta có thể bớt đi một nửa số dấu \ chúng ta sử dụng. Đơn giản biểu thức của chúng ta sẽ còn lại là:

    let regex = try NSRegularExpression(pattern: #"\\\([^)]+\)"#)

    Lời kết

    Như vậy là sau một hồi bàn luận về Raw String, hi vọng các bạn có thể áp dụng được vào code của mình để code của chúng ta ngày càng xịn sò hơn. Cảm ơn các bạn vì đã đọc bài viết này. Hẹn gặp lại các bạn ở các post tiếp theo ?