Criollo

其他类别 2025-08-23

Criollo

用于Mac,iOS和TVO的功能强大的可可网络框架和HTTP服务器。

Criollo帮助创建快速的独立或嵌入式Web应用程序,这些应用程序直接通过HTTP或FastCGI传递内容。您可以在Swift或Objective-C中编写代码,并且可以使用您已经知道的可可技术。

就像这样很容易:

 let server = CRHTTPServer ( )
server . get ( " / " ) { ( req , res , next ) in
  res . send ( " Hello world! " )
}
server . startListening ( )

...在Objective-C中:

CRServer* server = [[CRHTTPServer alloc ] init ];
[server get: @" / " block: ^(CRRequest *req, CRResponse *res, CRRouteCompletionBlock next) {
  [res send: @" Hello world! " ];
}];
[server startListening ];

关键功能

Criollo的设计牢记了速度,安全性和灵活性,这就是为什么它包含一些非常有用的功能,从而使您可以专注于项目需要做的实际工作,而无需跳过篮球即可实现它的实现。

https

Criollo完全支持所有平台上的HTTP。您可以将凭据作为PKCS#12身份和密码或X509证书和私钥对(PEM或DER编码)传递。

server . isSecure = true

// Credentials: PKCS#12 Identity and password
server . identityPath = Bundle . main . path ( forResource : " identity " , ofType : " p12 " )
server . password = " 123456 "

// Credentials: PEM-encoded certificate and public key
server . certificatePath = Bundle . main . path ( forResource : " certificate " , ofType : " pem " )
server . privateKeyPath = Bundle . main . path ( forResource : " key " , ofType : " pem " )

// Credentials: DER-encoded certificate and public key
server . certificatePath = Bundle . main . path ( forResource : " certificate " , ofType : " der " )
server . privateKeyPath = Bundle . main . path ( forResource : " key " , ofType : " der " )

...在Objective-C中:

server.isSecure = YES ;
        
// Credentials: PKCS#12 Identity and password
server.identityPath = [ NSBundle .mainBundle pathForResource: @" identity " ofType: @" p12 " ];
server.password = @" password " ;
        
// Credentials: PEM-encoded certificate and public key
server.certificatePath = [ NSBundle .mainBundle pathForResource: @" certificate " ofType: @" pem " ];
server.privateKeyPath = [ NSBundle .mainBundle pathForResource: @" key " ofType: @" pem " ];
        
// Credentials: DER-encoded certificate and public key
server.certificatePath = [ NSBundle .mainBundle pathForResource: @" certificate " ofType: @" der " ];
server.privateKeyPath = [ NSBundle .mainBundle pathForResource: @" key " ofType: @" der " ];

路由

定义路线时,可以通过三种方式指定路径:

  • 固定字符串(ex。 /api )。这将完全匹配字符串。
  • 占位符(例如/posts/:pid )。 /posts之后的下一个路径组件将匹配并添加到request.querypid
  • REGEX模式(例如/[0-9]{4}/[0-9]{1,2}/[a-zA-Z0-9-]+ )。 1三个模式匹配时,将它们0添加到request.query2
Criollo-app res.send(req.query) }">
server . add ( " /api " ) { ( req , res , next ) in
  // /api/?pid=12345
  res . send ( req . query )
}

server . add ( " /posts/:pid " ) { ( req , res , next ) in
  // /posts/12345
  res . send ( req . query )
}

server . add ( " /[0-9]{4}/[0-9]{1,2}/[a-zA-Z0-9-]+ " ) { ( req , res , next ) in
  // /2017/10/my-first- Criollo -app
  res . send ( req . query )
}

...在Objective-C中:

Criollo-app [res send:req]; }];">
[server add: @" /api " block: ^(CRRequest *req, CRResponse *res, CRRouteCompletionBlock next) {
  // /api/?pid=12345
  [res send: req];
}];

[server add: @" /posts/:pid " block: ^(CRRequest *req, CRResponse *res, CRRouteCompletionBlock next) {
  // /posts/12345
  [res send: req];
}];

[server add: @" /[0-9]{4}/[0-9]{1,2}/[a-zA-Z0-9-]+ " block: ^(CRRequest *req, CRResponse *res, CRRouteCompletionBlock next) {
  // /2017/10/my-first- Criollo -app
  [res send: req];
}];

控制器

控制器提供了将功能分组为一个语义单元的非常简单的方法。它们充当路由器,允许您根据路径相对于其本身所处的路径来定义路线。

// The controller class
class APIController : CRRouteController {
  override init ( prefix : String ) {
    super . init ( prefix : prefix )
    
    self . add ( " /status " ) { ( req , res , next ) in
      res . send ( [ " status " : true ] )
    }
    
  }
}

// Add the controller to the server
server . add ( " /api " , controller : APIController . self )

...在Objective-C中:

 // The controller class
@interface APIController : CRRouteController
@end

@implementation APIController

- ( instancetype ) initWithPrefix : ( NSString *) prefix {
  self = [ super initWithPrefix: prefix];
  if ( self != nil ) {
    
    [ self add: @" /status " block: ^(CRRequest *req, CRResponse *res, CRRouteCompletionBlock next) {
      [res send: @{ @" status " : @ YES }];
    }];
         
  }
}

@end

// Add the controller to the server
[server add: @" /api " controller: APIController.class];

查看和查看控制器

查看控制器渲染视图对象,该对象通过调用视图的render方法来从HTML资源文件构建。这是由CRViewConrollerCRViewCRNib API实现的。

视图控制器是强大的对象,可让您轻松地将应用程序的外观和组功能一起标准化为连贯的单元。

HTML模板文件:

 
>
  < html lang =" en " >
  < head >
    < title > {{title}}  title >
   head >
  < body >
    < h1 > {{title}}  h1 >
    < p > {{content}}  p >
   body >
 html >

源代码:

// The view controller class
class HelloWorldViewController : CRViewController {
  
  override func present ( with request : CRRequest , response : CRResponse ) -> String {
    self . vars [ " title " ] = String ( describing : type ( of : self ) )
    self . vars [ " content " ] = " Hello from the view controller. "

    return super . present ( with : request , response : response )
  }  
}

// Add the view controller to server
server . add ( " /controller " , viewController : HelloWorldViewController . self , withNibName : " HelloWorldViewController " , bundle : nil )

...在Objective-C中:

 // The view controller class
@interface HelloWorldViewController : CRViewController
@end

@implementation HelloWorldViewController

- ( NSString *) presentViewControllerWithRequest : (CRRequest *) request response : (CRResponse *) response {
    self. vars [ @" title " ] = NSStringFromClass (self. class );
    self. vars [ @" content " ] = @" Hello from the view controller. " ;

    return [ super presentViewControllerWithRequest: request response: response];
}

@end

// Add the view controller to server
[server add: @" /controller " viewController: HelloWorldViewController.class withNibName: @" HelloWorldViewController " bundle: nil ];

静态文件/目录服务

Criollo具有内置的支持,以公开目录和个人HTTP的个人。 CRStaticFileManagerCRStaticDirectoryManager API使您能够执行此操作。

// Expose the home directory (with auto-indexing)
server . mount ( " /pub " , directoryAtPath : " ~ " , options : [ . autoIndex ] )

// Serve a single static file at a path
server . mount ( " /info.plist " , fileAtPath :  Bundle . main . bundlePath . appending ( " /Info.plist " ) )

...在Objective-C中

 // Expose the home directory (with auto-indexing)
[server mount: @" /pub " directoryAtPath: @" ~ " options: CRStaticDirectoryServingOptionsAutoIndex];
   
// Serve a single static file at a path 
[server mount: @" /info.plist " fileAtPath: [ NSBundle .mainBundle.bundlePath stringByAppendingPathComponent: @" /Contents/Info.plist " ]];

多部分文件上传

Criollo附带了用于处理multipart/form-data Post请求的内置支持,因此您可以从包装盒中处理HTML文件上传。在request.files中提供上传的文件,作为CRUploadedFile对象的数组。

// Serve the first uploaded file back to the client
self . server . post ( " /image " ) { ( req , res , next ) in
  do {
    let data = try Data . init ( contentsOf : ( req . files! [ " 0 " ] ? . temporaryFileURL ) ! )
    res . setValue ( req . env [ " HTTP_CONTENT_TYPE " ] ! , forHTTPHeaderField : " Content-type " )
    res . setValue ( " ( data . count ) " , forHTTPHeaderField : " Content-Length " )
    res . send ( data )
  } catch {
    res . setValue ( " text/plain " , forHTTPHeaderField : " Content-type " )
    res . setValue ( " ( error . localizedDescription . count ) " , forHTTPHeaderField : " Content-length " )
    res . send ( error . localizedDescription )
  }
}

...在Objective-C中

 // Serve the first uploaded file back to the client
[server post: @" /image " block: ^(CRRequest *req, CRResponse *res, CRRouteCompletionBlock next) {
  NSError *error;
  NSData *data = [ NSData dataWithContentsOfURL: req[ 0 ].temporaryFileURL options: 0 error: &error];
  if ( error ) {
    [res setValue: @" text/plain " forHTTPHeaderField: @" Content-type " ];
    [res setValue: @(error.description.length).stringValue forHTTPHeaderField: @" Content-length " ];
    [res sendString: error.description];
  } else {
    [res setValue: request.env[ @" HTTP_CONTENT_TYPE " ] forHTTPHeaderField: @" Content-type " ];
    [res setValue: @(data.length).stringValue forHTTPHeaderField: @" Content-length " ];
    [res sendData: data];
  }
}];

为什么?

创建Criollo是为了利用Apple堆栈提供并提供通过网络生产的内容的真正令人敬畏的工具和API。

它结合了用于交付内容的HTTP Web服务器和FastCGI应用程序服务器。该服务器是建立在Grand Central Dispatch上的,并为速度设计。

如何使用

如果您需要这样的功能,则可以轻松地将Criollo嵌入MACOS,iOS或TVOS应用程序中,但是它旨在创建独立的,长寿的守护程序风格的应用程序。它是完全launchd的,并复制了NSApplication的生命周期和行为,因此学习曲线应尽可能平滑。

有关更真实的示例,请访问Criollo .io网站,该网站使用Criollo制作,可在https://g*ithub*.c*om/thecatalinstan/criollo-web上进行克隆乐趣。

有关两个用法模式的演示,请参见Hello World Multi Target示例。

入门

  • 阅读“入门”指南,并通过“做更多事情”指南进一步移动
  • 查看示例
  • 查看API参考以查看可用的API
  • 了解如何在“部署”指南中部署Criollo应用程序
  • 查看Criollo博客,以获取有关Criollo的新闻,想法和更新。

安装

安装Criollo的首选方法是通过可可录。但是,您也可以手动将框架嵌入到项目中。

与Cocoapods安装

  1. 如果您还没有一个,则创建Podfile 。您可以通过在项目文件夹中运行pod init来做到这一点。
  2. 将Criollo添加到您的Podfile中。 pod ' Criollo ', '~> 0.5'
  3. 运行pod install

请注意, Criollo将下载Cocoaasyncsocket作为依赖关系。

Swift软件包管理器

取得联系

如果您对该项目有任何疑问如何对其做任何事情,请随时在Twitter @ Criollo io或通过普通的旧电子邮件Criollo @ Criollo .io与您取得联系。

我真的鼓励您提交一个问题,因为您的意见是真正的,非常感谢。


查看Criollo博客,以获取有关Criollo的新闻,想法和更新。

下载源码

通过命令行克隆项目:

git clone https://github.com/thecatalinstan/Criollo.git