2014-10-30 10 views
6

Tôi đang cố gắng sử dụng python trong một ứng dụng OS X mới cho tập lệnh plugin. Tôi đang tìm cách để offload một số logic chương trình để python cho dễ dàng, on-the-fly sửa đổi. Tôi đã bắt đầu bằng cách xem số Big Nerd Ranch tutorial. Điều đó dường như hoạt động, nhưng nó gợi ý một phương pháp kết nối Python cũ hơn. Có vẻ như từ Xcode 5, chúng ta phải cài đặt python bằng cách sử dụng this Mac Developer Library Tech Note. Tuy nhiên, quá trình này dường như tạo ra một cá thể python được liên kết, không phải là một cá thể nhúng. Tôi đã thử làm theo các hướng dẫn trong các answer to this question nhưng có vẻ như để phá vỡ. Vì vậy, câu hỏi của tôi là: thực hành tốt nhất hiện nay để xây dựng python để sử dụng như một thời gian chạy plugin trong một ứng dụng Objective C Mac OS X là gì? Làm thế nào để đảm bảo rằng nó đi kèm với ứng dụng và có thể cài đặt bất kỳ thư viện bổ sung nào mà một người có thể muốn trước khi ứng dụng Objective C cuối cùng được xây dựng?Làm thế nào để nhúng python vào một ứng dụng Objective-C OS X cho các plugin?

+2

Có gì sai khi liên kết với khung công tác Python đi kèm với OS X? – mipadi

+0

Khuôn khổ Python đi kèm với OS X chạy python2.7. Tôi thích sử dụng python3 hơn. Ngoài ra, làm thế nào tôi sẽ kết hợp một mô-đun phi tiêu chuẩn vào plugin? Sẽ không muốn phải cài đặt các mô-đun python toàn hệ thống chỉ để cài đặt một ứng dụng Cocoa gốc. –

Trả lời

10

Tôi đã đưa ra một phương pháp có vẻ hoạt động khá tốt.

Trước tiên, tải xuống mã nguồn của phiên bản python bạn muốn sử dụng từ official website. Giải nén tệp lưu trữ ở đâu đó. Tôi đang sử dụng Python 3.4.2. Điều chỉnh các lệnh trên hệ thống của bạn cho phiên bản cụ thể mà bạn đang sử dụng.

Tạo thư mục xây dựng mà bạn sẽ sử dụng cho phiên bản python phát triển này. Toàn bộ thư mục sẽ không có dấu cách trong đó để đảm bảo rằng bash diễn giải chính xác các dòng she-bang (#!). Tôi đã sử dụng /Users/myaccount/development/python/devbuild/python3.4.2.

Đi vào thư mục Python chiết xuất và chạy các lệnh sau:

./configure --prefix="/Users/myaccount/development/python/devbuild/python3.4.2" 
make 
make install 

này sẽ cài đặt python trong đó phát triển xây dựng thư mục. Thiết lập các đường Python để sử dụng thư mục chính xác:

export PYTHONPATH="/Users/myaccount/development/python/devbuild/python3.4.2/lib/python3.4/site-packages/" 

Đi vào thư mục python bin (/Users/myaccount/development/python/devbuild/python3.4.2/bin) và sử dụng pip3 đó để cài đặt bất kỳ module mà bạn cần. Cài đặt $PYTHONPATH sẽ đảm bảo rằng các mô-đun được cài đặt vào đúng thư mục site-packages.

Tìm nhà tiện dụng cho kho lưu trữ PyObjC và sao chép tại đó. Sau đó kiểm tra các thẻ phiên bản mới nhất và cài đặt nó, và đảm bảo rằng $PYTHONPATH của bạn vẫn đúng:

hg clone https://bitbucket.org/ronaldoussoren/pyobjc 
cd pyobjc 
hg tags 
hg checkout [the id of the latest version from the tag list] 
/Users/myaccount/development/python/devbuild/python3.4.2/bin/python3 ./install.py 

Bất cứ khi nào bạn cần cập nhật các module python, chỉ cần đảm bảo sử dụng bin python chính xác và $PYTHONPATH.

Bây giờ hãy thêm python vào dự án Xcode.

Kéo thư mục /Users/myaccount/development/python/devbuild/python3.4.2 vào dự án Xcode, đặt thư mục đó để không sao chép các mục nếu cần và để tạo tham chiếu thư mục.

Thêm /Users/myaccount/development/python/devbuild/python3.4.2/include/python3.4m vào cài đặt Header Search Paths trong dự án Xcode Build Settings. Không chắc chắn nếu có một cách để làm điều này như là một bước tổng quát để chỉ tìm kiếm thư mục tham chiếu thư mục mà chúng tôi vừa thêm vào.

Kéo thư mục `/Users/myaccount/development/python/devbuild/python3.4.2/lib/libpython3.4m.a vào dự án Xcode, thiết lập nó để được thêm làm tham chiếu mà không cần sao chép.

Mã từ Big Nerd Ranch scripting tutorial repository hiện có thể được sử dụng với một vài sửa đổi.

Mã Giám đốc Plugin sẽ cần một phần mở rộng NSString để làm việc với các wchar_t chuỗi API Python có vẻ như rất nhiều:

@interface NSString (WcharEncodedString) 

- (wchar_t*) getWideString; 

@end 

@implementation NSString (WcharEncodedString) 

- (wchar_t*) getWideString { 
    const char* tmp = [self cStringUsingEncoding:NSUTF8StringEncoding]; 
    unsigned long buflen = strlen(tmp) + 1; 
    wchar_t* buffer = malloc(buflen * sizeof(wchar_t)); 
    mbstowcs(buffer, tmp, buflen); 
    return buffer; 
} 

@end 

Tiêu đề Python nên được bao gồm như sau:

#include "Python.h" 

Mã sau cần được chạy trước khi Py_Initialize() được gọi để thiết lập tệp thực thi python chính xác, PYTHONPATH và PYTHONHOME theo đề xuất của Zorg về câu hỏi khác.

NSString* executablePath = [[NSBundle mainBundle] pathForResource:@"python3.4" ofType:nil inDirectory:@"python3.4.2/bin"]; 
Py_SetProgramName([executablePath getWideString]); 

NSString* pythonDirectory = [[NSBundle mainBundle] pathForResource:@"python3.4" ofType:nil inDirectory:@"python3.4.2/lib"]; 
Py_SetPath([pythonDirectory getWideString]); 
Py_SetPythonHome([pythonDirectory getWideString]); 

Cuối cùng, con đường python cần phải được mở rộng trong file PluginExecutor.py để bao gồm các thư mục con khác nhau về mức độ cao đường lib. Thêm mã sau vào đầu tệp Trình xử lý tệp plugin:

import sys 
from os import walk 
path = sys.path.copy() 
for p in path: 
    for root,dirs,files in walk(p): 
     if p is not root: 
      sys.path.append(root) 

Tôi sẽ đăng cập nhật nếu mọi thứ bắt đầu bị hỏng, nhưng đây có vẻ là giải pháp làm việc ngay bây giờ.

+1

Cảm ơn bạn đã giải thích kỹ lưỡng. +1 –

+1

Bạn có thể cập nhật điều này cho Swift không? – qed

Các vấn đề liên quan