Category: macOS

  • XCode 14 có gì mới? (Phần 2)

    XCode 14 có gì mới? (Phần 2)

    Interface Builder

    Các tính năng mới

    • UISplitViewController hiện hỗ trợ sidebars trong các ứng dụng Mac được xây dựng bằng Mac Catalyst. Để bật sidebars, hãy đặt Primary Style trong trình kiểm tra thuộc tính của bộ điều khiển chế độ split view. (82004740)
    • Trình tạo giao diện hiện hỗ trợ các nhóm mục trung tâm mới trên UINavigationItem. (83252931)
    • Đã thêm một checkbox trong Attributes inspector để bật giao diện người dùng tìm và thay thế UI cho UITextView. (83726669)
    • Trình tạo giao diện hiện cập nhật các cảnh không đồng bộ. (83786577)
    • Trình tạo giao diện hiện hỗ trợ tác giả NSComboButton. (85583290)
    • Trình tạo giao diện hiện hỗ trợ tác giả với MKMapView, MKMapConfiguration including standard, imagery và hybrid. (85607049)
    • Chuyển bàn phím từ trình kiểm tra thuộc tính của UIViewController để hiểu cách bàn phím ảnh hưởng đến hướng dẫn bố cục trong canvas. (87975498)
    • Một hộp kiểm mới xuất hiện để bật giao diện người dùng tìm và thay thế tiêu chuẩn. (88049266)
    • Giờ đây, bạn có thể chỉnh sửa cấu hình mặc định của Biểu tượng SF (bao gồm phông chữ, tỷ lệ và trọng lượng) bằng NSButton và NSImageView bằng cách chọn biểu tượng thông qua trình kiểm tra hình ảnh của điều khiển. (88400241)
    • Hỗ trợ cho iOS để cho phép dán nội dung bằng một lần nhấn mà không cần thông báo hoặc cảnh báo dán. Điều khiển có thể nhắm mục tiêu bất kỳ đối tượng nào tuân theo UIPasteConfigurationSupporting (ví dụ: UIResponder) để nhận nội dung đã dán. (88648426)
    • Truy cập và tìm kiếm Ký hiệu SF thông qua tab thư viện ký hiệu. Mở thư viện (Xcode > View > Show Library) và nhấp vào tab Symbols. Bạn có thể kéo các biểu tượng vào source editor. (88726368)
    • Trình tạo giao diện bao gồm NSColorWell có các kiểu mặc định, tối thiểu và mở rộng mới trong macOS 13. (89051231)
    • Trình tạo giao diện hiện hỗ trợ tác giả MKPointOfInterestFilter. (89368386)
    • Trình tạo giao diện hiện hỗ trợ tác giả MKLookAroundViewController. (90994596)
    • Trình tạo giao diện hiện hỗ trợ tác giả RoomCaptureView. (91640003)

    Vấn đề đã giải quyết

    • UIBarButtonItemGroup đã được thêm vào thư viện đối tượng Interface builder. Nó có thể được kéo vào một UINavigationItem để cung cấp các Center Items. (19160962)
    • UIColorWell hiện có sẵn trong thư viện đối tượng. Khi chạm vào, điều khiển sẽ hiển thị bộ chọn màu. (67016855)
    • Giờ đây, bạn có thể bật hướng dẫn bố cục bàn phím trên cảnh UIView thông qua trình kiểm tra kích thước. Hạn chế chế độ xem đối với hướng dẫn bố cục để chúng điều chỉnh trong quá trình bố trí khi bàn phím hiển thị trên màn hình. (81959069) (FB9514618)
    • Tạo khả năng hiển thị phác thảo cho các tài liệu mới phù hợp với trạng thái được chuyển đổi của người dùng cuối cùng. (82857926) (FB9607879)
    • Đã khắc phục sự cố với kết nối ổ cắm và hành động với AppDelegates dựa trên AppleScript. (83373726) (FB9643535)
    • Đã khắc phục sự cố khi lưu tài liệu có nhiều Trình điều khiển Chế độ xem Nhìn xung quanh sẽ làm Xcode bị lỗi. (92304543)
    • Bảng phân cảnh WatchKit không được dùng trong watchOS 7.0 trở lên. Vui lòng chuyển sang SwiftUI và Vòng đời SwiftUI. (94058186)
    • Chế độ xem phác thảo của Interface builder hiện lưu và khôi phục trạng thái hiển thị/độ rộng trên toàn cầu thay vì trên mỗi tài liệu. (97084370)

    Vấn đề đã biết

    • Kích thước phông chữ không thay đổi để phù hợp với kích thước kiểm soát cho NSComboButton. (94610724) (FB10094813)

    Linking

    Vấn đề đã biết

    • Các ứng dụng Swift được xây dựng bằng Xcode 14 có thể không liên kết được với các tệp libswiftFoundation.dylib. Điều này có thể khiến ứng dụng hoạt động sai khi chạy trên các hệ điều hành trước macOS 13 Ventura và iOS 16, bao gồm cả việc in các chuỗi không chính xác và đưa ra các ngoại lệ đối với các phương thức bị thiếu trên các loại dữ liệu của Tổ chức. (99457165)
      Giải pháp thay thế : Tham chiếu rõ ràng một ký hiệu từ trong mã libswiftFoundation, ví dụ bằng cách thêm vào một hàm _ = JSONDecoder()

    Localization

    Các tính năng mới

    • Bây giờ bạn có thể xuất Swift Packages cục bộ để bản địa hóa. Xcode tạo một danh mục bản địa hóa duy nhất cho tất cả các dự án và Swift Packages có trong một project hoặc workspace. Bạn cũng có thể sử dụng xcodebuild -importLocalizations và xcodebuild -exportLocalizations để export hoặc import gói Swift. (56355281)

    Vấn đề đã giải quyết

    • Các chuỗi được bản địa hóa chỉ định rõ ràng một bảng tham số không phải là chuỗi ký tự không còn được trích xuất khi chạy genstrings hoặc xuất để bản địa hóa. Trước đây, genstrings mặc định là một bảng có tên Localizable.strings. (65063595)
    • Đã khắc phục sự cố trong đó Xcode đôi khi không phát sinh lỗi khi xuất .strings tệp không đúng định dạng để bản địa hóa. (85278818)
    • Đã khắc phục sự cố trong đó Xcode âm thầm bỏ qua XLIFF không đúng định dạng khi nhập bản địa hóa. (86849358) (FB9819403)
    • xcodebuild -importLocalizations và xcodebuild -exportLocalizations hiện bao gồm dấu thời gian cho các hoạt động bản địa hóa. (89373526)
    • Xcode tự động trích xuất NSHumanReadableDescription từ ​​các tệp Info.plist khi xuất để bản địa hóa. (89591666) (FB9935770)
    • Các khóa trong .strings tệp tồn tại trong một .stringsdict với NSStringDeviceSpecificRuleType không còn được đánh dấu là translate=”no” trong XLIFF đã xuất, bởi vì những khóa này cũng rơi trở lại giá trị tệp .strings khi chạy. (90785024)
    • Đã khắc phục sự cố trong đó Xcode đưa ra cảnh báo đối với các đơn vị chưa được dịch được đánh dấu là translate="no"khi nhập bản địa hóa. (91692843) (FB9982115)

    Metal

    Các tính năng mới

    • TextureConverter 2.0 thêm hỗ trợ giải nén kết cấu, số liệu lỗi kết cấu nâng cao và hỗ trợ đọc và ghi tệp KTX2.Thư viện AppleTextureConverter mới giúp TextureConverter có sẵn để tích hợp vào các công cụ và công cụ của bên thứ ba. (82244472)

    Vấn đề đã biết

    • Hồ sơ Chụp kim loại có chứa pipeline bị vô hiệu hóa. (93255574)

    Organizer

    Các tính năng mới

    • Phản hồi ảnh chụp màn hình TestFlight hiện có sẵn trong Xcode Organizer. Giờ đây, bạn có thể xem ảnh chụp màn hình và phản hồi bằng văn bản cho iOS và macOS trong Xcode bằng cách chọn mục “Phản hồi” trong phần báo cáo của thanh bên. Để bắt đầu, hãy đăng nhập bằng tài khoản Nhà phát triển Apple được liên kết với ứng dụng TestFlight của bạn và mở Trình tổ chức bằng cách chọn Cửa sổ > Trình tổ chức trong thanh menu. Ngoài việc xem phản hồi, bạn có thể liên hệ trực tiếp với người thử nghiệm và chia sẻ phản hồi với các thành viên trong nhóm phát triển của mình. (56519107)
    • TestFlight Screenshot Feedback hiện có thể được mở trong Xcode Organizer thông qua nút “Open in Xcode 14” trong App Store Connect. (83599827)

    Previews

    Các tính năng mới

    • Bản xem trước Xcode hiện tự động tiếp tục khi tạo dự án mới. (50474683)
    • Xem trước Xcode không còn tạm dừng sau khi chỉnh sửa tệp và chuyển về chế độ xem trước và tiếp tục hoặc khi các dự án sửa đổi thư mục nguồn trong quá trình xây dựng. (71593736)
    • Lỗi từ các bản xem trước tiện ích và phức tạp hiện được hiển thị trong khung vẽ. (76966327)
    • Bản xem trước Xcode hiện sử dụng dữ liệu từ các tệp Cấu hình StoreKit nếu một tệp được đặt trong các tùy chọn chạy của lược đồ. Bản xem trước chỉ hỗ trợ một tập hợp con API StoreKit. (82312384)
    • Chẩn đoán xem trước hiện có thể truy cập được bằng mục trình đơn Trình chỉnh sửa > Canvas > Chẩn đoán của Xcode. (92620156)

    Vấn đề đã giải quyết

    • Bản xem trước Xcode hiện hiển thị chính xác các chuỗi ký tự có chứa chuỗi thoát unicode Swift. (32722474)
    • Bản xem trước Xcode hiện có thể chạy trên các thiết bị vật lý mà không yêu cầu ứng dụng chứa, giúp dễ dàng xem trước trên thiết bị cho các khung và gói Swift. Xcode tự động chuẩn bị một ứng dụng đã ký phù hợp cho danh tính ký mặc định của bạn để lưu trữ bản xem trước. (50206641)
    • Khung Xcode Previews hiện hỗ trợ và mặc định là zoom-to-fit. (51146527)
    • Đã khắc phục một số sự cố khi sử dụng bản xem trước watchOS trong Xcode. Các bản xem trước hiện hoạt động chính xác khi điều hướng giữa các tệp trong ứng dụng iOS chứa hoặc ứng dụng watchOS được nhúng hoặc các khung và gói được bao gồm bởi một hoặc nhiều mục tiêu đó. (53183015)
    • Đã sửa một số trường hợp khi thực hiện chỉnh sửa theo một thứ tự cụ thể sẽ khiến các bản xem trước không thành công với lỗi thiếu biểu tượng (53740398)
    • Bản xem trước Xcode hiện có thể sử dụng chương trình có thể chạy được khi quyết định sử dụng ứng dụng nào để lưu trữ bản xem trước. Ví dụ: trong dự án có khung mà cả phiên bản đầy đủ và phiên bản beta của ứng dụng đều dùng chung, Xcode Previews tự động chọn ứng dụng để khởi chạy để xem trước dựa trên lựa chọn trong lược đồ. (60251198)
    • Đã khắc phục sự cố khi sử dụng nhiều bản xem trước sẽ gây ra lỗi hết thời gian chờ trong Bản xem trước Xcode. (68939151)
    • Đã khắc phục sự cố khiến Bản xem trước Xcode không thành công đối với các tệp có hai dấu ngoặc nhọn đóng trên cùng một dòng. (74035344) (FB8992136)
    • Xem trước Xcode không còn tạm dừng trên các chỉnh sửa lớn. Thay vào đó, Bản xem trước tiếp tục tự động xây dựng bằng cách phát hiện các loại thay đổi được thực hiện và tự động điều chỉnh tần suất cập nhật để cân bằng thời lượng pin và độ trễ. (77799105)
    • Đã khắc phục sự cố trong Bản xem trước Xcode gây ra tình trạng tạm dừng thường xuyên khi sử dụng các dự án Swift Playgrounds được mở trong Xcode. (79206975)
    • Đã khắc phục sự cố trong một số dự án mà lỗi tải gói không bao giờ biến mất trong Bản xem trước Xcode. (79207076)
    • Đã khắc phục sự cố trong đó Bản xem trước Xcode có thể không hiển thị chính xác sau khi đóng và mở canvas. (83789694)
    • Đã sửa các trường hợp Bản xem trước Xcode không phản ánh các thay đổi được thực hiện đối với các tệp trong Gói Swift. (84529522)
    • Đã khắc phục sự cố trong đó canvas Xcode Previews không hiển thị chính xác khi sử dụng @_implementationOnly nhập. (86214393)
    • Xcode hiện hiển thị từng bản xem trước trên trang chuyên dụng của riêng nó bao gồm các điều khiển mới cho phép bạn thay đổi các cài đặt chung như bảng màu, hướng hoặc kích thước loại động mà không cần viết bất kỳ mã nào. (87357785)
    • Bản xem trước Xcode hiện có tính tương tác theo mặc định. Bạn có thể sử dụng trình chuyển đổi chế độ ở cuối canvas để chuyển đổi giữa các chế độ tương tác, lựa chọn và biến thể. (87358985)
    • Bản xem trước Xcode hiện hỗ trợ các biến thể xem trước: bản xem trước được tạo tự động cho phép bạn xem chế độ xem của mình ở nhiều dạng, kích thước loại hoặc hướng cùng một lúc mà không cần viết bất kỳ mã cấu hình nào. (88937848)
    • Bản xem trước hiện hoạt động trong các mô-đun bằng cách sử dụng @_spi. (89653122)
    • Sự cố trong bản xem trước hiện được phản ánh chính xác cho các dự án Swift Playgrounds được mở trong Xcode. (91716026)
    • Việc thay đổi đích chạy đang hoạt động hiện cập nhật chính xác canvas Xcode Previews. (92152617)
    • Cải thiện thời lượng pin khi sử dụng Xcode Previews. (92179785)
    • Các thay đổi đối với giá trị bằng chữ trong trình khởi tạo hiện được phản ánh chính xác trong Bản xem trước Xcode. (92599456)
    • Mục menu “Tự động làm mới canvas” trong canvas Xcode Previews đã được thay đổi để tạm dừng hành vi tạo tự động mới. Điều này cho phép làm mới bản xem trước theo cách thủ công ở nhịp mong muốn. (93261715)
    • Đã khắc phục một số sự cố với Bản xem trước Xcode không phản ánh các thay đổi mã dự kiến ​​khi điều hướng đến các tệp không phải SwiftUI hoặc khi đóng canvas và mở lại. (93785410)
    • Bản xem trước Xcode hiện hỗ trợ các biến chứng watchOS bên trong các ứng dụng watchOS độc lập. (95311509)
    • Bản xem trước Xcode hiện hoạt động với các gói chứa tài nguyên không có trong ứng dụng. (96828503)

    Deprecations

    • Hỗ trợ xem trước các tiện ích được tạo cho ứng dụng macOS và ứng dụng được tạo bằng Mac Catalyst đã bị xóa. (92531529)
      Giải pháp thay thế : Sử dụng Trình mô phỏng WidgetKit macOS.

    Project Navigator

    Vấn đề đã giải quyết

    • Đã sửa lỗi: Khi bạn sử dụng Trình kiểm tra tệp để thay đổi loại tệp, tệp có thể được mở lại trong trình chỉnh sửa khác. (91784648)
    • Đã sửa lỗi: Trình điều hướng sự cố không liệt kê các sự cố được tạo khi xây dựng mã Swift trong giai đoạn mô-đun phát ra. (92430695)

    Vấn đề đã biết

    • Option+Clicking vào nút đóng cho tab trình chỉnh sửa không được chọn sẽ đóng tất cả các tab khác (như mong đợi) và cũng điều hướng đến tab được nhấp bằng điều hướng tùy chọn. Điều hướng này là không chủ ý. (96958005)
    • Việc mở gói kết quả có nhật ký bản dựng lớn có thể mất 30 giây trở lên. (97328772)
    • Option+Clicking vào tab trình chỉnh sửa không thực hiện “điều hướng tùy chọn” như được định cấu hình trong tùy chọn của Xcode. (97690500)

    Refactoring

    Các tính năng mới

    • Đã thêm một hành động tái cấu trúc để thêm một Codable triển khai rõ ràng. (87904700)

    Vấn đề đã biết

    • Chuyển đổi sang Trình tạo Regex không xử lý chính xác các mẫu có chuỗi thoát Unicode. Ví dụ: một ký tự regex có chứa \u{0} sẽ được chuyển đổi thành "" kết quả. (95465206) (FB10343998)

    Server

    Vấn đề đã biết

    • Xcode Server không còn được hỗ trợ. (73888675)

    Signing and Distribution

    Các tính năng mới

    • Ký tự động hiện được hỗ trợ cho trình điều khiển DriverKit đã ký phát triển. Việc phân phối vẫn yêu cầu sự chấp thuận của Apple và cấu hình thủ công các khả năng bổ sung trên trang web Nhà phát triển của Apple . (81215709)
    • Quyền Game Center hiện có sẵn cho các ứng dụng trên iOS, watchOS và tvOS. Nếu ứng dụng của bạn sử dụng Game Center, ứng dụng sẽ tự động nhận được quyền này khi bạn tạo lại hồ sơ cấp phép của mình. Nếu bạn sử dụng ký tự động, Xcode sẽ tự động tạo hồ sơ cung cấp mới cho bạn. Nếu sử dụng ký thủ công, bạn cần đăng nhập vào tài khoản của mình và tạo lại hồ sơ cấp phép của mình
      Nếu bạn dự định tiếp tục sử dụng Game Center trong ứng dụng của mình, hãy thêm quyền com.apple.developer.game-center vào tệp quyền của bạn trong Xcode. Nếu không, hãy xóa capability trong Xcode và tắt Trung tâm trò chơi trên ID ứng dụng của bạn trong tài khoản nhà phát triển của bạn. (90667072)

    Vấn đề đã biết

    • xcodebuild -exportArchivetrả về thông báo lỗi hết hạn phiên nếu bạn sử dụng khóa xác thực để tải ứng dụng của mình lên App Store Connect. (76036452)Giải pháp thay thế : Khóa xác thực chỉ được hỗ trợ để ký và cung cấp. Để tải ứng dụng lên từ xcodebuild, trước tiên hãy đăng nhập vào Xcode bằng ID Apple của bạn.
    • xcodebuildthỉnh thoảng có thể gặp sự cố trong DVTPortalEntitlementsManager. (98678163) (FB11267326)Cách giải quyết: Bạn có thể vô hiệu hóa logic lọc quyền lợi của Xcode để giải quyết vấn đề này, bằng cách chạy trong Terminal hoặc bằng cách thêm vào lời gọi dòng lệnh của bạn.defaults write com.apple.dt.Xcode DVTEnableMultiPlatformEntitlementFiltering -bool NO-DVTEnableMultiPlatformEntitlementFiltering=NOxcodebuild

    Vấn đề đã giải quyết

    • Đã sửa lỗi: Khi chỉnh sửa khả năng của iCloud, Nhóm ứng dụng, Apple Pay hoặc Wallet, Xcode có thể đề nghị chọn một nhóm nếu bạn không chọn một nhóm. Việc chọn một nhóm khiến Xcode gặp sự cố. (93914533)

    Simulator

    Các tính năng mới

    • Simulator hiện hỗ trợ remote notifications trong iOS 16 khi chạy trong macOS 13 trên máy tính Mac có bộ xử lý Apple silicon hoặc T2. Simulator hỗ trợ môi trường Sandbox push notification services của Apple. Máy chủ của bạn có thể gửi thông báo từ xa tới ứng dụng của bạn đang chạy trong simulator đó bằng cách kết nối với sandbox APNS (api.sandbox.push.apple.com). Mỗi Simulator tạo mã thông báo đăng ký duy nhất cho sự kết hợp giữa trình mô phỏng đó và phần cứng máy Mac mà nó đang chạy trên đó. Xem Thông báo người dùng để biết thêm thông tin.Thông báo từ xa hỗ trợ nhiều tính năng hơn (như Tiện ích mở rộng dịch vụ thông báo) so với thông báo được mô phỏng cục bộ bằng cách sử dụng tệp .apns trọng tải hoặc lệnh đẩy simctl. Mã thông báo đăng ký thiết bị có độ dài thay đổi. Mã thông báo trong Trình mô phỏng có thể lớn hơn mã thông báo trên thiết bị vật lý hiện tại. Không mã hóa cứng bất kỳ độ dài hoặc định dạng cụ thể nào cho các mã thông báo này. (60974170)
    • simctl hiện hỗ trợ kiểm soát vị trí mô phỏng, bao gồm các kịch bản đang chạy và nội suy giữa danh sách các điểm tham chiếu. Xem xcrun simctl location để biết thêm thông tin. (59422559) (FB7577924)
    • Simulator hiện hỗ trợ hình ảnh đĩa thời gian chạy ngoài định dạng gói thời gian chạy hiện có. Ảnh đĩa được thêm vào vị trí lưu trữ do hệ thống quản lý được Bảo vệ tính toàn vẹn của hệ thống bảo vệ và được gắn tại các điểm gắn do hệ thống quản lý. Xem xcrun simctl thời gian chạy để biết thêm thông tin. (84169585)
    • simctl addmedia đã được cập nhật để hỗ trợ nhiều định dạng hình ảnh bổ sung (bao gồm nhiều định dạng RAW phổ biến). (87103990) (FB9832655)
    • Giờ đây, bạn có thể khởi động các thiết bị giả lập bằng cách sử dụng thời gian chạy chung là x86_64 trên máy Mac với Apple silicon bằng cách sử dụng --arch đối số dòng lệnh mới cho simctl boot. (88278366) (FB9860747)

    Vấn đề đã biết

    • Nếu bạn ngắt kết nối hoặc tách hình ảnh đĩa thời gian chạy trình mô phỏng theo cách thủ công (chẳng hạn như bằng cách sử dụng diskutil eject hoặc umount), Trình mô phỏng và Xcode có thể không xác định được liệu thời gian chạy đã được cài đặt hay chưa. Nỗ lực tải xuống lại thời gian chạy dẫn đến lỗi với lỗi thời gian chạy trùng lặp. (89589210)
      Giải pháp thay thế : Việc khởi động lại khiến Trình mô phỏng gắn lại ảnh đĩa thời gian chạy. Ngoài ra, bạn có thể sử dụng xcrun simctl runtime để định vị ảnh đĩa thời gian chạy bị ảnh hưởng, xóa nó, sau đó sử dụng Xcode để tải xuống lại.
    • Hình ảnh đĩa thời gian chạy trình mô phỏng trong /tmp đó bạn thêm bằng cách sử dụng xcrun simctl runtime add sẽ bị xóa. (93858264)
      Giải pháp thay thế: Đặt hình ảnh đĩa thời gian chạy giả lập ở một nơi khác /tmp/trước khi chuyển nó vào xcrun simctl runtime add.

    Siri Intents

    Vấn đề đã biết

    • Mã Swift đã tạo mà trình biên dịch định nghĩa Ý định tạo ra sẽ phát ra cảnh báo khi được biên dịch:
    method 'handle(intent:)' with Objective-C selector 'handleIntent:completion:' conflicts with method 'handle(intent:completion:)' with the same Objective-C selector; this is an error in Swift 6

    (91852710)

    Source Control

    Vấn đề đã giải quyết

    • Nhiều lỗi ảnh hưởng đến độ chính xác và độ trễ của trạng thái tệp git trong bộ điều hướng Dự án và Thay đổi đã được giải quyết. Các thay đổi đối với tệp trong bản sao làm việc được phản ánh chính xác trong bộ điều hướng và trang cam kết mà không có độ trễ đáng kể. Ngoài ra, các tệp hiển thị các thanh thay đổi khi được trình bày trong trình chỉnh sửa sẽ nhận được trạng thái đã sửa đổi ngay sau khi thay đổi được thực hiện trong bộ nhớ, điều này sẽ khiến nó có trạng thái đã sửa đổi khi được lưu vào đĩa. (49909533)
    • Xcode hiện hỗ trợ tạo và sử dụng các khóa ED25519 và ECDSA được tạo bên ngoài để thực hiện gitcác thao tác SSH. (85009643)

    Vấn đề đã biết

    • Định cấu hình ứng dụng mới trong Xcode Cloud sẽ không thành công khi nhóm nhà phát triển không có ứng dụng hiện có trong App Store Connect. (94199091)Giải pháp thay thế : Tạo ứng dụng trong App Store Connect trước, sau đó tích hợp sản phẩm trong Xcode.

    Source Editor

    Các tính năng mới

    • Xcode hiện ghim các thành phần cấu trúc mã của bạn lên đầu trình chỉnh sửa khi bạn cuộn qua tài liệu. Để chuyển đổi hành vi này, hãy sử dụng “Hiển thị: Cấu trúc mã trong khi cuộn” trong tùy chọn Chỉnh sửa văn bản của Xcode. (10582250)
    • Các lỗi trong tệp Swift hiện cung cấp bản sửa lỗi để thêm các lần nhập bị thiếu. (21533417) (FB5562997)
    • Gói mã bằng câu lệnh if giờ đây sẽ tự động xác định lại khối. (29215201)
    • Trình khởi tạo hiện được trình bày dưới dạng hoàn thành mã toàn cục trong Swift. (60399329)
    • Giao diện người dùng để chuyển đến các định nghĩa ký hiệu hoặc trình gọi hiện cung cấp cho bạn một mẫu mã từ mỗi vị trí. (69467155)
    • Việc hoàn thành mã hiện thu gọn các chức năng quá tải thành một hàng. (81338102)
    • Đã thêm hỗ trợ chỉnh sửa và đánh dấu cú pháp cho Biểu thức chính quy Swift. Giờ đây, bạn có thể chuyển đổi các ký tự biểu thức chính quy sang trình tạo biểu thức chính quy tương đương bằng cách sử dụng Trình chỉnh sửa > Tái cấu trúc > Chuyển đổi sang Trình tạo Regex. Khi di chuyển điểm chèn bên trong một biểu thức chính quy, cấu trúc con kèm theo của biểu thức chính quy được tô sáng. (82540073)
    • Xcode hiện cung cấp mẫu tệp để chọn tham gia các lựa chọn thay thế cảm ứng cho ứng dụng iOS của bạn. Bạn có thể sử dụng các lựa chọn thay thế cảm ứng để tương tác với ứng dụng của mình trên máy Mac có silicon của Apple – ví dụ: nhấn và giữ phím Tùy chọn để sử dụng bàn di chuột làm màn hình cảm ứng ảo. Để bật, hãy chọn Tệp > Tệp mới > iOS > Tài nguyên > Các lựa chọn thay thế cảm ứng và định cấu hình tệp mới được thêm com.apple.uikit.inputalternatives.plist để chọn các lựa chọn thay thế cảm ứng cho ứng dụng của bạn. (84271952)
    • Hoàn thành mã trong Swift hiện cung cấp đoạn mã khởi tạo theo thành viên. (84348512)
    • Hoàn thành mã trong Swift hiện cung cấp các đoạn trích cho các if case câu lệnh. (84381718)
    • Giờ đây, bạn có thể chọn bất kỳ tổ hợp tham số mặc định nào khi hoàn thành mã bằng cách nhập để khớp với tên tham số. (84906871)
    • Cải thiện độ chính xác của việc hoàn thành mã trong Swift. (85090778)
    • Khi chỉnh sửa mã, mục menu Chỉnh sửa > Nhân bản và phím tắt tương ứng của nó giờ đây sẽ sao chép văn bản đã chọn — hoặc dòng hiện chứa điểm chèn, nếu không có văn bản nào được chọn. (8614499) (FB5618491)
    • Hoàn thành mã trong Swift hiện cung cấp các đoạn mã để thêm Codable triển khai rõ ràng. (87904617)
    • Xcode hiện bản địa hóa các phím tắt cho tất cả các bàn phím phần cứng quốc tế để có khả năng truy cập tốt hơn. Bạn có thể tùy chỉnh thêm điều này trong cài đặt Key Bindings. (88397421)
    • Hoàn thành mã trong Swift hiện cung cấp các đoạn mã cho mapfilter và contains, dựa trên tên biến. (89717471)
    • Cấu trúc mã được ghim vào đầu trình chỉnh sửa với tùy chọn “Hiển thị: Cấu trúc mã trong khi cuộn” mới của Xcode 14 hiện bao gồm thông tin bổ sung cho các khai báo được ngắt dòng. (93591165)

    Vấn đề đã giải quyết

    • Đã sửa lỗi: Hoàn thành mã tại các trang web gọi hàm trong Swift hiện chèn các đối số bị thiếu. (9293666)
    • Một số cải tiến hiệu suất đã được thực hiện để xem và chỉnh sửa các tệp lớn. Các sự cố thường xuất hiện nhất trong tệp nguồn được tạo tự động và tệp thử nghiệm với số lượng lớn thử nghiệm và có thể tồi tệ hơn khi hiển thị dải băng gấp mã. (57789416)
    • Hiệu suất khi sử dụng Minimap trong các tệp HTML với các dòng rất dài đã được cải thiện. (58893150)
    • Đã khắc phục sự cố khiến hiệu suất bị giảm khi nhập tệp có nhiều lỗi hoặc cảnh báo. (59084580)
    • Trình kiểm tra Trợ giúp nhanh hiện hiển thị các mô tả về cài đặt bản dựng trong trình chỉnh sửa cài đặt bản dựng dưới dạng văn bản có định dạng với các liên kết có thể nhấp. (60067884)
    • Hoàn thành mã không còn tự động nhập các mô-đun. (78136559)
    • Xcode hiện ưu tiên các loại có thể được sử dụng làm thuộc tính khi gọi hoàn thành mã sau @. (78239501)
    • Đã khắc phục sự cố khiến khoảng trắng xuất hiện sau một số vùng mã được gấp lại. (78333320) (FB9114110)
    • Đã khắc phục sự cố trong đó Trình chỉnh sửa nguồn bị chèn nhầm *khi tạo một dòng mới sau nhận xét tài liệu kiểu khối. (79415983)
    • Đã thêm giao diện người dùng mới để chuyển đến các định nghĩa biểu tượng hoặc trình gọi tập trung vào thông tin phân biệt về từng vị trí. (81366453)
    • Cải thiện tốc độ và tính chính xác của việc hoàn thành mã trong các biểu thức phức tạp và SwiftUI. (83435550)
    • Xcode ưu tiên các loại Chế độ xem SwiftUI khi bạn nhập bên trong trình tạo chế độ xem SwiftUI. (83846531)
    • Đã khắc phục sự cố khi di chuột qua văn bản trong trình chỉnh sửa Đánh giá mã có thể làm Xcode bị lỗi. (85239396)
    • Đã khắc phục sự cố trong đó các cảnh báo cũ hoặc lỗi gạch chân không chính xác các phần của dòng mà chúng được đính kèm. (86225773)
    • Đoạn mã hoàn thành mã động liên quan đến vòng lặp for không còn đề xuất đặt tên các phần tử được lặp lại giống hệt với vùng chứa của chúng. (87167378)
    • Gấp một tệp Swift bằng cách sử dụng mục menu Phương pháp và chức năng gấp hoặc phím tắt được liên kết của nó giờ đây cũng gấp các thuộc tính và chỉ số được tính toán. (87692952) (FB9849362)
    • Hoàn thành mã trong SwiftUI hiện cung cấp đoạn mã cho List và ForEach. (87904499)
    • Đã khắc phục sự cố có thể dẫn đến giảm hiệu suất theo thời gian khi chỉnh sửa các tệp dài có bật Bản đồ thu nhỏ. (89916018)
    • Đã khắc phục sự cố khi sử dụng tính năng “Hiển thị: Cấu trúc mã trong khi cuộn” mới của Xcode 14 với con trỏ khối có thể dẫn đến tạo tác trực quan. (89973125)
    • Các khai báo Swift actor hiện xuất hiện trong Bản đồ nhỏ cùng với các khai báo lớp và cấu trúc. (90279950)
    • Đã khắc phục sự cố khi hoàn thành mã trong Swift hiển thị các ký hiệu không thể truy cập được. (90404828)
    • Đã khắc phục các sự cố khác nhau trong đó các biểu tượng hệ thống không được đánh dấu cú pháp trong các tệp Swift. (91654823)
    • Hoàn thành mã trong Swift hiện ưu tiên tốt hơn các API hệ thống phổ biến. (91977150)
    • Đã khắc phục sự cố có thể dẫn đến sự cố khi chuyển đến định nghĩa ký hiệu trong theo dõi GPU. (93434935)
    • Tô màu cú pháp của chữ regex đã được cập nhật để hỗ trợ đề xuất tiến hóa nhanh mới nhất SE-0354 Chữ regex . Đặc biệt, giờ đây nó xử lý chính xác những gì trông giống như các ký tự không được đóng dấu, theo sau là một nhận xét, các ký tự được sử dụng trong try và các await biểu thức, đồng thời phân định tốt hơn với các toán tử tiền tố có chứa phần mở rộng /. (93673226, 92355356, 94661164) (95146866)

    Vấn đề đã biết

    • Chuyển đổi sang Trình tạo Regex không xử lý chính xác các mẫu bằng tính năng tra cứu. Ví dụ: /foo(?=bar)/nên tạo ra Lookahead("bar")kết quả, nhưng chỉ tạo ra "bar". (97208700)

    StoreKit

    Vấn đề đã giải quyết

    • Xcode hiện có khả năng đồng bộ hóa các sản phẩm mua trong ứng dụng từ App Store Connect vào các tệp cấu hình StoreKit để thử nghiệm StoreKit nhanh hơn trong thiết lập Xcode. Ngoài ra còn có một trình quản lý giao dịch được cập nhật với tính năng lọc và trình kiểm tra giao dịch. (83863948)
    • Đã khắc phục sự cố khi gọi phương thức ‘clearTransactions()’ trong SKTestSession mà không xóa tất cả các giao dịch SKPaymentQueue khi thử nghiệm ứng dụng bằng API gốc để mua hàng trong ứng dụng. (86696132) (FB9814502)
    • Đã sửa lỗi: Trình quản lý giao dịch không còn hiển thị cảnh báo chưa hoàn thành đối với các giao dịch không thể hoàn thành khi sử dụng thử nghiệm StoreKit trong Xcode. (89419046) (FB9927448)

    Vấn đề đã biết

    • Việc sử dụng các thuộc tính và phương pháp StoreKit sau đây trên các ứng dụng có mục tiêu triển khai tối thiểu bên dưới iOS 16, macOS 13, watchOS 9 và tvOS 16 sẽ khiến ứng dụng gặp sự cố khi khởi chạy khi chạy trên các hệ thống cũ hơn iOS 16, macOS 13, watchOS 9 và tvOS 16:
      • priceFormatStylevà trên các giá trịsubscriptionPeriodFormatStyleProduct
      • environmentStringRepresentationvà trên các giá trịrecentSubscriptionStartDateProduct.SubscriptionInfo.RenewalInfo
      • environmentStringRepresentationvề Transactiongiá trị
      • dateRange(referenceDate:)và trên các giá trị (99962885) (FB11516463)formatted(_:referenceDate:)Product.SubscriptionPeriod
      Giải pháp thay thế : Đối với mỗi mục tiêu sử dụng API StoreKit được liệt kê ở trên, hãy điều hướng đến tab “Giai đoạn xây dựng” trong trình chỉnh sửa dự án với mục tiêu được chọn và thêm StoreKit.framework trong “Liên kết nhị phân với thư viện” nếu nó chưa có. Đặt cột “Trạng thái” thành “Tùy chọn”.

    Refer

    https://developer.apple.com/documentation/xcode-release-notes/xcode-14-release-notes

  • XCode 14 có gì mới? (Phần 1)

    XCode 14 có gì mới? (Phần 1)

    Tổng quan

    Xcode 14 bao gồm Swift 5.7 và SDK cho iOS 16, iPadOS 16, tvOS 16, watchOS 9 và macOS Monterey 12.3. Bản phát hành Xcode 14 hỗ trợ gỡ lỗi trên thiết bị trong iOS 11 trở lên, tvOS 11 trở lên và watchOS 4 trở lên. Xcode 14 yêu cầu máy Mac chạy macOS Monterey 12.5 trở lên.

    Thay đổi chung

    Các tính năng mới

    • Xcode 14 cho phép một target duy nhất hỗ trợ nhiều nền tảng và bao gồm có điều kiện các dependencies, code, resource và build settings cho các nền tảng cụ thể. (74664328)
    • Xcode 14 hỗ trợ phát triển trình điều khiển DriverKit cho iPadOS. (81117498)
    • Xcode 14 bao gồm một mẫu mặc định cho các ứng dụng watchOS kết hợp các mục tiêu Ứng dụng WatchKit và Tiện ích mở rộng ứng dụng WatchKit thành một mục tiêu Ứng dụng Watch duy nhất, đơn giản hóa mã, nội dung và quản lý bản địa hóa. Bạn có thể triển khai các ứng dụng watchOS một mục tiêu cho watchOS 7 trở lên. (83222217)

    Vấn đề đã giải quyết

    • Đã sửa lỗi: Khi storyboard đang mở và nội dung watchOS hoặc tvOS bị xóa khỏi Cài đặt Xcode, storyboard sẽ không đóng. (87471381)

    Vấn đề đã biết

    • Nếu một file Package.swift được thêm vào thư mục chứa trong khi thư mục đó đang mở trong Xcode, Package sẽ không được nhận dạng. (85075018)
      Cách giải quyết : Thoát và chạy lại Xcode.
    • CGFLOAT_EPSILON không còn luôn là Float trên watchOS và nó có thể gây ra sự cố biên dịch. (88698530)
      Cách giải quyết: Chuyển đổi nó trước sang CGFloat bằng cách sử dụng trình khởi tạo CGFloat(CGFLOAT_EPSILON). Hiện được hỗ trợ trên cả nền tảng 32 và 64 bit
    • Xcode 14 có thể không tìm thấy các công cụ bằng cách sử dụng xcodebuild -find(được sử dụng bởi xcrun và các trình bao bọc /usr/bin chẳng hạn như /usr/bin/clang) nếu nội dung khởi chạy lần đầu chưa được cài đặt. (98008921)
      Cách giải quyết : Chạy hoặc khởi chạy Xcode.app trước .xcodebuild -runFirstLaunch
    • Xcode đôi khi có thể coi thời gian chạy sim của nền tảng bị thiếu khi thực hiện Đăng xuất và Đăng nhập của người dùng. (99200503)
      Cách giải quyết : Khởi động lại máy.
    • Khi chạy trong macOS 13 beta, mã AppIntents có thể không xây dựng được bằng Xcode 14. (99661742) (FB11470314)
      Cách giải quyết : Tạo mã AppIntents với Xcode 14 beta 6 hoặc trên máy Mac chạy macOS Monterey 12 với Xcode 14.
    • Không thể sử dụng Xcode 14 với iOS 15.7 để phát triển. (99847608)
      Cách giải quyết: Sử dụng Xcode 13.4.1 với iOS 15.7.

    Trình biên dịch Apple Clang

    Các tính năng mới

    • Các dự án C++ mới mà bạn tạo trong Xcode sử dụng phương ngữ ngôn ngữ mặc định là C++20. (93456065)
    • Một số C++20 và C++2b papers đã được triển khai:
      • Các C++20 papers đã triển khai:
        • P0692R1 – Kiểm tra quyền truy cập vào chuyên môn
        • P0388R4 – Cho phép chuyển đổi thành mảng có giới hạn không xác định
      • Các C++2b papers đã được triển khai:
        • P1938R3 –if consteval
        • P1401R5 – Thu hẹp chuyển đổi theo ngữ cảnh thành bool
        • P1949R7 – Cú pháp mã định danh C++ sử dụng Unicode Standard Annex 31
        • P2360R0 – Mở rộng init để cho phép khai báo bí danh (93898598)

    Vấn đề đã giải quyết

    • Đã sửa lỗi: Xcode không cung cấp tính năng làm nổi bật ngữ nghĩa và hỗ trợ chuyển sang định nghĩa cho các khai báo khái niệm C++20 và các mệnh đề yêu cầu trong các mẫu. (93046529)

    Tính năng không còn khả dụng trên XCode14

    • Bắt đầu với Xcode 14, bitcode không còn cần thiết cho các ứng dụng watchOS và tvOS và App Store không còn chấp nhận gửi bitcode từ Xcode 14. Xcode không còn xây dựng mã bit theo mặc định và tạo thông báo cảnh báo nếu một dự án kích hoạt rõ ràng mã bit: “Việc xây dựng bằng mã bit không được dùng nữa. Vui lòng cập nhật cài đặt dự án và/hoặc mục tiêu của bạn để tắt mã bit.” Khả năng xây dựng bằng mã bit sẽ bị xóa trong bản phát hành Xcode trong tương lai. IPA có chứa mã bit sẽ bị tước mã bit trước khi được gửi tới App Store. Chỉ có thể tải xuống các biểu tượng gỡ lỗi từ App Store Connect / TestFlight cho các lần gửi mã bit hiện có và không còn khả dụng cho các lần gửi được thực hiện bằng Xcode 14. (86118779)

    Danh mục tài sản

    Các tính năng mới

    • Đơn giản hóa biểu tượng ứng dụng bằng một hình ảnh 1024×1024 được tự động thay đổi kích thước cho mục tiêu của nó. Chọn tùy chọn Single Size trong tab Attributes inspector của mục app icon. Bạn vẫn có thể ghi đè các kích thước riêng lẻ bằng tùy chọn All Sizes. (18475136) (FB5503050)
    • Giờ đây, bạn có thể dán trực tiếp hình ảnh đã sao chép từ Finder vào asset catalog outline. (58980721)
    • Giờ đây, bạn có thể nhấp đúp vào một vị trí hình ảnh để hiển thị bảng điều khiển tệp đang mở và chọn nội dung thay thế. (81365822)
    • Bạn có thể chỉ định chế độ kết xuất mặc định cho các ký hiệu tùy chỉnh trong Asset Catalog. Đặt thuộc tính Kết xuất dưới dạng thành tự động, mẫu, nhiều màu hoặc phân cấp. Sau đó, hệ thống sẽ sử dụng chế độ kết xuất mặc định cho biểu tượng, trừ khi bạn ghi đè rõ ràng chế độ đó. Để biết thêm thông tin về biểu tượng tùy chỉnh, hãy xem Tạo hình ảnh biểu tượng tùy chỉnh cho ứng dụng của bạn . (84513859)

    Vấn đề đã giải quyết

    • Chế độ “Tất cả kích thước” cho các biểu tượng ứng dụng đã được làm linh hoạt hơn và bao gồm một số kích thước bổ sung chưa được sử dụng trước đây. Chế độ “Tất cả kích thước” không yêu cầu phải lấp đầy tất cả các vị trí, kích thước chỉ có thể được cung cấp khi cần. Các biểu tượng ứng dụng được tạo bằng Xcode 13 trở về trước có thể được chuyển đổi từ chế độ “Tất cả kích thước (Xcode 13)” thành “Tất cả các kích thước” hoặc “Một kích thước”. (93682080)

    Vấn đề đã biết

    • Các ứng dụng sử dụng biểu tượng ứng dụng có kích thước đơn lẻ có thể không xác thực được App Store nếu mục tiêu triển khai cũ hơn iOS 12 hoặc watchOS 4. (98471456)

    Build System

    Các tính năng mới

    • Xcode cung cấp một trình chỉnh sửa trợ lý mới cho nhật ký bản dựng tập trung vào tính song song để giúp xác định các vấn đề về hiệu suất bản dựng. Hình ảnh trực quan này hiển thị các sự kiện dưới dạng lưới các khối màu trong đó trục dọc biểu thị mức độ song song và trục ngang biểu thị thời gian. (47858322)
    • Xcode 14 hiện có thể biên dịch các mục tiêu song song với các phụ thuộc mục tiêu Swift của chúng. (57116972)
    • Trình điều khiển Swift, thành phần phối hợp các yêu cầu giao diện người dùng Swift, hiện được tích hợp vào hệ thống xây dựng của Xcode, cho phép phụ thuộc chi tiết hơn vào các tác vụ hệ thống xây dựng khác và lập lịch trình rõ ràng. (72440175)
    • Trong Build Phases, giờ đây bạn có thể chỉnh sửa hàng loạt tệp trong chế độ xem bảng nhiều lựa chọn. Khi bạn chỉnh sửa cột bộ lọc nền tảng của bảng đó, hệ thống sẽ áp dụng các thay đổi cho tất cả các tệp trong lựa chọn. (80683128) (FB9340886)
    • Các mục tiêu thư viện động và khung chỉ dành cho Swift có thể chọn tham gia tối ưu hóa hệ thống bản dựng mới bằng cách sử dụng cài đặt bản dựng EAGER_LINKING. Khi bạn bật tính năng này, Xcode sẽ phát ra các thành phần tạo tác bổ sung trong quá trình biên dịch Swift, cho phép Xcode bỏ chặn liên kết của các mục tiêu xuôi dòng trước đó, tăng tính song song trong các bản dựng. (82396635)
    • Hệ thống xây dựng chạy song song các tác vụ từ các giai đoạn xây dựng khác nhau khi các yếu tố phụ thuộc đầu vào và đầu ra không thực thi thứ tự của chúng. Bạn có thể chọn tham gia hành vi mới này cho các giai đoạn xây dựng tập lệnh chạy bằng cách sử dụng cài đặt bản dựng FUSE_BUILD_SCRIPT_PHASES. (82396977)
    • App Store hiện hỗ trợ làm mỏng ứng dụng cho các trình đổ bóng Metal được biên dịch sẵn. (82902821)
    • Các bản dựng Xcode cho thiết bị watchOS hiện bao gồm kiến ​​trúc arm64 theo mặc định. (83319300)
    • Đã thêm toán tử thay thế :relativeto=macro mới cho cài đặt bản dựng mà bạn có thể sử dụng để tính toán đường dẫn tương đối từ đường dẫn này sang đường dẫn khác; 
      Ví dụ: $(INSTALL_PATH:relativeto=/usr/lib)
      Chỗ INSTALL_PATH là “ /usr/bin..” và đánh giá là “../lib ”. Bạn có thể sử dụng quy tắc này trong quy tắc xây dựng để sao chép một loạt tham chiếu tệp trong khi vẫn duy trì phân cấp thư mục của chúng trong thư mục đích hoặc để tính toán mục tiêu dự kiến rpaths ​​bằng cách sử dụng đường dẫn tương đối giữa đường dẫn cài đặt của chính nó và đường dẫn cài đặt đã biết của các thành phần phụ thuộc. (88293015)
    • Xcode hiện cung cấp các cài đặt RECOMMENDED_MACOSX_DEPLOYMENT_TARGET, RECOMMENDED_IPHONEOS_DEPLOYMENT_TARGET, RECOMMENDED_TVOS_DEPLOYMENT_TARGET, RECOMMENDED_WATCHOS_DEPLOYMENT_TARGET, RECOMMENDED_DRIVERKIT_DEPLOYMENT_TARGET và xây dựng cho biết các phiên bản triển khai tối thiểu được đề xuất cho từng nền tảng Xcode được hỗ trợ. (90464341)
    • Giờ đây, bạn có thể bật Sandbox cho các giai đoạn xây dựng tập lệnh shell bằng cách sử dụng ENABLE_USER_SCRIPT_SANDBOXING trong build settings. Sandbox chặn quyền truy cập vào các tệp bên trong gốc nguồn của dự án cũng như thư mục Dữ liệu được tạo trừ khi bạn liệt kê các tệp đó dưới dạng đầu vào hoặc đầu ra. Khi được bật, quá trình xây dựng không thành công do vi phạm Sandbox nếu một giai đoạn tập lệnh cố gắng đọc hoặc ghi vào một phần phụ thuộc không được khai báo, ngăn chặn các quá trình xây dựng không chính xác. (90506067)

    Vấn đề đã giải quyết

    • Đã khắc phục sự cố trong đó nhiều dự án Xcode tham chiếu cùng một xcconfig (do đó bao gồm một xcconfig khác) đã tính toán không chính xác cùng một cài đặt bản dựng trên cả hai dự án. (84319288) (FB9707003)
    • Đã sửa lỗi: đích chạy của thiết bị watchOS không còn xuất hiện hai lần trong menu đích chạy. (85635959)
    • Cải thiện tốc độ tải của không gian làm việc lớn có nhiều mục tiêu chia sẻ .xcconfigtệp. (85985712)
    • Đã sửa lỗi: Khi bạn lưu trữ ứng dụng watchOS với kiến ​​trúc arm64e được bật, ứng dụng đó không thể xây dựng. (93550623)

    Vấn đề đã biết

    • Báo cáo sự cố từ các ứng dụng Mac Catalyst không được ký hiệu đầy đủ trong Xcode Organizer. (94820955)

    Tính năng bị loại bỏ

    • Vì mã bit hiện không được dùng nữa nên các bản dựng cho iOS, tvOS và watchOS không còn bao gồm mã bit theo mặc định. (87590506)
    • Đã thêm cài đặt bản dựng mới, SWIFT_TOOLS_DIR, thay thế SWIFT_EXEC làm cơ chế được đề xuất để sử dụng tệp thực thi giao diện người dùng nhanh tùy chỉnh. SWIFT_TOOLS_DIR phải được đặt thành đường dẫn của thư mục chứa giao diện người dùng nhanh và các công cụ liên quan. Lưu ý rằng vì trình điều khiển Swift hiện được tích hợp trong hệ thống xây dựng Xcode, không thể sử dụng SWIFT_TOOLS_DIR và SWIFT_EXEC để chỉ định nhị phân trình điều khiển tùy chỉnh trừ khi SWIFT_USE_INTEGRATED_DRIVER được đặt thành NO. (88967344)
    • Hệ thống xây dựng cũ đã bị xóa. (90801041)
    • Việc xây dựng các dự án iOS với các mục tiêu triển khai cho kiến ​​trúc armv7, armv7s và i386 không còn được hỗ trợ nữa. (92831716)
    • Bản phát hành xây dựng để triển khai cho hệ điều hành cũ hơn macOS 10.13, iOS 11, tvOS 11 và watchOS 4 không còn được hỗ trợ. (92834476)
    • Khi xóa một điều kiện khỏi trình chỉnh sửa biến thể, giá trị sẽ không được duy trì. (98149034)
      Giải pháp thay thế: Sử dụng Trình chỉnh sửa cài đặt bản dựng để xóa điều kiện.

    Debugging

    Các tính năng mới

    • Trình gỡ lỗi biểu đồ bộ nhớ hiện hiển thị tất cả các tham chiếu đến và đi trong biểu đồ bộ nhớ. Bạn có thể điều chỉnh tập hợp các nút hiển thị trong cửa sổ bật lên mới. (69454709)
    • LLDB hiện hiển thị các cập nhật tiến độ trong Xcode và dòng lệnh cho các hoạt động chạy dài. (73511008)
    • Giờ đây, bạn có thể gọi tập lệnh nhật ký sự cố của LLDB bằng xcrun crashlog <path/to/crash>. (79991815)
    • Trình kiểm tra hiệu suất luồng hiển thị các vấn đề về hiệu suất thời gian chạy trong Trình điều hướng sự cố và trình chỉnh sửa nguồn trong khi gỡ lỗi ứng dụng. Chọn hộp kiểm Trình kiểm tra hiệu suất luồng trong Lược đồ chạy của mục tiêu ứng dụng của bạn để bật tính năng này. (80048810)
    • Giờ đây, bạn có thể mở một .xcresult cho một hành động scheme khởi chạy. (88932007)
    • Xcode hiện hiển thị nhật ký khởi chạy mới trong Trình điều hướng báo cáo. Nhật ký cho biết các hành động mà Xcode thực hiện để cài đặt, khởi chạy và gỡ lỗi. (90859910)

    Vấn đề đã giải quyết

    • Cải thiện hiệu suất khi gỡ lỗi chương trình Swift trên thiết bị iOS. Thay vì sao chép siêu dữ liệu phản ánh từ thiết bị iOS, giờ đây Xcode có thể đọc siêu dữ liệu từ đĩa. (73179144)
    • Xcode hiện nhóm các mục nhật ký cho cùng một hành động sơ đồ khởi chạy trong trình điều hướng Báo cáo. (87216988)
    • Đã sửa lỗi: Thay vào đó, bước vào chức năng không đồng bộ Swift trong LLDB sẽ hoàn thành chức năng hiện tại. (88142757)

    Vấn đề đã biết

    • Không thể đính kèm trình gỡ lỗi vào Tiện ích mở rộng tiện ích màn hình khóa. (93941779)
      Giải pháp thay thế: Chỉnh sửa Extension scheme – trong tab Run action, tab Argument, hãy đặt biến môi trường ‘_XCWidgetKind’ thành một trong các tên class/struct của bạn khi triển khai widget.

    Tài liệu

    Các tính năng mới

    • Swift-DocC trong Xcode hiện hỗ trợ viết và xây dựng tài liệu cho API Objective-C và C. (58760015)
    • Các trang web tài liệu Swift-DocC mà Xcode 14 tạo ra bao gồm một thanh bên điều hướng mới để khám phá và lọc tài liệu. (89031049)
    • Theo mặc định, tài liệu Swift-DocC mà Xcode 14 tạo ra hiện tương thích với hầu hết các dịch vụ lưu trữ được quản lý, bao gồm Trang GitHub. (91173450)

    Vấn đề đã giải quyết

    • Đã sửa lỗi: Swift-DocC đưa ra chẩn đoán không chính xác về các lệnh không được hỗ trợ trong tài liệu nguồn biểu tượng khi xây dựng tài liệu cho các dự án Objective-C bao gồm các lệnh Doxygen. (90953916)
    • Đã sửa lỗi: Tài liệu Mục tiêu-C cho các API đa ngôn ngữ hiển thị các mối quan hệ ký hiệu Swift thay vì các mối quan hệ Mục tiêu-C. (91627374)
    • Đã sửa lỗi: Swift-DocC đưa ra chẩn đoán không chính xác về các liên kết ký hiệu không thể giải quyết đối với tài liệu kế thừa từ các ký hiệu trong các mô-đun khác. (92185538)
    • Đã sửa lỗi : Không thể xây dựng tài liệu cho các loại phù hợp với ChartContent protocol khi conform Swift Charts. (93610106)

    Instruments

    Các tính năng mới

    • Các hàm tổng hợp hoạt động trên các khoảng thời gian hiện tính toán chính xác hơn kết quả của chúng khi bộ lọc thời gian đang hoạt động, chỉ dựa trên phần của khoảng thời gian tổng thể giao với bộ lọc thời gian hiện tại. (32330648)
    • Bộ lọc chi tiết hiện cho phép áp dụng các bộ lọc cho một cột cụ thể khi xem Chế độ xem danh sách. Có thể thêm các bộ lọc đã nhập này bằng cách sử dụng menu ngữ cảnh trên các giá trị được hiển thị hoặc bằng cách nhập mã thông báo rồi chọn loại mã thông báo. (56080914)
    • Các rãnh Chủ đề chính hiện được sắp xếp đầu tiên khi hiển thị các rãnh trong dòng thời gian của Nhạc cụ. (59876638)
    • Công cụ có công cụ Theo dõi treo mới hiển thị khi chuỗi chính của ứng dụng không thể xử lý các sự kiện đến trong một khoảng thời gian dài, có khả năng khiến giao diện người dùng bị treo. Ngoài ra, các công cụ Time Profiler và CPU Profiler cũng hiển thị khả năng bị treo. (65694830)
    • Biểu đồ biểu đồ trong Công cụ hiện hiển thị thời lượng của phạm vi thời gian được sử dụng để tổng hợp dữ liệu trong chú giải công cụ di chuột qua. (65684291)
    • Chế độ xem danh sách của công cụ hiện hiển thị nhãn trạng thái ở dưới cùng, báo cáo về số lượng hàng hiện có và được chọn trong chế độ xem hiện tại. (82652407)
    • Mẫu Core ML mới có sẵn trong Công cụ. Mẫu này bao gồm các công cụ Core ML và Neural Engine mới cùng với các công cụ GPU và Time Profiler. Sử dụng mẫu này để giúp lập hồ sơ sử dụng Core ML và hiểu cách các mô hình của bạn đang chạy trên thiết bị. Việc kết hợp thông tin từ Core ML, Công cụ thần kinh và Công cụ GPU có thể giúp theo dõi những hoạt động nào được thực thi trên phần cứng được tăng tốc. Dữ liệu thời gian tổng hợp có sẵn cho từng sự kiện, mô hình và mô hình con. (83123510)
    • Bạn có thể mở một menu ngữ cảnh mới bằng các khoảng thời gian bấm Điều khiển trong dòng thời gian. Menu cung cấp các hành động để đặt bộ lọc thời gian theo khoảng thời gian đã chọn hoặc hiển thị thông tin tương ứng trong khu vực chi tiết. (86728567)
    • Chế độ xem Thông tin Chạy của Dụng cụ hiện bao gồm kiến ​​trúc của tệp nhị phân đích khi ghi một dấu vết quy trình. (89733709)
    • Instruments có một công cụ Runloop mới hiển thị việc sử dụng runloop và các lần lặp lại riêng lẻ, đồng thời phân biệt trực quan các chế độ ngủ của runloop và các khoảng thời gian bận cho tất cả các runloop trong một quy trình. (89746568)
    • Các giá trị trong chế độ xem chi tiết tổng hợp hoặc danh sách giờ đây sẽ được tô sáng khi bạn trỏ con trỏ qua chúng và bạn có thể giữ Control khi bấm vào một giá trị để xem menu ngữ cảnh. Menu này hiển thị các hành động để sao chép giá trị, đặt bộ lọc chi tiết và thêm hoặc ghim rãnh nếu giá trị có đại diện cho rãnh. (90817779)
    • Các công cụ hiện bao gồm một mẫu Đồng thời Swift mới để theo dõi cách sử dụng và hành vi của các nguyên mẫu đồng thời của Swift. Mẫu chứa:
      • Một công cụ Swift Tasks mới hiển thị các trạng thái nhiệm vụ theo thời gian, tóm tắt các trạng thái nhiệm vụ, cung cấp tường thuật chi tiết về nhiệm vụ, minh họa các mối quan hệ đồng thời có cấu trúc và xây dựng cây cuộc gọi của các ngăn xếp công việc tạo nhiệm vụ.
      • Một công cụ Swift Actors mới để theo dõi hành vi tác vụ giữa các tác nhân hiển thị hàng đợi tác vụ cho từng tác nhân và giúp chẩn đoán các sự cố với mã và tranh chấp được cô lập bởi tác nhân.Các công cụ này yêu cầu thiết bị trong thời gian chạy đồng thời Swift lần đầu tiên có sẵn trong macOS 13, iOS 16, tvOS 16 và watchOS 9 trở lên. (69852855)
    • heapleaks, and Instruments’ leaks tool hiện báo cáo ít tham chiếu sai hơn bắt nguồn từ phân bổ liên quan đến đồng thời Swift và xác định đây là phân bổ Swift AsyncTask. (72907112)
    • leaks --atExit -- <command> giờ đây sẽ tự động đặt trong môi trường MallocStackLogging=lite cho lệnh đã chỉ định để Công cụ có thể hiển thị dấu vết ngược ngăn xếp cho phân bổ bị rò rỉ. Để sử dụng một cài đặt khác của biến môi trường đó (chẳng hạn như CÓ hoặc KHÔNG), hãy đặt biến môi trường trước khi chạy leaks. (73779272)
    • xctrace bây giờ sẽ gửi thông báo Darwin khi bắt đầu theo dõi, thông báo này nên được ưu tiên thay vì đọc đầu ra tiêu chuẩn của lệnh. Để sử dụng nó, hãy chỉ định notify-tracing-started tùy chọn có tên thông báo mong muốn và sử dụng notify_register_dispatch để nhận thông báo không đồng bộ trong tập lệnh của bạn. (75745933)
    • Cải thiện hiệu suất phân tích của mẫu Dấu vết Hệ thống. Các công cụ hiện hiển thị các bản ghi cho người dùng nhanh hơn; tuy nhiên, khi theo dõi một quy trình đơn lẻ, bạn không thể thấy trạng thái luồng cho các quy trình khác. Thay vào đó, để xem trạng thái của các quy trình khác, hãy theo dõi “Tất cả các quy trình”. (79904471)
    • Đối với các quy trình đang chạy MallocStackLogging được bật, heap, leaks và trình gỡ rối bộ nhớ Xcode hiển thị các tên loại dành cho phân bổ không đối tượng ở dạng malloc in <function name> trong đó “function name” là khung ngăn xếp không phân bổ đầu tiên. Tính năng này giúp xác định rõ hơn mục đích của bộ nhớ phi đối tượng. (85598783)
    • heap -addresses=all hiện hiển thị các mô tả của các đối tượng CFData có chứa các .plisttệp nhị phân theo cách dễ đọc hơn đối với con người. (88466642)

    Vấn đề đã giải quyết

    • heap , leaks, và stringdups bây giờ bao gồm nội dung của một số loại chuỗi Swift được cấp phát theo đống trong phần mô tả về cấp phát của các chuỗi đó. (14902403)
    • Công cụ Hiệu suất GCD hiện diễn giải chính xác các sự kiện có mã “7” và “9”. (69721960)
    • Thiết kế trình xem nguồn trong Công cụ bao gồm các cải tiến để hiển thị dữ liệu hiệu suất tốt hơn:
      • Có một chế độ Xen kẽ mới để xem mã nguồn và tháo gỡ liên kết với nhau, giúp việc liên kết các hướng dẫn được tạo cho từng dòng mã nguồn trở nên dễ dàng hơn.
      • Trình xem nguồn hiện hiển thị các giá trị được lấy mẫu được gán cho một dòng mã hoặc phân tách trong một cột riêng biệt thay vì dưới dạng chú thích dòng.
      • Trình xem nguồn hiện hiển thị Bộ đếm CPU, sự kiện PMC và công thức động được định cấu hình trong các tùy chọn ghi bên cạnh nguồn và tháo gỡ. (80232392)
    • Đã khắc phục sự cố trong đó Chế độ xem nguồn trong Công cụ đôi khi không hiển thị chú thích hiệu suất khi được mở từ chế độ xem Sơ đồ cuộc gọi. (80501587)
    • Khi sử dụng Instruments Source Viewer ở chế độ xem tách, việc chọn tháo gỡ bây giờ cũng chọn nguồn tương ứng ở bên trái. (82642041)
    • Đã khắc phục sự cố xctrace export đôi khi xuất giá trị chuỗi UTF-16 thay vì UTF-8, dẫn đến lỗi kết xuất trong Terminal. (87594987)
    • Đã khắc phục sự cố trong đó một số sự kiện đã ghi sau khi khởi động lại sẽ bị mất khi nhập kho lưu trữ nhật ký trong quá trình khởi động lại thiết bị. (89003393)
    • Đã sửa lỗi xctrace list devices đôi khi không bao gồm tất cả các thiết bị được kết nối vật lý trong đầu ra của nó. (89142775) (FB9913864)
    • heapleaks, and Instruments hiện nhận dạng chính xác bảng phụ của các đối tượng Swift đã hủy phân bổ dưới dạng bảng phụ. (89459805)
    • Đã khắc phục sự cố trong đó Công cụ không cho phép ghi các thiết bị tvOS được kết nối qua WiFi. (89592418) (FB9935783)
    • Đã khắc phục sự cố trong đó bản dựng gói Công cụ tùy chỉnh có thể không thành công khi cùng một biến được sử dụng nhiều lần trong trường biểu thức. (89653878)
    • heapleaks, and Instruments hiện hiển thị tên dễ đọc hơn cho các loại thư viện tiêu chuẩn Foundation và Swift bổ sung. (90441836)
    • xctrace không còn trả về trạng thái lỗi khi truy tìm chỉ gây ra cảnh báo. Các vấn đề hiện được quy cho mức độ nghiêm trọng thích hợp. (90560207) (FB9963155)
    • Đã khắc phục sự cố trong xctrace export khi dữ liệu theo dõi VM và phân bổ đôi khi được xuất với các hàng dữ liệu bị thiếu. (90560947) (FB9963169)
    • Đã khắc phục sự cố trong đó Công cụ sẽ quên đối số dòng lệnh sau khi mở và đóng trình chỉnh sửa đích khi đã có đối số. (90666084)
    • Đã khắc phục sự cố khi di chuyển đầu kiểm tra trong thước theo dõi cũng sẽ cuộn trục Y của dòng thời gian. (90810506)
    • Đã sửa lỗi: Khoảng thời gian chạy vòng lặp cho thời gian chạy, lặp, chờ và bận có nhãn và độ dài không chính xác khi được hiển thị trong rãnh quy trình. (91130163)
    • Đã khắc phục sự cố Công cụ không liên tục khi ghi dấu vết với các mẫu Phân bổ hoặc Rò rỉ. (93916110)
    • Đã sửa lỗi: Tạo Báo cáo hiệu suất Core ML có thể không thành công sau khi bật Chế độ nhà phát triển trên thiết bị. (93923607)

    Vấn đề đã biết

    • Ký hiệu mã người dùng dSYM có thể không thành công đối với tệp tailspin được nhập vào Công cụ. Các ký hiệu cho thư viện hệ thống cũng không xuất hiện khi các tệp này được tải. (93261223)
      Giải pháp thay thế : Ký hiệu nhật ký treo trong Terminal bằng spindump -i <UIKit-runloop*.ips>.
    • Vô hiệu hóa Trình kiểm tra hiệu suất luồng thông qua tab Chẩn đoán trong Trình chỉnh sửa lược đồ nếu Ứng dụng iOS hoặc macOS của bạn sử dụng Fishhook để kết nối các cuộc gọi tới libSystem nhằm mục đích gỡ lỗi/theo dõi. (94724380) (FB10131267)

    Refer: https://developer.apple.com/documentation/xcode-release-notes/xcode-14-release-notes

  • Hướng dẫn tạo và sử dụng Manually Signing App

    Hướng dẫn tạo và sử dụng Manually Signing App

    Link tham khảo: https://help.apple.com/developer-account/

    Code Signing là một thứ bắt buộc để ta có thể cài đặt ứng dụng vào devices thật, hoặc để upload lên AppStore Connect. Có hai cách để cài đặt code signing, “Automatically manage signing” hoặc “Manually manage signing”. Bài viết này sẽ hướng dẫn cài đặt manual code signing.

    Để cài đặt app, bạn cần có :

    • Signing certificate (Personal Information Exchange, .p12)
    • Provisioning profile (.mobileprovision)

    Signing certificate là chứng chỉ giúp xác định danh tính để cài app

    Provision profile (development hoặc distribution) chứa những thông tin về appID, các devices mà app có thể cài đặt, thông tin certificate để signing app. Lưu ý rằng nếu ứng dụng có chứa các extensions, bạn cần thêm các provision profile tương ứng 

    Mỗi dự án sẽ có những certificate và provision profile riêng. Như ảnh dưới, ta có 2 certificate, cho môi trường dev và distribute, ta cũng có các provision dev và distribute tương ứng, kèm theo đó là những provision profile của các extension của app.

    Sau đây là hướng dẫn tạo manually signing app:

    B1. Tạo certificate cho app

    1. Ở Certificates, Identifiers & Profiles, chọn Certificates

    2. Chọn nút (+)

    3. Chọn loại certificates mà mình muốn và chọn nút “Tiếp tục”

    4. Tạo certificate signing request

    4.1. Mở app Keychain Access ở máy

    4.2. Chọn Keychain Access > Certificate Assistant > Request a Certificate from a Certificate Authority. 

    4.3. Điền thông tin như email, name, bổ trống CA Email Address

    4.4. Chọn “Save to disk” và chọn tiếp tục

    5. Chọn file đuôi .certSigningRequest đã tạo ở b4

    6. Chọn “Tiếp tục” và “Tải về” máy. (File certificate sẽ có đuôi .cer)

    B2. Đăng ký AppID

    AppID sẽ định danh app của bạn trong provisioning profile. Có 2 loại AppID: explicit AppID (sử dụng riêng từng app) và wildcard AppID (sử dụng chung 1 số app). Wildcard AppID sẽ chỉ enable được một số Capabilities, nếu muốn sử dụng những Capabilities khác, bạn phải tạo explicit AppID

    Các bước tạo AppID:

    1. Trong Certificates, Identifiers & Profiles, chọn “Identifiers”, rồi chọn (+)
    2. Chọn AppIDs 
    3. Điền name, descriptions, chọn các loại Capabilities mà app sẽ dùng
    • Nếu chọn Explicit App ID, bạn phải điền giống bundleID của app trong Xcode
    • Nếu chọn Wildcard App ID, bạn phải điền bundle ID với hậu tố (VD: com.domainname.*)

    B3. Đăng ký devices

    Đăng ký một device:

    1. Trong Certificates, Identifiers & Profiles, chọn Devices, rồi chọn (+)
    2. Chọn platform, điền device name, device ID (UDID)
    3. Chọn tiếp tục, chọn “Register” để hoàn tất đăng ký

    Đăng ký nhiều device:

    Bạn có thể dùng app “Configurator 2” trên MacAppStore hoặc tạo file .txt chứa thông tin (mỗi dòng chứa deviceID, device name, platform name cách nhau bởi tab-delimited)

    B4. Tạo provisioning profile

    1. Trong Certificates, Identifiers & Profiles, chọn Profiles, rồi chọn nút (+) 
    2. Chọn loại provisioning profile mà bạn muốn tạo, rồi chọn “Tiếp tục”

    3. Chọn App ID mà mình đã tạo ở Bước 2, chọn “Tiếp tục”

    4. Chọn Certificate mà mình đã tạo ở Bước 1, chọn “Tiếp tục”

    5. Chọn các device đã được tạo ở Bước 3, chọn “Tiếp tục”

    6. Điền profile name, rồi chọn “Generate”

    7. Chọn “Download” để tải về

    8. Sau khi đã tải về, click double vào các certificate và nhập mật khẩu để add vào keychain

    • Tắt Automatically manage signing trong Xcode 
    • Import các provision profile tương ứng 

    Nếu status không còn báo đỏ nữa là bạn đã import thành công. Giờ run và build thôi.

  • [MacOS] Hướng dẫn cài đặt Oracle JDK

    [MacOS] Hướng dẫn cài đặt Oracle JDK

    Mặc định thì Oracle JDK sẽ được chọn cài đặt trên MacOS. Do đó nếu muốn sử dụng Oracle JDK thì bạn cần phải cài đặt lại. Trong bài viết này tôi sẽ hướng dẫn các bạn cài đặt Oracle JDK.

    Homebrew

    • Nếu bạn chưa cài đặt brew thì có thể sử dụng lệnh sau để tiến hành cài đặt
    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
    
    • Nếu đã cài đặt rồi thì tiến hành update lastest brew như sau:
    hieunv@HieuNV ~ % brew update && brew upgrade
    Updated 1 tap (homebrew/core).
    ==> New Formulae
    swift-sh
    ==> Updated Formulae
    apache-spark               jetty                      xcodegen
    docker-slim                vim                        zsh-syntax-highlighting
    Updating Homebrew...
    

    Kiểm tra caskjava

    brew cask info java
    

    Nếu homebrew/cask chưa được cài đặt thì nó sẽ tự động cài đặt luôn

    hieunv@HieuNV ~ % brew cask info java
    ==> Tapping homebrew/cask
    Cloning into '/usr/local/Homebrew/Library/Taps/homebrew/homebrew-cask'...
    remote: Enumerating objects: 3655, done.
    remote: Counting objects: 100% (3655/3655), done.
    remote: Compressing objects: 100% (3648/3648), done.
    remote: Total 3655 (delta 26), reused 510 (delta 5), pack-reused 0
    Receiving objects: 100% (3655/3655), 1.23 MiB | 215.00 KiB/s, done.
    Resolving deltas: 100% (26/26), done.
    Tapped 1 command and 3543 casks (3,660 files, 4.0MB).
    java: 13.0.2,8:d4173c853231432d94f001e99d882ca7
    https://openjdk.java.net/
    Not installed
    From: https://github.com/Homebrew/homebrew-cask/blob/master/Casks/java.rb
    ==> Name
    OpenJDK Java Development Kit
    ==> Artifacts
    jdk-13.0.2.jdk -> /Library/Java/JavaVirtualMachines/openjdk-13.0.2.jdk (Generic Artifact)
    
    • Nếu đã cài đặt rồi bạn sẽ nhận được thông tin về phiên bản java đã được cài đặt
    hieunv@HieuNV ~ % brew cask info java
    java: 13.0.2,8:d4173c853231432d94f001e99d882ca7
    https://openjdk.java.net/
    Not installed
    From: https://github.com/Homebrew/homebrew-cask/blob/master/Casks/java.rb
    ==> Name
    OpenJDK Java Development Kit
    ==> Artifacts
    jdk-13.0.2.jdk -> /Library/Java/JavaVirtualMachines/openjdk-13.0.2.jdk (Generic Artifact)
    

    Tiến hành cài đặt Oracle JDK sử dụng brew cask

    hieunv@HieuNV ~ % brew cask install oracle-jdk
    ==> Caveats
    Installing oracle-jdk means you have AGREED to the license at:
      https://www.oracle.com/technetwork/java/javase/terms/license/javase-license.html
    
    ==> Downloading https://download.oracle.com/otn-pub/java/jdk/13.0.2+8/d4173c8532
    ==> Downloading from https://download.oracle.com/otn-pub/java/jdk/13.0.2+8/d4173
    ######################################################################## 100.0%
    ==> Verifying SHA-256 checksum for Cask 'oracle-jdk'.
    ==> Installing Cask oracle-jdk
    ==> Running installer for oracle-jdk; your password may be necessary.
    ==> Package installers may write to any location; options such as --appdir are i
    Password:
    installer: Package name is JDK 13.0.2
    installer: Installing at base path /
    installer: The install was successful.
    ?  oracle-jdk was successfully installed!
    

    Kiểm tra phiên bản java sau khi cài đặt

    hieunv@HieuNV ~ % java --version
    java 13.0.2 2020-01-14
    Java(TM) SE Runtime Environment (build 13.0.2+8)
    Java HotSpot(TM) 64-Bit Server VM (build 13.0.2+8, mixed mode, sharing)
    
    hieunv@HieuNV ~ % javac --version
    javac 13.0.2
    

    setting JAVA_HOME

    Thêm export JAVA_HOME=$(/usr/libexec/java_home) vào ~/.zshrc

    echo 'export JAVA_HOME=$(/usr/libexec/java_home)' >> ~/.zshrc
    

    Kiểm tra biến JAVA_HOME

    Đóng Termial sau đó bật lại và kiểm tra biến JAVA_HOME

    hieunv@HieuNV libexec % echo $JAVA_HOME
    /Library/Java/JavaVirtualMachines/jdk-13.0.2.jdk/Contents/Home
    

    Như vậy là bạn đã tiến hành cài đặt thành công Oracle Java rồi.
    Tài liệu tham khảo
    https://emcorrales.com/blog/install-oracle-jdk-macos-homebrew

  • Cải thiện Terminal mặc định của MacOS với zsh và zsh-autosuggestions

    Cải thiện Terminal mặc định của MacOS với zsh và zsh-autosuggestions

    Giới thiệu chung

    Sau khoảng thời gian làm việc trên MacOS, có quá nhiều lệnh bạn phải nhớ, hoặc đôi khi bạn phải thực hiện đi thực hiện lại nhiều lần, giá như terminal ngoài auto-complete mà có thể suggest được lệnh cho chúng ta thì tốt biết mấy. Bài viết này giúp bạn giải quyết điều đó!

    ?

    Về mình, thực ra mình là một thằng Developer khá đơn giản  nên mình thích mọi thứ cũng đơn giản, rộng rãi và thoáng đãng. Cũng bởi lẽ đó nên ngay từ khi bắt đầu sử dụng MacOS để làm việc, mình đã yêu thích Terminal mặc định của nó; ngay từ khi nhìn cái logo đơn giản nhưng không kém phần bắt mắt.

    Để làm được việc suggest lệnh thì với /bin/bash là không đủ, chúng ta cần đổi bộ shell mặc định này sang một thằng khác mạnh mẽ hơn đó là Z-Shell hay còn gọi là zsh.

    Đi kèm zsh có một framework đó là oh-my-zsh support mọi thứ từ theme, command line prompts, auto suggestions, .etc. Trong bài mình sẽ hướng dẫn mọi người cài đặt zsh và oh-my-zsh trên MacOS, tích hợp plugin zsh-autosuggestions cho oh-my-zsh để terminal có thể tự động suggest lệnh cho chúng ta. Hãy cùng bắt đầu nhé!

    Cài đặt zsh

    Cài đặt trực tiếp zsh thông qua brew như sau:

    $ brew install zsh

    Kiểm tra xem đã cài đặt thành công chưa:

    $ which zsh
    
    /usr/local/bin/zsh

    Cài đặt oh-my-zsh

    Bây giờ chúng ta cài đặt oh-my-zsh, là một framework cho zsh sẽ giúp mình cài đặt nhiều thứ như theme, PS1 prompts:

    $ sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"

    Cài đặt zsh-autosuggestions

    Cài đặt plugin zsh-autosuggestions, giúp tự động suggetions các lệnh mà mình đã dùng:

    ➜ brew install zsh-autosuggestions

    $ brew install zsh-autosuggestions

    Tiếp đó để kích hoạt plugin zsh-autosuggtestions lên, mình cần chạy thêm lệnh sau:

    ➜ source ~/.oh-my-zsh/custom/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh

    Khởi động lại terminal và tận hưởng:

  • Hướng dẫn cài đặt DynamoDB với Docker

    Hướng dẫn cài đặt DynamoDB với Docker

    Cài đặt docker

    • Cập nhập brew
    hieunv@HieuNV ~ % brew update && brew upgrade
    Updated 1 tap (homebrew/core).
    No changes to formulae.
    
    • Cài đặt docker
    brew install docker
    
    • Kiểm tra docker sau khi cài đặt
    hieunv@HieuNV ~ % docker -v
    Docker version 19.03.1, build 74b1e89
    
    • Khởi động Docker
    Kiểm tra trạng thái docker

    Tạo DynamoDB container

    • Tạo docker-compose.yml để up DynamoDB

    docker-compose.yml

    version: '3'
    services:
      dynamodb:
        image: amazon/dynamodb-local
        container_name: dynamodb
        ports:
          - '8000:8000'
        volumes:
          - ./dynamodb/data:/home/dynamodblocal/data
        entrypoint: java
        command: '-jar DynamoDBLocal.jar -sharedDb -dbPath /home/dynamodblocal/data'
    
    • Up DynamoDB container sau khi tạo docker-compose.yml
    docker-compose up -d
    
    Kiểm tra trạng thái docker sau khi up DynamoDB container

    Bạn có thể truy cập vào docker shell bằng link sau:

    http://localhost:8000/shell
    

    Như vậy là bạn đã tạo xong container cho DynamoDB rồi.

  • Quản lý python packages như thế nào cho đúng

    Quản lý python packages như thế nào cho đúng

    Maven dùng pom để quản lý packages, Node thì có packages.json. Anh em python thì quản lý python packages bằng pip (Package installer for Python). Tuy nhiên khi sử dụng pip sẽ gặp phải tình huống các dự án khác nhau sử dụng dánh sách packages khác nhau. Vấn đề lớn hơn nữa có thể xảy ra tình huống 2 dự án nào đó sử dụng cùng package ở hai phiên bản khách nhau. Trong bài viết này tôi sẽ hướng dẫn các bạn cách quản lý python packages cho các dự án khác nhau mà không bị phụ thuộc vào nhau. Chúng ta cùng bắt đầu nhé.

    Kiểm tra tình trạng hoạt động của brew nào:

    hieunv@HieuNV ~ % brew update && brew upgrade
    Updated 1 tap (homebrew/core).
    ==> Updated Formulae
    abcm2ps             consul              grails              pjproject
    allure              dps8m               graphicsmagick      rancid
    appstream-glib      erlang              i2p                 ratfor
    byteman             flyway              jruby               stress-ng
    camlp5              folly               libgphoto2          zydis
    cargo-instruments   fonttools           libjwt
    cfengine            gmsh                mill
    clblast             gptfdisk            mongoose
    

    Cài đặt python 3

    brew install python
    

    Mặc định MacOS sử dụng python 2

    hieunv@HieuNV ~ % python -V
    Python 2.7.16
    hieunv@HieuNV ~ % python3 -V
    Python 3.7.0
    

    Các bạn cần thêm đoạn sau vào ~/.zshrc.

    export PATH="/usr/local/opt/python/libexec/bin:/usr/local/sbin:$PATH"
    

    Nếu đang mở Terminal bạn cần đóng Terminal lại rồi kiểm tra lại python version

    hieunv@HieuNV ~ % python -V
    Python 3.7.6
    hieunv@HieuNV ~ % pip -V
    pip 19.3.1 from /usr/local/lib/python3.7/site-packages/pip (python 3.7)
    

    Cài đặt virtualenvvirtualenvwrapper

    Với python các packages không được cài đặt cục bộ giống như node. Do đó chúng ta cần tạo ra các môi trường khác nhau với các packages khác nhau để sử dụng cho các dự án khác nhau.

    Cài đặt virtualenv

    pip install virtualenv
    

    Cài đặt virtualenvwrapper

    pip install virtualenvwrapper
    

    Activate virtualenv mỗi khi bật khởi động Terminal

    Các bạn thêm đoạn sau vào ~/.zshrc để virutalenv có thể dượcd khởi động mỗi khi bạn bật Terminal

    export WORKON_HOME=$HOME/.virtualenvs
    source /usr/local/bin/virtualenvwrapper.sh
    

    Tiến hành tạo môi trưởng ảo và cài đặt packages mong muốn

    • Tạo môi trường ảo
    hieunv@HieuNV ~ % mkvirtualenv a
    created virtual environment CPython3.7.6.final.0-64 in 515ms
      creator CPython3Posix(dest=/Users/hieunv/.virtualenvs/a, clear=False, global=False)
      seeder FromAppData(download=False, pip=latest, setuptools=latest, wheel=latest, via=copy, app_data_dir=/Users/hieunv/Library/Application Support/virtualenv/seed-app-data/v1)
      activators BashActivator,CShellActivator,FishActivator,PowerShellActivator,PythonActivator,XonshActivator
    virtualenvwrapper.user_scripts creating /Users/hieunv/.virtualenvs/a/bin/predeactivate
    virtualenvwrapper.user_scripts creating /Users/hieunv/.virtualenvs/a/bin/postdeactivate
    virtualenvwrapper.user_scripts creating /Users/hieunv/.virtualenvs/a/bin/preactivate
    virtualenvwrapper.user_scripts creating /Users/hieunv/.virtualenvs/a/bin/postactivate
    virtualenvwrapper.user_scripts creating /Users/hieunv/.virtualenvs/a/bin/get_env_details
    (a) hieunv@HieuNV ~ %
    

    Các bạn để ý dòng cuối cùng (a). Sau khi tạo xong thì zsh đã activate vào môi trường ảo.

    • Active vào môi trường ảo nếu môi trường chưa được active thì có thể làm như sau:
    hieunv@HieuNV ~ % workon a
    (a) hieunv@HieuNV ~ %
    
    • Khi muốn thoát khỏi môi trường ảo thì có thể làm như sau:
    (a) hieunv@HieuNV ~ % deactivate
    hieunv@HieuNV ~ %
    
    • Để cài đặt packages thì tiến hành cài đặt bằng pip như bình thường
    pip install boto3
    

    Sử dụng môi trường ảo với python 2

    • Cài đặt python 2
    brew install python2
    
    • Tạo môi trường ảo sử dụng python bằng tham số -p
    mkvirtualenv py2 -p python2
    

    Export package list để install trên máy khác

    (a) hieunv@HieuNV ~ % pip freeze > requirements.txt
    (a) hieunv@HieuNV ~ % cat requirements.txt
    boto3==1.12.11
    botocore==1.15.11
    docutils==0.15.2
    jmespath==0.9.5
    python-dateutil==2.8.1
    s3transfer==0.3.3
    six==1.14.0
    urllib3==1.25.8
    

    Cài đặt packages sử dụng requirements.txt

    pip install -r requirements.txt
    

    Tài liệu tham khảo:

    • https://swapps.com/blog/how-to-configure-virtualenvwrapper-with-python3-in-osx-mojave/
  • Media Player (Part2) – Add Record function vào IJKPlayer trên Android

    Media Player (Part2) – Add Record function vào IJKPlayer trên Android

    Điểm mạnh của IJKPlayer là low latency, nó có độ trễ khá thấp khi streaming, nhưng giả sử phát sinh tình huống cần record một đoạn video khi đang streaming thì phải làm thế nào? IJKPlayer không support sẵn.

    Sau khi tham khảo 1 số blog của các bạn…..Trung Quốc và build được thành công thì mình share lại thông tin cho ai cần(vâng, ko hiểu tại sao cứ liên quan đến video, camera,Streaming thì tài liệu chỉ có thể tìm thấy bên….Trung Quốc. Không phủ nhận, các bạn ý giỏi thật  )

    Trước hết, các bạn cần build được IJKPlayer cho Android đã nhé, cụ thể có thể xem link bên dưới

    OK, Sau khi các bạn biết cách chuẩn bị môi trường và build thành công, chúng ta cần tiến hành chỉnh sửa một chút trong thư viện IJKplayer(Mình sẽ không đề cập đến vấn đề pháp lý, licence ở đây)

    Chúng ta cần check out source code và build thử nhé

    git clone https://github.com/baka3k/IjkPlayerRecorder.git
    cd IjkPlayerRecorder
    // Khởi tạo project build cho Android
    ./init-android.sh
    //IJKPlayer có sử dụng ffmpeg - nên việc build ffmpeg là bắt buộc
    cd android/contrib
    ./compile-ffmpeg.sh clean
    ./compile-ffmpeg.sh all
    
    //quay lại thư mục IJK và build IJKPlayer
    cd ..
    ./compile-ijk.sh all

    Nếu thành công – tức là bạn đã setup đầy đủ, có thể build IJKPlayer được, sẵn sàng cho việc thêm code để thêm chức năng recorder cho IJKPlayer.

    Tiếp tục nhé

    1.Trong thư mục ijkmedia/ijkplayer bạn tìm đến file ff_ffplay.h và khai báo các hàm sau:

    Refer:

    https://github.com/baka3k/IjkPlayerRecorder/blob/master/ijkmedia/ijkplayer/ff_ffplay.h
    /* record rtsp streaming */
    int ffp_start_recording_l(FFPlayer *ffp, const char *file_name);
    int ffp_record_isfinished_l(FFPlayer *ffp);
    int ffp_stop_recording_l(FFPlayer *ffp);
    void ffp_get_current_frame_l(FFPlayer *ffp, uint8_t *frame_buf);

    2.Trong file ff_ffplay.c chúng ta định nghĩa nội dung thân hàm cho 4 function này

    Refer:

    https://github.com/baka3k/IjkPlayerRecorder/blob/master/ijkmedia/ijkplayer/ff_ffplay.c
    int ffp_start_recording_l(FFPlayer *ffp, const char *file_name)
    {
    assert(ffp);
    VideoState *is = ffp->is;
    
    ffp->m_ofmt_ctx = NULL;
    ffp->m_ofmt = NULL;
    ffp->is_record = 0;
    ffp->record_error = 0;
    
    if (!file_name || !strlen(file_name)) {
    av_log(ffp, AV_LOG_ERROR, "filename is invalid");
    goto end;
    }
    
    if (!is || !is->ic || is->paused || is->abort_request) {
    av_log(ffp, AV_LOG_ERROR, "is,is->ic,is->paused is invalid");
    goto end;
    }
    
    if (ffp->is_record) {
    av_log(ffp, AV_LOG_ERROR, "recording has started");
    goto end;
    }
    
    avformat_alloc_output_context2(&ffp->m_ofmt_ctx, NULL, NULL, file_name);
    if (!ffp->m_ofmt_ctx) {
    av_log(ffp, AV_LOG_ERROR, "Could not create output context filename is %s\n", file_name);
    goto end;
    }
    ffp->m_ofmt = ffp->m_ofmt_ctx->oformat;
    
    for (int i = 0; i < is->ic->nb_streams; i++) {
    AVStream *in_stream = is->ic->streams[i];
    AVStream *out_stream = avformat_new_stream(ffp->m_ofmt_ctx, in_stream->codec->codec);
    if (!out_stream) {
    av_log(ffp, AV_LOG_ERROR, "Failed allocating output stream\n");
    goto end;
    }
    
    av_log(ffp, AV_LOG_DEBUG, "in_stream->codec;%p\n", in_stream->codec);
    if (avcodec_copy_context(out_stream->codec, in_stream->codec) < 0) {
    av_log(ffp, AV_LOG_ERROR, "Failed to copy context from input to output stream codec context\n");
    goto end;
    }
    
    out_stream->codec->codec_tag = 0;
    if (ffp->m_ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER) {
    out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
    }
    }
    
    av_dump_format(ffp->m_ofmt_ctx, 0, file_name, 1);
    
    if (!(ffp->m_ofmt->flags & AVFMT_NOFILE)) {
    if (avio_open(&ffp->m_ofmt_ctx->pb, file_name, AVIO_FLAG_WRITE) < 0) {
    av_log(ffp, AV_LOG_ERROR, "Could not open output file '%s'", file_name);
    goto end;
    }
    }
    
    if (avformat_write_header(ffp->m_ofmt_ctx, NULL) < 0) {
    av_log(ffp, AV_LOG_ERROR, "Error occurred when opening output file\n");
    goto end;
    }
    
    ffp->is_record = 1;
    ffp->record_error = 0;
    pthread_mutex_init(&ffp->record_mutex, NULL);
    
    return 0;
    end:
    ffp->record_error = 1;
    return -1;
    }
    
    int ffp_record_isfinished_l(FFPlayer *ffp)
    {
    return 0;
    }
    
    int ffp_record_file(FFPlayer *ffp, AVPacket *packet)
    {
    assert(ffp);
    VideoState *is = ffp->is;
    int ret = 0;
    AVStream *in_stream;
    AVStream *out_stream;
    
    if (ffp->is_record) {
    if (packet == NULL) {
    ffp->record_error = 1;
    av_log(ffp, AV_LOG_ERROR, "packet == NULL");
    return -1;
    }
    
    AVPacket *pkt = (AVPacket *)av_malloc(sizeof(AVPacket));
    av_new_packet(pkt, 0);
    if (0 == av_packet_ref(pkt, packet)) {
    pthread_mutex_lock(&ffp->record_mutex);
    if (!ffp->is_first) {
    ffp->is_first = 1;
    pkt->pts = 0;
    pkt->dts = 0;
    } else {
    if (pkt->stream_index == AVMEDIA_TYPE_AUDIO) {
    pkt->pts = llabs(pkt->pts - ffp->start_a_pts);
    pkt->dts = llabs(pkt->dts - ffp->start_a_dts);
    }
    else if (pkt->stream_index == AVMEDIA_TYPE_VIDEO) {
    pkt->pts = pkt->dts = llabs(pkt->dts - ffp->start_v_dts);
    }
    }
    
    in_stream = is->ic->streams[pkt->stream_index];
    out_stream = ffp->m_ofmt_ctx->streams[pkt->stream_index];
    
    pkt->pts = av_rescale_q_rnd(pkt->pts, in_stream->time_base, out_stream->time_base, (AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
    pkt->dts = av_rescale_q_rnd(pkt->dts, in_stream->time_base, out_stream->time_base, (AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
    pkt->duration = av_rescale_q(pkt->duration, in_stream->time_base, out_stream->time_base);
    pkt->pos = -1;
    
    if ((ret = av_interleaved_write_frame(ffp->m_ofmt_ctx, pkt)) < 0) {
    av_log(ffp, AV_LOG_ERROR, "Error muxing packet\n");
    }
    
    av_packet_unref(pkt);
    pthread_mutex_unlock(&ffp->record_mutex);
    } else {
    av_log(ffp, AV_LOG_ERROR, "av_packet_ref == NULL");
    }
    }
    return ret;
    }
    
    int ffp_stop_recording_l(FFPlayer *ffp){
    assert(ffp);
    if (ffp->is_record) {
    ffp->is_record = 0;
    pthread_mutex_lock(&ffp->record_mutex);
    if (ffp->m_ofmt_ctx != NULL) {
    av_write_trailer(ffp->m_ofmt_ctx);
    if (ffp->m_ofmt_ctx && !(ffp->m_ofmt->flags & AVFMT_NOFILE)) {
    avio_close(ffp->m_ofmt_ctx->pb);
    }
    avformat_free_context(ffp->m_ofmt_ctx);
    ffp->m_ofmt_ctx = NULL;
    ffp->is_first = 0;
    }
    pthread_mutex_unlock(&ffp->record_mutex);
    pthread_mutex_destroy(&ffp->record_mutex);
    av_log(ffp, AV_LOG_DEBUG, "stopRecord ok\n");
    } else {
    av_log(ffp, AV_LOG_ERROR, "don't need stopRecord\n");
    }
    return 0;
    }
    void ffp_get_current_frame_l(FFPlayer *ffp, uint8_t *frame_buf)
    {
    ALOGD("=============>start snapshot\n");
    
    VideoState *is = ffp->is;
    Frame *vp;
    int i = 0, linesize = 0, pixels = 0;
    uint8_t *src;
    
    vp = &is->pictq.queue[is->pictq.rindex];
    int height = vp->bmp->h;
    int width = vp->bmp->w;
    
    ALOGD("=============>%d X %d === %d\n", width, height, vp->bmp->pitches[0]);
    
    // copy data to bitmap in java code
    linesize = vp->bmp->pitches[0];
    src = vp->bmp->pixels[0];
    pixels = width * 4;
    for (i = 0; i < height; i++)
    {
    memcpy(frame_buf + i * pixels, src + i * linesize, pixels);
    }
    ALOGD("=============>end snapshot\n");
    }

    3. Define thêm các cấu trúc dữ liệu cần thiết trong ff_ffplay_def.h

    Refer(line 724->733)

    https://github.com/baka3k/IjkPlayerRecorder/blob/master/ijkmedia/ijkplayer/ff_ffplay_def.h
    AVFormatContext *m_ofmt_ctx;
    AVOutputFormat *m_ofmt;
    pthread_mutex_t record_mutex;
    int is_record;
    int record_error;
    int is_first;
    int64_t start_v_pts;
    int64_t start_v_dts;
    int64_t start_a_pts;
    int64_t start_a_dts;

    4. Define thêm hàm record trong ijkplayer.c(đây chính là class player mà chúng ta sẽ phải viết thêm JNI để câu xuống)

    Define hàm vào header file ijkplayer.h

    Refer

    https://github.com/baka3k/IjkPlayerRecorder/blob/master/ijkmedia/ijkplayer/ijkplayer.h
    int ijkmp_start_recording(IjkMediaPlayer *mp, const char *filePath);
    int ijkmp_stop_recording(IjkMediaPlayer *mp);
    int ijkmp_isRecording(IjkMediaPlayer *mp);
    void ijkmp_get_current_frame(IjkMediaPlayer *mp,uint8_t *frame_buf);

    Viết thân hàm vào ijkplayer.c

    Refer

    https://github.com/baka3k/IjkPlayerRecorder/blob/master/ijkmedia/ijkplayer/ijkplayer.c
    static int ijkmp_start_recording_l(IjkMediaPlayer *mp, const char *filePath)
    {
    av_log(mp->ffplayer,AV_LOG_INFO,"cjz ijkmp_start_recording_l filePath %s",filePath);
    return ffp_start_recording_l(mp->ffplayer, filePath);
    }
    
    int ijkmp_start_recording(IjkMediaPlayer *mp,const char *filePath)
    {
    assert(mp);
    pthread_mutex_lock(&mp->mutex);
    av_log(mp->ffplayer,AV_LOG_WARNING,"cjz ijkmp_start_recording --- ");
    int retval = ijkmp_start_recording_l(mp,filePath);
    printf("ijkmp_start_recording return == %d\n",retval);
    pthread_mutex_unlock(&mp->mutex);
    return retval;
    }
    
    static int ijkmp_stop_recording_l(IjkMediaPlayer *mp)
    {
    return ffp_stop_recording_l(mp->ffplayer);
    }
    
    int ijkmp_stop_recording(IjkMediaPlayer *mp)
    {
    assert(mp);
    pthread_mutex_lock(&mp->mutex);
    av_log(mp->ffplayer,AV_LOG_WARNING,"cjz ijkmp_stop_recording");
    int retval = ijkmp_stop_recording_l(mp);
    pthread_mutex_unlock(&mp->mutex);
    return retval;
    }
    
    static int ijkmp_isRecordFinished_l(IjkMediaPlayer *mp)
    {
    return ffp_record_isfinished_l(mp->ffplayer);
    }
    
    int ijkmp_isRecordFinished(IjkMediaPlayer *mp)
    {
    assert(mp);
    pthread_mutex_lock(&mp->mutex);
    av_log(mp->ffplayer,AV_LOG_WARNING,"cjz ijkmp_isRecordFinished ");
    int retval = ijkmp_isRecordFinished_l(mp);
    pthread_mutex_unlock(&mp->mutex);
    return retval;
    }
    
    int ijkmp_isRecording(IjkMediaPlayer *mp) {
    return mp->ffplayer->is_record;
    }
    void ijkmp_get_current_frame(IjkMediaPlayer *mp,uint8_t *frame_buf){
    ffp_get_current_frame_l(mp->ffplayer,frame_buf);
    }

    5. Cuối cùng, update thêm JNI để có thể call được từ tầng java xuống C nhé

    Refer:

    https://github.com/baka3k/IjkPlayerRecorder/blob/master/ijkmedia/ijkplayer/android/ijkplayer_jni.c

    Các bạn tìm đến đường dẫn IjkPlayerRecorder/ijkmedia/ijkplayer/android/ijkplayer_jni.c

    Và thêm vào

    static jint
    IjkMediaPlayer_startRecord(JNIEnv *env, jobject thiz,jstring file)
    {
    jint retval = 0;
    IjkMediaPlayer *mp = jni_get_media_player(env, thiz);
    JNI_CHECK_GOTO(mp, env, NULL, "mpjni: startRecord: null mp", LABEL_RETURN);
    const char *nativeString = (*env)->GetStringUTFChars(env, file, 0);
    retval = ijkmp_start_recording(mp,nativeString);
    
    LABEL_RETURN:
    ijkmp_dec_ref_p(&mp);
    return retval;
    }
    
    static jint
    IjkMediaPlayer_stopRecord(JNIEnv *env, jobject thiz)
    {
    jint retval = 0;
    IjkMediaPlayer *mp = jni_get_media_player(env, thiz);
    JNI_CHECK_GOTO(mp, env, NULL, "mpjni: stopRecord: null mp", LABEL_RETURN);
    
    retval = ijkmp_stop_recording(mp);
    
    LABEL_RETURN:
    ijkmp_dec_ref_p(&mp);
    return retval;
    }
    
    static jboolean
    IjkMediaPlayer_getCurrentFrame(JNIEnv *env, jobject thiz, jobject bitmap)
    {
    jboolean retval = JNI_TRUE;
    IjkMediaPlayer *mp = jni_get_media_player(env, thiz);
    JNI_CHECK_GOTO(mp, env, NULL, "mpjni: getCurrentFrame: null mp", LABEL_RETURN);
    
    uint8_t *frame_buffer = NULL;
    
    if (0 > AndroidBitmap_lockPixels(env, bitmap, (void **)&frame_buffer)) {
    (*env)->ThrowNew(env, "java/io/IOException", "Unable to lock pixels.");
    return JNI_FALSE;
    }
    
    ijkmp_get_current_frame(mp, frame_buffer);
    
    if (0 > AndroidBitmap_unlockPixels(env, bitmap)) {
    (*env)->ThrowNew(env, "java/io/IOException", "Unable to unlock pixels.");
    return JNI_FALSE;
    }
    
    LABEL_RETURN:
    ijkmp_dec_ref_p(&mp);
    return retval;
    }

    6. Chỉnh sửa các function để JNI map với java

    Trong file ijkplayer_jni.c, tìm đến line 1190 có đoạn define

    static JNINativeMethod g_methods[] = {....

    Add thêm

    { "startRecord", "(Ljava/lang/String;)I", (void *) IjkMediaPlayer_startRecord },
    { "stopRecord", "()I", (void *) IjkMediaPlayer_stopRecord },
    { "getCurrentFrame", "(Landroid/graphics/Bitmap;)Z", (void *) IjkMediaPlayer_getCurrentFrame },

    Refer

    https://github.com/baka3k/IjkPlayerRecorder/blob/master/ijkmedia/ijkplayer/android/ijkplayer_jni.c

    Việc update code đến đây là OK

    Chúng ta build lại IJKPlayer

    cd android/contrib
    ./compile-ffmpeg.sh clean
    ./compile-ffmpeg.sh all
    
    cd ..
    ./compile-ijk.sh all

    Chờ đợi khá lâu đấy, nếu build lần đầu tiên có khả năng mất 1 tiếng :(, sau khi kết thúc build các bạn sẽ tìm thấy các file .so trong thư mục

    - /IjkPlayerRecorder/android/ijkplayer/ijkplayer-armv7a/src/main/libs/armeabi-v7a
    - /IjkPlayerRecorder/android/ijkplayer/ijkplayer-armv5/src/main/libs/armeabi
    - /IjkPlayerRecorder/android/ijkplayer/ijkplayer-arm64/src/main/libs/arm64-v8a

    Copy các file SO này vào project sample

    IjkPlayerRecorder/android/ijkplayer/ijkplayer-example
    

    và thử thôi

  • Missing pieces for developers using macOS

    Missing pieces for developers using macOS

    Homebrew (The missing package manager for macOS)

    • Homebrew là package manager rất có ích cho macOS, nó giúp bạn cài đặt các thư viện, ngôn ngữ, framework… rất nhanh và dễ dàng.
    • Ưu điểm của Homebrew đó là bạn chỉ cần gõ câu lệnh để cài đặt package mà được Homebrew support, sau đó nó sẽ tự động download, check các dependencies (các package cần phải có trước khi cài đặt package mình mong muốn), nếu chưa có nó sẽ download và install dependencies trước, rồi sẽ install package mà bạn muốn cài
    • Ngoài ra thì Homebrew cũng cài đặt các package lên máy trong folder riêng của nó, sau đó mới link sang thư mục /usr/local, việc này sẽ đảm bảo môi trường default trên máy bạn không bị ảnh hưởng.
    • Homebrew cũng đảm bảo các package luôn được up-to-date. Điều này chắc chắn là tiết kiệm cho bạn rất nhiều thời gian.
    • Ngoài ra, bạn có thể cài đặt các application trên macOS bằng cách sử dụng Homebrew Cask. (No more download, no more .dmg)

    Oh my zsh

    • Các developer sử dụng macOS và các OS Linux khác chắc hẳn rằng không còn xa lạ gì với bash, có thể nói rằng bash chính là một phần không thể thiếu trong công việc hàng ngày. Khi bạn mở Terminal lên, gõ câu lệnh và OS thực thi nó, vậy là bạn đã sử dụng bash.
    • Vậy bash là gì?
      • bash (Bourne-Again SHell) thực chất là các shell, hay còn gọi là command-line interpreter hoặc command language interpreter (CLI). Nó cho phép người dùng sử dụng các câu lệnh dạng text để gọi đến các service của OS (kernel), qua đó thực thi các câu lệnh của người dùng.
      • bash là shell mặc định trên các OS như macOS, Linux. Ngoài việc nhận lệnh trực tiếp từ user thông qua các ứng dụng như Terminal thì bash còn có thể thực thi lệnh thông qua file được gọi là shell script.
    • zsh là gì?
      • zsh cũng giống như bash, nhưng nó được thiết kế nhằm mục đích phục vụ cho việc tương tác với người dùng (thực hiện  lệnh mà người dùng input vào). zsh cũng “học hỏi” rất nhiều tính năng từ bash, ksh, tcsh ngoài những tính năng nó có sẵn, đem đến cho người dùng một bộ công cụ mạnh mẽ khi làm việc với shell.
      • Những điểm thú vị khi so sánh zsh với bash
        • muốn thay đổi directory thì chỉ cần gõ tên directory, không cần thêm cd ở đầu
        • ls *.(h|m) : list tất cả các file có đuôi .h hoặc .m trong folder
        • completing command options: example git — + tab => liệt kê các options tương ứng với command vừa gõ.
        • hiển thị thời điểm gõ câu lệnh RPROMPT=”%t”

    oh-my-zsh

    • Không dừng lại ở zsh, cộng đồng developers đã tạo ra oh-my-zsh, một framework thú vị, giúp người dùng không còn cảm thấy nhàm chán mỗi khi làm việc với command line.
    • oh-my-zsh có gì thú vị?
      • Có bộ plugin khổng lồ cho các công cụ, ngôn ngữ và framework mà bạn hay dùng như: aws, docker, git, rails, laravel, npm, osx, python… Nó giúp bạn có thể autocomplete câu lệnh hoặc cung cấp các alias ngắn gọn, giúp rút ngắn thời gian gõ lệnh.
      • Cung cấp các bộ theme đẹp và tiện dụng cho terminal, một terminal màu mè với các symbol hiển thị phù hợp sẽ đỡ nhàm chán hơn rất nhiều so với một terminal đen trắng.
      • Bạn có thể trở thành contributor để cung cấp những plugin do chính mình viết.
    • Install oh-my-zsh
      • Mở terminal, paste câu lệnh sau và nhấn enter:
        1. sh -c “$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)”
      • Config plugin cho on-my-zsh
        1. Mở file ~/.zshrc
        2. Tìm đến dòng plugins=(…) và add plugin cho phù hợp với nhu cầu. Ví dụ muốn dùng plugin git, macos, aws, docker thì chỉnh sửa thành:
          1. plugins=(git osx aws docker)
        3. Restart terminal
      • Kết quả:
        1. Ví dụ, trước đây khi muốn show hidden file trong macOS thì cần phải gõ
          1. defaults write com.apple.finder AppleShowAllFiles -bool TRUE
          2. killall Finder 
        2. Sau khi dùng plugin osx thì chỉ cần gõ
          1. showfiles / hidefiles để hiện và ẩn hidden file (hidden file là những file có tên bắt đầu bằng dấu .)
    • Install theme cho on-my-zsh
      • Mở file ~/.zshrc
      • Điền tên theme vào sau ZSH_THEME=, ví dụ ZSH_THEME=”robbyrussell”

    iTerm2

    • App Terminal, default của macOS có thể thực hiện tốt các nhiệm vụ khi người dùng muốn làm việc với shell. Tuy nhiên, nếu bạn thực sự muốn một app có tính tuỳ biến cao, nhiều tính năng thú vị hỗ trợ thì nên thử qua app iTerm2.
    • Một vài tính năng thú vị của iTerm2:
      • Split panels: tính năng này cho phép bạn chia tab hiện tại của iTerms ra thành các “panel” khác nhau, mỗi panel là một section riêng biệt. Rất có ích khi làm việc mà cần phải tham chiếu kết quả giữa các section với nhau.
      • Search: tính năng search trên iTerm2 có sự khác biệt khi so sánh với Terminal, iTerm2 highlight tất cả các kết quả phù hợp với điều kiện search, ngoài ra nó còn hỗ trợ cả search theo regular expression.
      • Autocomplete: với những câu lệnh bạn đã từng gõ trong iTerm, thì lần sau chỉ cần gõ vài ký tự đầu và nhấn tổ hợp phím Cmd + ; thì iTerm sẽ liệt kê lịch sử các câu lệnh đã gõ tương ứng cho bạn lựa chọn.

    ref: